脚本

https://git.xyh.moe:8888/xian.yuheng/docker-push

#! /bin/bash

################################################################################
# 检测 docker 是否存在
docker 1>/dev/null 2>/dev/null
[ $? != 0 ] && echo -e "\e[33m Docker不存在\e[0m" && exit 1
# 检测是否有 docker 运行权限
docker version 1>/dev/null 2>/dev/null
[ $? != 0 ] && echo -e "\e[33m缺少权限\e[0m" && exit 1
################################################################################
# 帮助文档
help_str="""\
参数说明:
    -h 帮助文档
    -f, --file 镜像列表
    -r, --custom_registry 自定义推送源\
"""
################################################################################
# 参数判断
ARGS=` \
    getopt \
    -o hf:r: \
    -l help,file:,custom_registry: \
    -n "$0" \
    -- "$@" \
`
[ $? != 0 ] && echo -e "$help_str" && exit 1;
#[ $# == 0 ] && echo -e "$help_str" && exit 1;
eval set -- "${ARGS}"

while true
do
    case "$1" in
        -h | --help)
            echo -e "$help_str"
            exit
            ;;
        -f | --file)
            file=$2
            shift 2
            ;;
        -r | --registry)
            custom_registry=$2
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "处理选项时出现未知错误"
            exit 1
            ;;
    esac
done
#################################################################################
# 函数
function generate_horizontal_line()
{   # 创建一条和终端等宽的 分割线 [horizontal line]

    printf "%.0s${mark:-*}" $(stty size | awk '{print $2}' | xargs seq) && printf "\n"
}

function check_remote_image()
{   # 判断 远程镜像 是否存在
    # ${1} 一个 镜像名 形如 registry/repo/image:tag
    
    # 存在 返回 0
    # 不存在 返回 1
    
    docker manifest inspect ${1} 1>/dev/null 2>/dev/null
}

function format_image_file()
{   # 处理 输入文件
    # ${1} 输入的镜像列表
    
    # 1 读取 输入的第一个参数
    # 2 排除 # 开头的行
    # 3 排除 > 开头的行
    # 4 排除 空行
    
    images=`\
        cat ${1}      | \
        grep -v '#.*' | \
        grep -v '>.*' | \
        grep -v '^$'`
}

function format_image_name()
{   # 格式化 镜像名
    # ${1} 镜像名
    # ${2} 推送镜像源
    
    image_tag=`echo ${1} | awk -F: '{print $NF}'`
    image_longname=`echo ${1} | grep -oP '.+(?=:)'`

    if [[ `echo ${image_longname} | grep '^.*/.*/.*$'` ]]; then
        # registry/repo/image 型
        image_registry="$2"
        image_repo=`    echo ${image_longname} | awk -F"/" '{ print $2 }'`
        image_name=`    echo ${image_longname} | awk -F"/" '{ print $3 }'`
    elif [[ `echo ${image_longname} | grep '^.*/.*$'` ]]; then
        # repo/image 型
        image_registry="$2"
        image_repo=`    echo ${image_longname} | awk -F"/" '{ print $1 }'`
        image_name=`    echo ${image_longname} | awk -F"/" '{ print $2 }'`
    else
        # image 型
        image_registry="$2"
        image_repo="library"
        image_name=`    echo ${image_longname} | awk -F"/" '{ print $1 }'`
    fi
    
    formated_image_name=${image_registry}/${image_repo}/${image_name}:${image_tag}
}
################################################################################
# 推送源
if [[ -n $custom_registry ]]; then
    push_registry=$custom_registry
else
    push_registry='docker.xyh.moe'
fi

################################################################################
if [[ -n $file ]]; then
    #images=`cat $file | grep -v '#.*' | grep -v '>.*' | grep -v '^$'`
    format_image_file $file
else
    images=`docker images --format '{{.Repository}}:{{.Tag}}'`
fi


generate_horizontal_line
printf "%-24s%s\n" 推送仓库 $push_registry
printf "%-24s%s\n" 镜像列表文件 $file
generate_horizontal_line

# 打印 镜像 列表
for xxx in $images;do
    echo $xxx
done
generate_horizontal_line


# 推送镜像
for i in $images;do
        format_image_name ${i} ${push_registry}
        check_remote_image ${formated_image_name}
        
        
        if [[ $? == 0 ]]; then
            echo ${formated_image_name} 已存在
        else
            docker pull $i 1>/dev/null
            if [[ $? == 0 ]]; then
                docker tag $i $formated_image_name
                docker push $formated_image_name
                docker rmi $formated_image_name
            else
                echo $formated_image_name 拉取失败
            fi
        fi
done

exit 0

镜像文件格式

# Nginx
docker.io/library/nginx:1.25-alpine
docker.io/library/nginx:1.25.0-alpine
docker.io/library/nginx:1.25.1-alpine
docker.io/library/nginx:1.25.2-alpine