Skip to content

Instantly share code, notes, and snippets.

@hedzr
Last active August 27, 2022 00:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hedzr/1eba09ff0fda650f203f6a008e23038b to your computer and use it in GitHub Desktop.
Save hedzr/1eba09ff0fda650f203f6a008e23038b to your computer and use it in GitHub Desktop.
This script give a set of commands to save/load [all] docker containers as/from .tgz file(s).
#!/usr/bin/env bash
# # docker-fn series
# docker-fn-save-load.sh:
#
# This script give a set of commands to save/load [all] docker containers as/from .tgz file(s).
# > While you would plan to reset docker disk image file.
#
# Author: Hedzr Yeh
# LICENSE: MIT
# Feel free to use, copy, modify it
# Usage:
# $0 image [save|restore|load|saveall|restoreall|loadall]
#
# $0 image [help|--help]
# $0 image save mysql:8
# $0 image load mysql:8
# $0 image saveall
# $0 image [loadall|restoreall]
#
# # Specify a target directory:
# TARGET=/tmp $0 docker ...
#
# > Tips for $TARGET/docker.images.txt:
# >
# > - Pls sort the $TARGET/docker.images.txt by yourself.
# > - Comment one line with '#' to ignore it in restoring its (via 'loadall')
# >
docker_image() { commander 'img' "$@"; }
img_usage () {
cat <<-EOF
'docker' sub-command Usages:
SUB-COMMANDS:
save [tag] save a image
restore,load [tag] restore a image
saveall save all images
restoreall,loadall restore all images
Help:
# go mod helpers:
TARGET=\$HOME/Downloads/docker-images
EOF
}
function img_save () {
local TARGET=${TARGET:-$HOME/Downloads/docker-images}
[[ -d $TARGET ]] || mkdir $TARGET
IFS=: read -r cn tag < "$1"
[[ $cn == */* ]] && {
dir=$(dirname $cn)
cn=$(basename $cn)
[[ -d $TARGET/$dir ]] || mkdir -p $TARGET/$dir
[[ -f $TARGET/$dir/$cn.$tag.tgz ]] || docker save $dir/$cn:$tag | gzip -c > $TARGET/$dir/$cn.$tag.tgz
} || {
[[ -f $cn.$tag.tgz ]] || docker save $cn:$tag | gzip -c > "$cn.$tag.tgz"
}
}
function img_load () { img_restore $*; }
function img_restore () {
local TARGET=${TARGET:-$HOME/Downloads/docker-images}
[[ -d $TARGET ]] || mkdir $TARGET
IFS=: read -r cn tag < "$1"
[[ $cn == */* ]] && {
dir=$(dirname $cn)
cn=$(basename $cn)
[[ -d $TARGET/$dir ]] || mkdir -p $TARGET/$dir
[[ -f $TARGET/$dir/$cn.$tag.tgz ]] || docker save $dir/$cn:$tag | gzip -c > $TARGET/$dir/$cn.$tag.tgz
} || {
[[ -f $cn.$tag.tgz ]] || docker save $cn:$tag | gzip -c > "$cn.$tag.tgz"
}
}
function img_saveall () {
local TARGET=${TARGET:-$HOME/Downloads/docker-images}
[[ -d $TARGET ]] || mkdir $TARGET
local xtmp=$TARGET/docker.images.txt
# docker images | tail -n +2 | awk '{ if ($1 != "<none>") { printf "%s:%s\n",$1,$2 }}' >$xtmp
docker images | tail -n +2 | awk '{ if ($1 != "<none>") { printf "%s:%s\n",$1,$2 }}' >$xtmp
while IFS=: read -r cn tag; do
echo "saving $cn:$tag ..."
[[ $cn =~ '#.*' ]] || {
[[ $cn == */* ]] && {
dir=$(dirname $cn)
cn=$(basename $cn)
[[ -d $TARGET/$dir ]] || mkdir -p $TARGET/$dir
[[ -f $TARGET/$dir/$cn.$tag.tgz ]] || docker save $dir/$cn:$tag | gzip -c > $TARGET/$dir/$cn.$tag.tgz
} || {
[ -f ${cn}.$tag.tgz ] || docker save $cn:$tag | gzip -c > "$cn.$tag.tgz"
}
}
# return
done < $xtmp
}
function img_loadall () { img_restoreall $*; }
function img_restoreall () {
local TARGET=${TARGET:-$HOME/Downloads/docker-images}
[[ -d $TARGET ]] || mkdir $TARGET
local xtmp=$TARGET/docker.images.txt
while IFS=: read -r cn tag; do
echo "saving $cn:$tag ..."
#[[ $cn =~ '#.*' ]] || {
[[ $cn == */* ]] && {
dir=$(dirname $cn)
cn=$(basename $cn)
[ -f $TARGET/$dir/$cn.$tag.tgz ] && gunzip -c $TARGET/$dir/$cn.$tag.tgz | docker load
} || {
[ -f $cn.$tag.tgz ] && gunzip -c $cn.$tag.tgz | docker load
}
#}
# return
done < $xtmp
}
#### write your functions here, and invoke them by: `./bash.sh <your-func-name>`
cool(){ echo cool; }
sleeping(){ echo sleeping; }
_my_main_do_sth(){
local cmd=${1:-core} && { [ $# -ge 1 ] && shift; } || :
# for linux only:
# local cmd=${1:-sleeping} && shift || :
is_vagrant && CD=/vagrant && SCRIPT=$CD/bootstrap.sh
headline "CD = $CD, SCRIPT = $SCRIPT, PWD=$(pwd)"
# [ -d $CD/.boot.d ] || mkdir -p $CD/.boot.d
# [ -z "$(ls -A $CD/.boot.d/)" ] && for f in $CD/.boot.d/*; do source $f; done
debug "docker_$cmd - $@"
eval "docker_$cmd $@" || { echo 'not true' 1>&2; :; }
}
is_vagrant() { [[ -d /vagrant ]]; }
#### HZ Tail BEGIN ####
in_debug() { [[ $DEBUG -eq 1 ]]; }
is_root() { [ "$(id -u)" = "0" ]; }
is_bash() { is_bash_t1 && is_bush_t2; }
is_bash_t1() { [ -n "$BASH_VERSION" ]; }
is_bash_t2() { [ ! -n "$BASH" ]; }
is_zsh() { [[ $SHELL == */zsh ]]; }
is_zsh_t2() { [ -n "$ZSH_NAME" ]; }
is_darwin() { [[ $OSTYPE == *darwin* ]]; }
is_linux() { [[ $OSTYPE == *linux* ]]; }
in_sourcing() { is_zsh && [[ "$ZSH_EVAL_CONTEXT" == toplevel* ]] || [[ $(basename -- "$0") != $(basename -- "${BASH_SOURCE[0]}") ]]; }
is_interactive_shell () { [[ $- == *i* ]]; }
is_not_interactive_shell () { [[ $- != *i* ]]; }
is_ps1 () { [ -z "$PS1" ]; }
is_not_ps1 () { [ ! -z "$PS1" ]; }
is_stdin () { [ -t 0 ]; }
is_not_stdin () { [ ! -t 0 ]; }
headline() { printf "\e[0;1m$@\e[0m:\n"; }
headline_begin() { printf "\e[0;1m"; } # for more color, see: shttps://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux
headline_end() { printf "\e[0m:\n"; } # https://misc.flogisoft.com/bash/tip_colors_and_formatting
printf_black() { printf "\e[0;30m$@\e[0m:\n"; }
printf_red() { printf "\e[0;31m$@\e[0m:\n"; }
printf_green() { printf "\e[0;32m$@\e[0m:\n"; }
printf_yellow() { printf "\e[0;33m$@\e[0m:\n"; }
printf_blue() { printf "\e[0;34m$@\e[0m:\n"; }
printf_purple() { printf "\e[0;35m$@\e[0m:\n"; }
printf_cyan() { printf "\e[0;36m$@\e[0m:\n"; }
printf_white() { printf "\e[0;37m$@\e[0m:\n"; }
debug() { in_debug && printf "\e[0;38;2;133;133;133m$@\e[0m\n" || :; }
debug_begin() { printf "\e[0;38;2;133;133;133m"; }
debug_end() { printf "\e[0m\n"; }
dbg() { ((DEBUG)) && printf ">>> \e[0;38;2;133;133;133m$@\e[0m\n" || :; }
debug_info() {
debug_begin
cat <<-EOF
in_debug: $(in_debug && echo Y || echo '-')
is_root: $(is_root && echo Y || echo '-')
is_bash: $(is_bash && echo Y || echo '-')
is_zsh: $(is_zsh && echo Y || echo '-')
in_sourcing: $(in_sourcing && echo Y || echo '-') # ZSH_EVAL_CONTEXT = $ZSH_EVAL_CONTEXT
is_interactive_shell: $(is_interactive_shell && echo Y || echo '-')
is_darwin: $(is_darwin && echo Y || echo '-')
EOF
debug_end
}
commander () {
local self=$1; shift;
local cmd=${1:-usage}; [ $# -eq 0 ] || shift;
#local self=${FUNCNAME[0]}
case $cmd in
help|usage|--help|-h|-H) "${self}_usage" "$@"; ;;
funcs|--funcs|--functions|--fn|-fn) script_functions "^$self"; ;;
*)
if [ "$(type -t ${self}_${cmd}_entry)" == "function" ]; then
"${self}_${cmd}_entry" "$@"
else
"${self}_${cmd}" "$@"
fi
;;
esac
}
script_functions () {
# shellcheck disable=SC2155
local fncs=$(declare -F -p | cut -d " " -f 3|grep -vP "^[_-]"|grep -vP "\\."|grep -vP "^[A-Z]"); # Get function list
if [ $# -eq 0 ]; then
echo "$fncs"; # not quoted here to create shell "argument list" of funcs.
else
echo "$fncs"|grep -P "$@"
fi
#declare MyFuncs=($(script.functions));
}
main_do_sth() {
set -e
trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
trap '[ $? -ne 0 ] && echo FAILED COMMAND: $previous_command with exit code $?' EXIT
MAIN_DEV=${MAIN_DEV:-eth0}
MAIN_ENTRY=${MAIN_ENTRY:-_my_main_do_sth}
# echo $MAIN_ENTRY - "$@"
in_debug && { debug_info; echo "$SHELL : $ZSH_NAME - $ZSH_VERSION | BASH_VERSION = $BASH_VERSION"; [ -n "$ZSH_NAME" ] && echo "x!"; }
$MAIN_ENTRY "$@"
trap - EXIT
${HAS_END:-$(false)} && { debug_begin;echo -n 'Success!';debug_end; } || :
}
DEBUG=${DEBUG:-0}
# is_darwin && { is_zsh && realpathx(){ [[ $1 == /* ]] && echo ${1:a} || { local A="$PWD/${1#./}"; echo ${A:a}; } } || realpathx(){ [[ $1 == /* ]] && echo "$1" || echo "$PWD/${1#./}"; } } ||
is_darwin && {
realpathx () {
perl -MCwd -le '
for (@ARGV) {
if ($p = Cwd::abs_path $_) {
print $p;
} else {
warn "abs_path: $_: $!\n";
$ret = 1;
}
}
exit $ret' "$@"
}
} || realpathx () { readlink -f $*; }
in_sourcing && { CD=${CD}; debug ">> IN SOURCING, \$0=$0, \$_=$_"; } || { SCRIPT=$(realpathx $0) && CD=$(dirname $SCRIPT) && debug ">> '$SCRIPT' in '$CD', \$0='$0','$1'."; }
main_do_sth "$@"
#### HZ Tail END ####
@hedzr
Copy link
Author

hedzr commented Aug 27, 2019

docker-fn series

docker-fn-save-load.sh

This script give a set of commands to save/load [all] docker containers as/from .tgz file(s).

While you would plan to reset docker disk image file.

Author: Hedzr Yeh
LICENSE: MIT
Feel free to use, copy, modify it.

Usage:

$0 image [save|restore|load|saveall|restoreall|loadall]

$0 image [help|--help]
$0 image save mysql:8
$0 image load mysql:8
$0 image saveall
$0 image [loadall|restoreall]

Specify a target directory:

TARGET=/tmp $0 docker ...

Tips for $TARGET/docker.images.txt:

  • Pls sort the $TARGET/docker.images.txt by yourself.
  • Comment one line with '#' to ignore it in restoring its (via 'loadall')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment