Docker镜像批量导入导出shell脚本

➜ cat docker_image_load_save.sh
#!/bin/bash
#
#******************************************************************************************
#Author:                QianSong
#QQ:                    xxxxxxxxxx
#Date:                  2024-08-25
#FileName:              docker_image_load_save.sh
#URL:                   https://github.com
#Description:           The test script
#Copyright (C):         QianSong 2024 All rights reserved
#******************************************************************************************

#######################################
# 初始化全局变量
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function init_global_vars() {

    #ding  yi  bian  liang
    docker_result_dir="/tmp/image/docker_images_result"
    containerd_result_dir="/tmp/image/containerd_images_result"

    #color
    hei_color="\033[1;30m"
    hong_color="\033[1;31m"
    lv_color="\033[1;32m"
    huang_color="\033[1;33m"
    lan_color="\033[1;34m"
    zi_color="\033[1;35m"
    tianlan_color="\033[1;36m"
    bai_color="\033[1;37m"
    normal_color="\033[0m"

    #pan duan docker_result_dir shi  fou  cun  zai
    if [ ! -d "${docker_result_dir}" ]; then
        mkdir "${docker_result_dir}" -p
    fi

    #pan duan containerd_result_dir shi  fou  cun  zai
    if [ ! -d "${containerd_result_dir}" ]; then
        mkdir "${containerd_result_dir}" -p
    fi
}

#######################################
# 打印logo
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function print_app_info() {

    clear
    echo -e "\033[35mWMWMWMWMWMWMWMWMWMWMWMWMWMWMWWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                 *${normal_color}"
    sleep 0.1
    echo -e "${hong_color}              *      *${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                 *${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                    **********************************************${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                 *                                                *${normal_color}"
    sleep 0.1
    echo -e "${lv_color}< JJ 18 CM >${normal_color}     ${hong_color}*                                           *******${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                 *                                                *${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                    **********************************************${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                 *${normal_color}"
    sleep 0.1
    echo -e "${hong_color}              *      *${normal_color}"
    sleep 0.1
    echo -e "${hong_color}                 *${normal_color}"
    sleep 0.1
    echo -e "\033[35mWMWMWMWMWMWMWMWMWMWMWMWMWMWMWWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM${normal_color}"
    sleep 0.1

    #print process info
    local i=1
    local char
    while [ "${i}" -lt 5 ]; do
        for char in "/" "." "\\"; do
            echo -n "                                  [${char}]                                    "
            echo -ne "\r\r"
            sleep 0.2
        done
        i=$((i + 1))
    done
    echo -e "\n"
    sleep 0.3
}

#######################################
# 打印提示信息
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function print_notice_info() {

    echo -e "\n"
    echo -e "${huang_color}加载完毕!正在为您启动,请稍等鸡儿几秒钟.......${normal_color}"
    sleep 5
    clear
}

#######################################
# 导出镜像通过docker
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function save_image_by_docker() {

    rm -rf "${docker_result_dir:?}/image_save.csv" >/dev/null 2>&1

    #输入一个表头,防止意外的错误提示
    echo -e "IMAGE_NAME," >>"${docker_result_dir:?}/image_save.csv"

    local image
    IFS=$'\n'
    for image in $(docker image ls | awk 'NR>1''{print $1":"$2}'); do
        echo -e "${image}," >>"${docker_result_dir:?}/image_save.csv"
    done

    local image_total
    image_total="$(cat "${docker_result_dir}/image_save.csv" | sed -r '1d' | wc -l)"
    if [ "${image_total}" -eq 0 ]; then
        echo -e "${huang_color}镜像列表为空,无需导出!${normal_color}"
        echo
        echo -ne "${huang_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    else
        display_image_to_save "docker"
        IFS=$' \n\t'
        local item file_name
        for item in "${selected_image_to_save[@]}"; do
            file_name="$(echo "${item}" | sed -r 's#(/|:|\.)#-#g')".tar
            echo -e "\033[45;37mSaveing image ${item}....${normal_color}"
            docker image save "${item}" >"${docker_result_dir:?}/${file_name:?}"
            echo -e "${lv_color}Image ${item} has saved complete!${normal_color}"
            echo -e " "
        done
        echo -e " "
        echo -e "${lv_color}导出完成,本次导出共计【${#selected_image_to_save[@]}】个镜像!${zi_color}镜像保存在[${docker_result_dir}]${normal_color}"

        echo
        echo -ne "${huang_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    fi
}

#######################################
# 导出镜像通过containerd
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function save_image_by_containerd() {

    rm -rf "${containerd_result_dir:?}/image_save.csv" >/dev/null 2>&1

    #输入一个表头,防止意外的错误提示
    echo -e "IMAGE_NAME," >>"${containerd_result_dir:?}/image_save.csv"

    local image
    IFS=$'\n'
    for image in $(ctr -n k8s.io image ls | awk "NR>1"'{print $1}' | grep -v "sha256:"); do
        echo -e "${image}," >>"${containerd_result_dir:?}/image_save.csv"
    done

    local image_total
    image_total="$(cat "${containerd_result_dir}/image_save.csv" | sed -r '1d' | wc -l)"
    if [ "${image_total}" -eq 0 ]; then
        echo -e "${huang_color}镜像列表为空,无需导出!${normal_color}"
        echo
        echo -ne "${huang_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    else
        display_image_to_save "containerd"
        IFS=$' \n\t'
        local item file_name
        for item in "${selected_image_to_save[@]}"; do
            file_name="$(echo "${item}" | sed -r 's#(/|:|\.)#-#g')".tar
            echo -e "\033[45;37mSaveing image ${item}....${normal_color}"
            ctr -n k8s.io image export "${containerd_result_dir:?}/${file_name:?}" "${item}"
            echo -e "${lv_color}Image ${item} has saved complete!${normal_color}"
            echo -e " "
        done
        echo -e " "
        echo -e "${lv_color}导出完成,本次导出共计【${#selected_image_to_save[@]}】个镜像!${zi_color}镜像保存在[${containerd_result_dir}]${normal_color}"

        echo
        echo -ne "${huang_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    fi
}

#######################################
# 选择镜像导出
# Globals:
#   ${selected_image_to_save[@]}
# Arguments:
#   $1: 传入操作的容器运行时类型containerd OR docker
# Outputs:
#   none
# Returns:
#   none
#######################################
function display_image_to_save() {

    local image_save_dir

    if [ "${1}" == "containerd" ]; then
        image_save_dir="${containerd_result_dir}"
    elif [ "${1}" == "docker" ]; then
        image_save_dir="${docker_result_dir}"
    fi

    #循环读取文件里边的镜像信息打印选择
    clear
    echo -e "序号     镜像tag"
    echo -e "------------------------------------------------------------------"
    local i=0
    local exp_image sp1
    declare -A image_array
    while IFS=, read -r exp_image; do
        if [ "${#exp_image}" -gt 0 ] && [ "${exp_image^^}" != "IMAGE_NAME" ]; then
            i=$((i + 1))
            exp_image="$(echo "${exp_image}" | awk '{print $1}')"
            if [ "${#i}" -eq 1 ]; then
                sp1="   "
            elif [ "${#i}" -eq 2 ]; then
                sp1="  "
            elif [ "${#i}" -eq 3 ]; then
                sp1=" "
            else
                sp1=""
            fi

            image_array["${i}"]="${exp_image}"
            echo -e "${lv_color}${sp1}${i}).   ${bai_color}${exp_image}${normal_color}"
        fi
    done <"${image_save_dir}/image_save.csv"
    echo -e "------------------------------------------------------------------"

    echo -e ""
    echo -e "${huang_color}请选择一个镜像导出,${lv_color}导出多个镜像请使用空格隔开镜像序号[1 2 3 4...],导出所有镜像请直接输入all${normal_color}"
    local you_zl
    local regexp="^([1-9])$|^([1-9])([0-9 ])*([0-9])$|^(all)$"
    read -rp "> " you_zl
    while true; do
        if [[ ! "${you_zl}" =~ ${regexp} ]]; then
            echo -e "${hong_color}Invalid${normal_color}"
            read -rp "> " you_zl
        elif [[ "${you_zl}" =~ ^[0-9]+$ ]] && [ "${you_zl}" -eq 0 ]; then
            echo -e "${hong_color}Invalid${normal_color}"
            read -rp "> " you_zl
        elif [[ "${you_zl}" =~ ^[0-9]+$ ]] && [ "${you_zl}" -gt "${i}" ]; then
            echo -e "${hong_color}Invalid${normal_color}"
            read -rp "> " you_zl
        else
            break
        fi
    done

    selected_image_to_save=()
    if [ "${you_zl}" == "all" ]; then
        selected_image_to_save=("${image_array[@]}")
    else
        IFS=$' \n\t'
        local iterm
        for iterm in ${you_zl}; do
            selected_image_to_save+=("${image_array[${iterm}]}")
        done
    fi

    local image_total_to_save
    image_total_to_save="$(echo "${selected_image_to_save[@]}" | awk '{print $0}')"

    echo
    echo -e "${lv_color}已选择镜像列表: ${normal_color}"

    IFS=$' \n\t'
    local item
    for item in ${image_total_to_save}; do
        echo -e "${huang_color}${item}${normal_color}"
    done

    echo
    echo -ne "${lv_color}按[Enter]键继续...${normal_color}"
    local you_zl
    read -r you_zl
}

#######################################
# 导入镜像通过docker
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function load_image_by_docker() {

    local image_total
    image_total="$(find "${docker_result_dir}"/ -maxdepth 1 -name "*.tar" | wc -l)"
    if [ "${image_total}" -eq 0 ]; then
        echo -e "${huang_color}镜像目录 ${zi_color}[${docker_result_dir}] ${huang_color}为空,无法导入!您可能需要先导出镜像${normal_color}"
        echo
        echo -ne "${lv_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    else
        display_image_to_load "docker"
        IFS=$' \n\t'
        local item file_name
        for item in "${selected_image_to_load[@]}"; do
            file_name="${docker_result_dir}/${item}"
            echo -e "\033[45;37mLoading image ${item}....${normal_color}"
            docker image load -i "${file_name}"
            echo -e "${lv_color}Image ${item} has loaded complete!${normal_color}"
            echo -e " "
        done
        docker image ls
        echo -e " "
        echo -e "${lv_color}导入完成!本次导入了【${#selected_image_to_load[@]}】个镜像,系统共计【$(docker image ls | awk 'NR>1' | wc -l)】个镜像。${normal_color}"

        echo
        echo -ne "${lv_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    fi
}

#######################################
# 导入镜像通过containerd
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function load_image_by_containerd() {

    local image_total
    image_total="$(find "${containerd_result_dir}"/ -maxdepth 1 -name "*.tar" | wc -l)"
    if [ "${image_total}" -eq 0 ]; then
        echo -e "${huang_color}镜像目录 ${zi_color}[${containerd_result_dir}] ${huang_color}为空,无法导入!您可能需要先导出镜像${normal_color}"
        echo
        echo -ne "${lv_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    else
        display_image_to_load "containerd"
        IFS=$' \n\t'
        local item file_name
        for item in "${selected_image_to_load[@]}"; do
            file_name="${containerd_result_dir}/${item}"
            echo -e "\033[45;37mLoading image ${item}....${normal_color}"
            ctr -n k8s.io image import "${file_name}"
            echo -e "${lv_color}Image ${item} has loaded complete!${normal_color}"
            echo -e " "
        done
        ctr -n k8s.io image ls | awk "NR>1"'{print $1}' | grep -v "sha256:"
        echo -e " "
        echo -e "${lv_color}导入完成!本次导入了【${#selected_image_to_load[@]}】个镜像,系统共计【$(ctr -n k8s.io image ls | awk "NR>1"'{print $1}' | grep -v "sha256:" | wc -l)】个镜像。${normal_color}"

        echo
        echo -ne "${lv_color}按[Enter]键继续...${normal_color}"
        local you_zl
        read -r you_zl
        opt_select
    fi
}

#######################################
# 选择镜像导入
# Globals:
#   ${selected_image_to_load[@]}
# Arguments:
#   $1: 传入操作的容器运行时类型containerd OR docker
# Outputs:
#   none
# Returns:
#   none
#######################################
function display_image_to_load() {

    local image_load_dir

    if [ "${1}" == "containerd" ]; then
        image_load_dir="${containerd_result_dir}"
    elif [ "${1}" == "docker" ]; then
        image_load_dir="${docker_result_dir}"
    fi

    local file_name image_name
    rm -rf "${image_load_dir:?}/image_load.csv" >/dev/null 2>&1

    #输入一个表头,防止意外的错误提示
    echo -e "IMAGE_NAME," >>"${image_load_dir:?}/image_load.csv"

    IFS=$'\n'
    while IFS= read -r -d '' file_name; do
        image_name="$(basename "${file_name}")"
        echo -e "${image_name}," >>"${image_load_dir:?}/image_load.csv"
    done < <(find "${image_load_dir}"/ -maxdepth 1 -name "*.tar" -print0)

    #循环读取文件里边的镜像信息打印选择
    clear
    echo -e "序号     镜像压缩包文件"
    echo -e "------------------------------------------------------------------"
    local i=0
    local exp_image
    declare -A image_array
    while IFS=, read -r exp_image; do
        if [ "${#exp_image}" -gt 0 ] && [ "${exp_image^^}" != "IMAGE_NAME" ]; then
            i=$((i + 1))
            exp_image="$(echo "${exp_image}" | awk '{print $1}')"
            if [ "${#i}" -eq 1 ]; then
                sp1="   "
            elif [ "${#i}" -eq 2 ]; then
                sp1="  "
            elif [ "${#i}" -eq 3 ]; then
                sp1=" "
            else
                sp1=""
            fi

            image_array["${i}"]="${exp_image}"
            echo -e "${lv_color}${sp1}${i}).   ${bai_color}${exp_image}${normal_color}"
        fi
    done <"${image_load_dir}/image_load.csv"
    echo -e "------------------------------------------------------------------"

    echo -e ""
    echo -e "${huang_color}请选择一个镜像导入,${lv_color}导入多个镜像请使用空格隔开镜像序号[1 2 3 4...],导入所有镜像请直接输入all${normal_color}"
    local you_zl
    local regexp="^([1-9])$|^([1-9])([0-9 ])*([0-9])$|^(all)$"
    read -rp "> " you_zl
    while true; do
        if [[ ! "${you_zl}" =~ ${regexp} ]]; then
            echo -e "${hong_color}Invalid${normal_color}"
            read -rp "> " you_zl
        elif [[ "${you_zl}" =~ ^[0-9]+$ ]] && [ "${you_zl}" -eq 0 ]; then
            echo -e "${hong_color}Invalid${normal_color}"
            read -rp "> " you_zl
        elif [[ "${you_zl}" =~ ^[0-9]+$ ]] && [ "${you_zl}" -gt "${i}" ]; then
            echo -e "${hong_color}Invalid${normal_color}"
            read -rp "> " you_zl
        else
            break
        fi
    done

    selected_image_to_load=()
    if [ "${you_zl}" == "all" ]; then
        selected_image_to_load=("${image_array[@]}")
    else
        IFS=$' \n\t'
        local iterm
        for iterm in ${you_zl}; do
            selected_image_to_load+=("${image_array[${iterm}]}")
        done
    fi

    local image_total_to_load
    image_total_to_load="$(echo "${selected_image_to_load[@]}" | awk '{print $0}')"

    echo
    echo -e "${lv_color}已选择镜像列表: ${normal_color}"

    IFS=$' \n\t'
    local item
    for item in ${image_total_to_load}; do
        echo -e "${huang_color}${item}${normal_color}"
    done

    echo
    echo -ne "${lv_color}按[Enter]键继续...${normal_color}"
    local you_zl
    read -r you_zl
}

#######################################
# 操作类型选择菜单
# Globals:
#   none
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function opt_select() {

    clear
    echo -e "${huang_color}请选择一个镜像操作类型${normal_color}"
    echo -e "${tianlan_color}************************************${normal_color}"
    echo -e "${hong_color}当前运行时: ${runtime_type:-空}${normal_color}"
    echo -e "${tianlan_color}************************************${normal_color}"
    echo -e "${lv_color}0.  返回上一级${normal_color}"
    echo -e "${tianlan_color}-----${normal_color}"
    echo -e "${lv_color}1.  导出镜像${normal_color}"
    echo -e "${lv_color}2.  导入镜像${normal_color}"
    echo -e "${lv_color}3.  退出${normal_color}"
    echo -e "${tianlan_color}-----${normal_color}"
    local you_zl
    read -rp "Please select: " you_zl
    you_zl="$(echo "${you_zl}" | awk '{print $1}')"
    case "${you_zl}" in
    0)
        runtime_select
        ;;
    1)
        if [ "${runtime_type}" == "docker" ]; then
            save_image_by_docker
        elif [ "${runtime_type}" == "containerd" ]; then
            save_image_by_containerd
        fi
        ;;
    2)
        if [ "${runtime_type}" == "docker" ]; then
            load_image_by_docker
        elif [ "${runtime_type}" == "containerd" ]; then
            load_image_by_containerd
        fi
        ;;
    3)
        exit 3
        ;;
    *)
        opt_select
        ;;
    esac
}

#######################################
# 运行时选择菜单
# Globals:
#   ${runtime_type}
# Arguments:
#   none
# Outputs:
#   none
# Returns:
#   none
#######################################
function runtime_select() {

    clear
    echo -e "${huang_color}请给出您当前使用的容器runtime运行时类型${normal_color}"
    echo -e "${tianlan_color}************************************${normal_color}"
    echo -e "${lv_color}1.  Docker${normal_color}"
    echo -e "${lv_color}2.  Containerd${normal_color}"
    echo -e "${tianlan_color}************************************${normal_color}"
    local you_zl
    read -rp "Please select: " you_zl
    you_zl="$(echo "${you_zl}" | awk '{print $1}')"
    case "${you_zl}" in
    1)
        runtime_type='docker'
        opt_select
        ;;
    2)
        runtime_type='containerd'
        opt_select
        ;;
    *)
        runtime_select
        ;;
    esac
}

#######################################
# 脚本的入口,程序执行的起点函数main
# Globals:
#   none
# Arguments:
#   "$@"
# Outputs:
#   none
# Returns:
#   none
#######################################
function main() {

    init_global_vars
    print_app_info
    print_notice_info
    runtime_select
}

main "$@"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值