Files
ljwx-harbor/harbor/push-local-images.sh

311 lines
6.7 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
##############################################################################
# Push Local Images to Harbor
# 将本地所有基础镜像推送到 Harbor
##############################################################################
set -euo pipefail
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Harbor 配置
HARBOR_IP="${HARBOR_IP:-192.168.1.83}"
HARBOR_HTTP_PORT="${HARBOR_HTTP_PORT:-8080}"
HARBOR_REGISTRY="${HARBOR_IP}:${HARBOR_HTTP_PORT}"
HARBOR_PROJECT="${HARBOR_PROJECT:-library}"
HARBOR_USERNAME="${HARBOR_USERNAME:-admin}"
HARBOR_PASSWORD="${HARBOR_PASSWORD:-admin123}"
# 日志函数
log_info() {
echo -e "${BLUE}ℹ${NC} $1"
}
log_success() {
echo -e "${GREEN}✓${NC} $1"
}
log_warning() {
echo -e "${YELLOW}⚠${NC} $1"
}
log_error() {
echo -e "${RED}✗${NC} $1"
}
# 登录 Harbor
harbor_login() {
log_info "登录到 Harbor Registry..."
if echo "${HARBOR_PASSWORD}" | docker login "${HARBOR_REGISTRY}" -u "${HARBOR_USERNAME}" --password-stdin 2>/dev/null; then
log_success "登录成功"
return 0
else
log_error "登录失败"
return 1
fi
}
# 获取本地所有镜像
get_local_images() {
log_info "获取本地镜像列表..."
# 获取所有本地镜像,排除 Harbor 自身的镜像
docker images --format "{{.Repository}}:{{.Tag}}" | \
grep -v "^${HARBOR_REGISTRY}" | \
grep -v "<none>" | \
sort -u
}
# 过滤基础镜像
filter_base_images() {
log_info "过滤基础组件镜像..."
# 基础镜像关键词
local base_keywords=(
"alpine"
"ubuntu"
"debian"
"centos"
"fedora"
"nginx"
"redis"
"postgres"
"mysql"
"mongo"
"python"
"node"
"golang"
"openjdk"
"busybox"
"registry"
"k8s.gcr.io"
"registry.k8s.io"
"quay.io"
"ghcr.io"
"docker.io"
)
# 读取所有镜像
local images=()
while IFS= read -r image; do
images+=("$image")
done
# 过滤基础镜像
local filtered=()
for image in "${images[@]}"; do
for keyword in "${base_keywords[@]}"; do
if echo "$image" | grep -qi "$keyword"; then
filtered+=("$image")
break
fi
done
done
# 输出过滤后的镜像
printf '%s\n' "${filtered[@]}"
}
# 推送单个镜像
push_image() {
local source_image="$1"
local image_name
local image_tag
# 解析镜像名称和标签
if [[ "$source_image" =~ ^(.+):(.+)$ ]]; then
image_name="${BASH_REMATCH[1]}"
image_tag="${BASH_REMATCH[2]}"
else
image_name="$source_image"
image_tag="latest"
fi
# 移除仓库前缀(如果有)
image_name="${image_name##*/}"
# 构建目标镜像名称
local target_image="${HARBOR_REGISTRY}/${HARBOR_PROJECT}/${image_name}:${image_tag}"
log_info "推送镜像: ${source_image} -> ${target_image}"
# Tag 镜像
if docker tag "${source_image}" "${target_image}"; then
# 推送镜像
if docker push "${target_image}"; then
log_success "推送成功: ${target_image}"
return 0
else
log_error "推送失败: ${target_image}"
return 1
fi
else
log_error "Tag 失败: ${source_image}"
return 1
fi
}
# 推送所有镜像
push_all_images() {
local images
local total=0
local success=0
local failed=0
# 获取镜像列表
mapfile -t images < <(get_local_images | filter_base_images)
total=${#images[@]}
if [ "$total" -eq 0 ]; then
log_warning "没有找到需要推送的基础镜像"
return 0
fi
log_info "找到 ${total} 个基础镜像需要推送"
echo ""
# 显示镜像列表
log_info "镜像列表:"
printf '%s\n' "${images[@]}" | sed 's/^/ - /'
echo ""
# 询问确认
read -p "是否继续推送所有镜像?[y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
log_warning "取消推送操作"
return 0
fi
# 推送所有镜像
for image in "${images[@]}"; do
if push_image "$image"; then
((success++))
else
((failed++))
fi
echo ""
done
# 输出统计信息
echo ""
log_info "推送统计:"
echo " 总计: ${total}"
echo " 成功: ${success}"
echo " 失败: ${failed}"
}
# 推送指定镜像
push_specific_images() {
local images=("$@")
log_info "推送指定的 ${#images[@]} 个镜像"
for image in "${images[@]}"; do
push_image "$image"
echo ""
done
}
# 显示使用说明
show_usage() {
cat <<EOF
使用方法:
$0 [OPTIONS] [IMAGE...]
选项:
-h, --help 显示此帮助信息
-a, --all 推送所有基础镜像(默认)
-l, --list 仅列出本地基础镜像,不推送
-p, --project NAME 指定 Harbor 项目(默认: library)
示例:
# 推送所有基础镜像
$0 --all
# 仅列出镜像
$0 --list
# 推送到指定项目
$0 --project myproject --all
# 推送指定镜像
$0 nginx:latest redis:7-alpine
EOF
}
# 主函数
main() {
local mode="all"
local specific_images=()
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-a|--all)
mode="all"
shift
;;
-l|--list)
mode="list"
shift
;;
-p|--project)
HARBOR_PROJECT="$2"
shift 2
;;
*)
specific_images+=("$1")
mode="specific"
shift
;;
esac
done
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE}Push Local Images to Harbor${NC}"
echo -e "${BLUE}======================================${NC}"
echo ""
echo "Harbor Registry: ${HARBOR_REGISTRY}"
echo "Harbor Project: ${HARBOR_PROJECT}"
echo ""
# 登录 Harbor
if ! harbor_login; then
exit 1
fi
echo ""
# 根据模式执行
case $mode in
all)
push_all_images
;;
list)
log_info "本地基础镜像列表:"
get_local_images | filter_base_images | sed 's/^/ - /'
;;
specific)
push_specific_images "${specific_images[@]}"
;;
esac
log_success "操作完成!"
}
# 执行主函数
main "$@"