➜ 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 "$@"
Docker镜像批量导入导出shell脚本
于 2024-08-25 18:19:20 首次发布