-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdocker_save.sh
More file actions
executable file
·249 lines (228 loc) · 5.55 KB
/
docker_save.sh
File metadata and controls
executable file
·249 lines (228 loc) · 5.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#!/bin/bash
# __author__: tuan t. pham <tuan at vt dot edu>
# Description: a glorious shell script to save the typing of
# for i in `docker images | tail -n +2...;do docker save $i | xz ...>;done
# This script will save your docker image(s) to .tar.xz file(s)
# To load the saved image(s):
# $ for i in `ls *.xz`; do
# xzcat $i | docker load
# done
OPTS=":l:o:n:c:h"
DEBUG=${DEBUG:=0}
OUTDIR=${OUTDIR:=.}
COMPRESS_LEVEL=6
# Define your own filter command to filter out the output of `docker images`
FILTER=${FILTER:="grep -vi \"^<None>\""}
CPUS=${CPUS:=`grep -c processor /proc/cpuinfo`}
DEF_IMG_CMD="docker images | tail -n +2 | $FILTER | awk '{print \$1\":\"\$2}'"
IMG_CMD=${IMG_CMD:=$DEF_IMG_CMD}
# see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
# the color code snippet is from https://github.com/docker/docker @ docker/contrib/check-config.sh
declare -A colors=(
[black]=30
[red]=31
[green]=32
[yellow]=33
[blue]=34
[magenta]=35
[cyan]=36
[white]=37
)
# Ex:
# color red
# echo something
# color reset
function color()
{
color=( '1' )
if [ $# -gt 0 ] && [ "${colors[$1]}" ]; then
color+=( "${colors[$1]}" )
else
color=()
fi
# set delimiter
local IFS=';'
echo -en '\033['"${color[*]}"m
}
# reverse docker's order
# wrap_color <color> <"text">
function wrap_color()
{
color "$1"
shift
echo -ne "$@"
color reset
echo
}
function log()
{
if [ "$DEBUG" = 1 ]; then
eval "echo $*"
fi
}
function dump_vars()
{
VAR_LIST="OPTS DEBUG OUTDIR COMPRESS_LEVEL FILTER CPUS DEF_IMG_CMD IMG_CMD"
for e in $VAR_LIST; do
d="$e"
d=`eval echo "\\$$d"`
echo "$e=$d"
done
}
function help_msg()
{ #onc
echo "$(wrap_color red "Usage:") $0"
echo -e "\t$(wrap_color yellow "[--help|-h]:") Help message"
echo
echo -e "$(wrap_color yellow "Options:")"
echo -e "\t-h This help message"
echo
echo -e "\t-l <DIR>"
echo -e "\t\tLoad images from DIR"
echo -e "\t\tMust specify the directory"
echo -e "\tOR just run something like this"
echo -e "\t\tfor i in \`ls *.xz\`; do xzcat \$i | docker load; done"
echo
echo -e "\t-o <DIR>"
echo -e "\t\tOutput directory for saved docker images"
echo -e "\t\tDEFAULT is the current working directory"
echo
echo -e "\t-n <N>"
echo -e "\t\tNumber of cpu core to be used for compression"
echo -e "\t\tDEFAULT is the number of available cores, $(grep -c processor /proc/cpuinfo)"
echo
echo -e "\t-c <N>"
echo -e "\t\tCompression level"
echo -e "\t\tDEFAULT=$COMPRESS_LEVEL; MIN=0, MAX=9"
echo
echo -e "$(wrap_color yellow "Environment Variables:")"
echo -e "\t$(wrap_color red "IMG") List of docker images to be saved"
echo -e "\t DEFAULT is the list of images from docker images"
echo
echo -e "\t$(wrap_color red "COMPRESSOR") Compressor command line; take STDIN and output to STDOUT"
echo -e "\t\tDEFAULT COMPRESSOR=\"pxz -T$CPUS -c$COMPRESS_LEVEL - \""
echo
echo -e "\t$(wrap_color red "COMP_EXT") The file extension if the above variable is set"
echo -e "\t\tDEFAULT COMP_EXT=xz"
echo
echo -e "\t$(wrap_color red "FILTER") The command to filter the output of \`docker images\`"
echo -e "\t\tDefault FILTER=\"grep -vi \"^<None>\""
echo
echo -e "$(wrap_color yellow Examples:)"
echo -e "\t1) Save all current docker images except the <None> ones to current working directory"
echo -e "\t\t\$ $0"
echo
echo -e "\t2) Save one container"
echo -e "\t\t\$ IMG=debian:jessie $0"
echo
echo -e "\t3) Use 4 cpu cores for pxz (default), output to 'images' directory, maximum compression level"
echo -e "\t\t\$ $0 -n 4 -o docker_images -c 9"
echo
echo -e "\t4) Load docker images from a directory"
echo -e "\t\t\$ $0 -l docker_images"
echo
echo -e "__author__: tuan t. pham <tuan at vt dot edu>"
}
function set_compressor()
{
if [ "$COMPRESSOR" ]; then
echo "Using user compressor command '$COMPRESSOR'"
echo "Filename extension = .$COMP_EXT"
return
fi
which pxz >/dev/null
if [ $? = 0 ]; then
COMPRESSOR="pxz -T$CPUS -c$COMPRESS_LEVEL - "
else
which xz >/dev/null
if [ $? = 0 ]; then
COMPRESSOR="xz -z -c$COMPRESS_LEVEL "
fi
fi
if [ ! "$COMPRESSOR" ]; then
echo "Use the default compressor gz"
COMPRESSOR="gz -c$COMPRESS_LEVEL"
COMP_EXT="gz"
else
COMP_EXT="xz"
fi
}
function get_img()
{
if [ ! "$IMG" ]; then
IMG=$(eval "$IMG_CMD")
fi
}
# load_images DIR
function load_images()
{
if [ -d "$1" ]; then
for d in $(ls "$1"/*.tar.xz); do
xzcat $d | docker load
done
else
echo "Directory $1 does not exist"
fi
}
function docker_save()
{
set_compressor
echo "Compressor Command = '$COMPRESSOR'"
get_img
echo -e "Saving $(echo "$IMG" | sed -s "s/ /\n/g" | wc -l) image(s):\n$IMG"
for i in $IMG
do
echo -e "\nSaving docker image '$i'"
OUTFILE=$(echo $i | tr '\:' '_')
CMD="docker save \$i | \$COMPRESSOR > \$OUTDIR/\$OUTFILE.tar.$COMP_EXT"
echo "Output file = '$OUTDIR/$OUTFILE.tar.$COMP_EXT'"
# echo $CMD
eval "$CMD"
done
}
function parse_opts()
{
while getopts $OPTS opt; do
case $opt in
l)
log "Setting loading files from directory $OPTARG"
LOAD_DIR=$OPTARG
;;
o)
log "Setting the OUTDIR to \'$OPTARG\'"
OUTDIR=$OPTARG
[ -d "$OUTDIR" ] || mkdir -p $OUTDIR
;;
n)
log "Setting the number of cpus to $OPTARG"
CPUS=$OPTARG
;;
c)
log "Setting compression level $OPTARG"
COMPRESS_LEVEL=$OPTARG
;;
h)
log "Setting -h option"
help_msg
exit 0
;;
\?)
echo "Invalid option(s)"
help_msg
exit 1
;;
esac
done
}
function main()
{
if [ "$1" = "--help" ]; then
help_msg
exit 0
fi
parse_opts "$@"
[ "$LOAD_DIR" ] && load_images $LOAD_DIR && exit 0
[ "$DEBUG" = 1 ] && dump_vars
docker_save
}
main "$@"