24
by Scott Moser
add skeleton versions of remove-image remove-build and remove-manifest |
1 |
#!/bin/bash
|
2 |
# vi: ts=4 noexpandtab
|
|
3 |
||
30
by Scott Moser
implement remove-image |
4 |
TMPD="" |
5 |
VERBOSITY=0 |
|
24
by Scott Moser
add skeleton versions of remove-image remove-build and remove-manifest |
6 |
error() { echo "$@" 1>&2; } |
7 |
errorp() { printf "$@" 1>&2; } |
|
8 |
fail() { [ $# -eq 0 ] || error "$@"; exit 1; } |
|
9 |
failp() { [ $# -eq 0 ] || errorp "$@"; exit 1; } |
|
10 |
debug() { |
|
11 |
local level=${1} |
|
12 |
shift;
|
|
13 |
[ "${level}" -gt "${VERBOSITY}" ] && return |
|
634
by Robert Jennings
Remove "error" from debug output |
14 |
echo "$(date): ${@}" 1>&2 |
24
by Scott Moser
add skeleton versions of remove-image remove-build and remove-manifest |
15 |
}
|
343
by Scott Moser
remove-image: improvements to snapshot deleting |
16 |
get_img_entry() { |
17 |
# get all entries correlating to ami from describe-images output in input
|
|
18 |
# given valid input, this is the same as 'describe-images ami-id'
|
|
19 |
local ami="$1" |
|
20 |
awk '-F\t' '{ |
|
21 |
if ($1 == "IMAGE") { if ($2 == ami) cur=1; else cur=0; };
|
|
22 |
if ( cur == 1 ) print $0 }' "ami=$ami" |
|
23 |
}
|
|
24
by Scott Moser
add skeleton versions of remove-image remove-build and remove-manifest |
24 |
|
25 |
Usage() { |
|
26 |
cat <<EOF
|
|
27 |
Usage: ${0##*/} [ options ] region image-id
|
|
28 |
||
29 |
remove 'image-id' from 'region' on ec2.
|
|
30 |
||
31 |
This includes both unregistering and deleting.
|
|
32 |
Both operations are permenant, so be careful!
|
|
33 |
||
34 |
If image-id is kernel or ramdisk, check for other references, failing
|
|
35 |
if there are any.
|
|
36 |
||
37 |
-f | --follow if image-id is a machine image, remove
|
|
38 |
the associated kernel and ramdisk
|
|
39 |
-n | --dry-run only report what would be done
|
|
40 |
-s | --skip-referenced if image-id is a kernel or ramdisk and is
|
|
41 |
referenced by other images, silently continue
|
|
42 |
-v | --verbose increase verbosity
|
|
43 |
Example:
|
|
44 |
${0##*/} us-east-1 ami-abcdef
|
|
45 |
||
46 |
EOF
|
|
47 |
}
|
|
48 |
||
30
by Scott Moser
implement remove-image |
49 |
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; } |
50 |
||
51 |
cleanup() { |
|
52 |
[ -n "${TMPD}" -a -d "${TMPD}" ] && rm -Rf "${TMPD}" |
|
53 |
return 0 |
|
54 |
}
|
|
55 |
remove_image() { |
|
56 |
||
57 |
local short_opts="fhnsv" |
|
143
by Scott Moser
add cleaning support for ebs root images |
58 |
local long_opts="cache:,dry-run,follow,following:,help,skip-referenced,unpub-path-fmt:,verbose" |
30
by Scott Moser
implement remove-image |
59 |
getopt_out=$(getopt --name "${0##*/}" \ |
60 |
--options "${short_opts}" --long "${long_opts}" -- "$@") && |
|
61 |
eval set -- "${getopt_out}" || { bad_Usage; return 1; } |
|
62 |
||
63 |
local oifs=${IFS}; |
|
64 |
local region="" id="" img_info="" x="" |
|
108
by Scott Moser
remove-image fixes to --dry-run pass through and support for 'name' |
65 |
local id_info="" manif="" nmanif="" acl="" itype="" kernel="" ramdisk="" |
107
by Scott Moser
fix --following and --cache internal options in remove-image |
66 |
local dry_run=0 follow=0 skip=0 cur="" next="" followed="" |
108
by Scott Moser
remove-image fixes to --dry-run pass through and support for 'name' |
67 |
local VERBOSITY=0 # verbosity is local, but read by debug |
143
by Scott Moser
add cleaning support for ebs root images |
68 |
local unpub_path_fmt="" unpub_path="" |
30
by Scott Moser
implement remove-image |
69 |
|
70 |
local pt; pt=( ); # remove_image pass through |
|
71 |
local rpt; rpt=( ); # remove manifest pass through |
|
72 |
||
73 |
while [ $# -ne 0 ]; do |
|
74 |
cur=${1}; next=${2}; |
|
75 |
case "$cur" in |
|
76 |
--) shift; break;; |
|
77 |
-f|--follow) follow=1; pt[${#pt[@]}]=${cur};; |
|
78 |
--following) followed=${next}; shift;; |
|
79 |
-h|--help) Usage; return 0;; |
|
80 |
-n|--dry-run) |
|
81 |
dry_run=1; |
|
82 |
pt[${#pt[@]}]=${cur}; |
|
108
by Scott Moser
remove-image fixes to --dry-run pass through and support for 'name' |
83 |
rpt[${#rpt[@]}]=${cur};; |
30
by Scott Moser
implement remove-image |
84 |
-s|--skip-referenced) skip=1; pt[${#pt[@]}]=${cur};; |
143
by Scott Moser
add cleaning support for ebs root images |
85 |
--unpub-path-fmt)
|
86 |
unpub_path_fmt=${next}; |
|
87 |
pt[${#pt[@]}]="--unpub-path-fmt=${next}"; |
|
88 |
shift;;
|
|
30
by Scott Moser
implement remove-image |
89 |
-v|--verbose) |
108
by Scott Moser
remove-image fixes to --dry-run pass through and support for 'name' |
90 |
pt[${#pt[@]}]=${cur}; |
91 |
rpt[${#rpt[@]}]=${cur}; |
|
30
by Scott Moser
implement remove-image |
92 |
VERBOSITY=$((${VERBOSITY}+1));; |
93 |
-*) bad_Usage "confused by ${cur}"; return 1;; |
|
94 |
esac
|
|
95 |
shift;
|
|
96 |
done
|
|
97 |
||
98 |
region=${1} |
|
99 |
id=${2} |
|
100 |
||
101 |
[ $# -gt 2 ] && { bad_Usage "to many arguments given"; return 1; } |
|
102 |
[ $# -lt 2 ] && { bad_Usage "must provide region and image-id"; return 1; } |
|
103 |
||
104 |
if [ -z "${TMPD}" ]; then |
|
133
by Scott Moser
TMPDIR is the variable to define temp dir, not TEMPDIR |
105 |
TMPD=$(mktemp -d ${TMPDIR:-/tmp}/${0##*/}.XXXXXX) || |
30
by Scott Moser
implement remove-image |
106 |
{ error "failed to make temp dir"; return 1; } |
107 |
trap cleanup EXIT
|
|
108 |
fi
|
|
109 |
||
367
by Scott Moser
utilize 'xc2 ximages' to avoid expensive 'xc2 describe-images' |
110 |
img_info=${TMPD}/img_info.txt; |
111 |
xc2 ximages describe-images "--region=$region" --all > "$img_info" || |
|
400
by Scott Moser
remove-image: fail on failure of ximages describe-images |
112 |
fail "failed to describe-images --region=$region --all" |
30
by Scott Moser
implement remove-image |
113 |
|
114 |
# get manifest, public/private, type, kernel,ramdisk
|
|
143
by Scott Moser
add cleaning support for ebs root images |
115 |
id_info=$(awk '-F\t' '$2 == id { print $3,$6,$13,$9,$10,$11 }' \ |
30
by Scott Moser
implement remove-image |
116 |
"id=${id}" "OFS=|" "${img_info}" ) && |
117 |
{ IFS="|"; set -- ${id_info}; IFS=${oifs}; } || |
|
50
by Scott Moser
correctly identify when image isn't present |
118 |
error "failed to parse images info"
|
119 |
||
57
by Scott Moser
fix in remove-image for images that have on ramdisk and/or no kernel |
120 |
# ramdisk and kernel can be empty, in which case the 'set based split'
|
121 |
# above will result in 4 items in the list
|
|
143
by Scott Moser
add cleaning support for ebs root images |
122 |
[ $# -eq 5 -o $# -eq 6 ] || |
57
by Scott Moser
fix in remove-image for images that have on ramdisk and/or no kernel |
123 |
{ error "${id} not found in ${region}"; return 1; } |
30
by Scott Moser
implement remove-image |
124 |
|
143
by Scott Moser
add cleaning support for ebs root images |
125 |
nmanif=${1}; acl=${2}; st_type=${3}; itype=${4}; kernel=${5}; ramdisk=${6}; |
108
by Scott Moser
remove-image fixes to --dry-run pass through and support for 'name' |
126 |
|
143
by Scott Moser
add cleaning support for ebs root images |
127 |
local snapshots="" |
179
by Scott Moser
remove-image: only use manif if store is instance-store |
128 |
manif="" |
143
by Scott Moser
add cleaning support for ebs root images |
129 |
if [ "${st_type}" = "ebs" ]; then |
343
by Scott Moser
remove-image: improvements to snapshot deleting |
130 |
local my_snaps="" snap="" others="" |
131 |
get_img_entry "$id" < "$img_info" > "$TMPD/tmp.out" && |
|
132 |
my_snaps=$(awk '-F\t' '$1 == "BLOCKDEVICEMAPPING" && |
|
574
by Ben Howard
Fix remove-image to work with snapshots. |
133 |
$5 ~ /snap-/ { printf("%s ",$5) }' < "${TMPD}/tmp.out") && |
343
by Scott Moser
remove-image: improvements to snapshot deleting |
134 |
[ -n "$my_snaps" ] || |
135 |
{ error "failed to get snapshot info for ${id}"; return 1; } |
|
136 |
||
137 |
# filter out snapshots that are used by other (more than 1) builds
|
|
138 |
# this occurs when a daily build has been promoted as the promoted
|
|
139 |
# name re-uses the snapshot
|
|
140 |
snapshots="" |
|
141 |
for snap in $my_snaps; do |
|
142 |
others=$(awk '-F\t' ' |
|
143 |
$1 == "IMAGE" { curami=$2; curname=$3 };
|
|
576
by Ben Howard
Actually fixed bad duplicate snapshot detection |
144 |
$1 == "BLOCKDEVICEMAPPING" && $5 == snap && curami != ami \
|
343
by Scott Moser
remove-image: improvements to snapshot deleting |
145 |
{ printf("%s:%s ",curami,curname); }' \ |
146 |
"snap=$snap" ami="$id" "$img_info") || { |
|
147 |
error "failed check for other snaps for $id/$snap"; |
|
148 |
return 1; |
|
149 |
}
|
|
150 |
if [ -n "$others" ]; then |
|
151 |
error "Warn: not deleting $id/$snap. used by others: $others" |
|
152 |
else
|
|
153 |
snapshots="$snapshots $snap" |
|
154 |
fi
|
|
155 |
done
|
|
156 |
snapshots=${snapshots# } |
|
179
by Scott Moser
remove-image: only use manif if store is instance-store |
157 |
elif [ "${st_type}" = "instance-store" ]; then |
158 |
# due to 'ec2-register --name', manifest path isn't in describe-images
|
|
159 |
# output. need to get it elsewhere
|
|
160 |
manif=$(xc2 get-manifest-path "${id}" "${region}") |
|
143
by Scott Moser
add cleaning support for ebs root images |
161 |
fi
|
162 |
||
163 |
if [ -n "${unpub_path_fmt}" ]; then |
|
164 |
unpub_path=${unpub_path_fmt//%r/${region}} |
|
165 |
unpub_path=${unpub_path//%i/${id}} |
|
166 |
fi
|
|
167 |
||
30
by Scott Moser
implement remove-image |
168 |
# check if this manifest is registered more than once
|
169 |
local other="" |
|
143
by Scott Moser
add cleaning support for ebs root images |
170 |
|
171 |
## TODO: THIS IS BROKEN. To check if manifest path is registered
|
|
172 |
## more than once, you have to get the manifest path. but
|
|
173 |
## will not have that, only name
|
|
30
by Scott Moser
implement remove-image |
174 |
other=$(awk '-F\t' '$3 == manif && $2 != id { print $2 }' \ |
108
by Scott Moser
remove-image fixes to --dry-run pass through and support for 'name' |
175 |
"manif=${nmanif}" "id=${id}" "${img_info}") || |
30
by Scott Moser
implement remove-image |
176 |
{ error "failed to check for multi-registered manifest"; return 1; } |
177 |
[ -z "${other}" ] || |
|
108
by Scott Moser
remove-image fixes to --dry-run pass through and support for 'name' |
178 |
{ error "${id}:${nmanif} is multi-registered: ${other}"; return 1; } |
30
by Scott Moser
implement remove-image |
179 |
|
180 |
# if its a kernel or ramdisk, check public images
|
|
181 |
if [ "${itype}" = "kernel" -o "${itype}" = "ramdisk" ]; then |
|
182 |
local used_by="" |
|
183 |
# have to check that the image we find isn't the one followed
|
|
184 |
local cond='( $10 == id || $11 == id )' |
|
185 |
local action='{ printf("\t%s %s\n",$2,$3); }' |
|
186 |
[ -z "${followed}" ] || cond="${cond} && \$2 != \"${followed}\"" |
|
187 |
||
188 |
used_by=$(awk '-F\t' "${cond} ${action}" "id=${id}" "${img_info}" ) || |
|
189 |
{ error "failed to parse image info for ${id}"; return 1; } |
|
190 |
if [ -n "${used_by}" ]; then |
|
191 |
||
192 |
debugp 2 "%s used by:\n%s\n" "${id}" "${used_by}" |
|
193 |
||
194 |
if [ ${skip} -eq 0 ]; then |
|
195 |
errorp "%s referenced by public images%s\n" \ |
|
196 |
"${id}" "${followed:+ [followed from ${followed}]}" |
|
197 |
errorp "\t%s\n" " use --skip-referenced to skip" |
|
198 |
return 1; |
|
199 |
fi
|
|
200 |
||
201 |
# skip was set, just ignore
|
|
179
by Scott Moser
remove-image: only use manif if store is instance-store |
202 |
debugp 1 "skipping %s %s\n" "${id}" "${nmanif}" |
30
by Scott Moser
implement remove-image |
203 |
return 0 |
204 |
fi
|
|
205 |
# if its a machine and follow was given, then follow
|
|
206 |
elif [ "${itype}" = "machine" ]; then |
|
207 |
if [ ${follow} -ne 0 ]; then |
|
208 |
for x in "${kernel}" "${ramdisk}"; do |
|
209 |
[ -n "${x}" ] || continue; |
|
210 |
remove_image "${pt[@]}" --following=${id} "${region}" "${x}" || |
|
211 |
return 1; |
|
212 |
done
|
|
213 |
fi
|
|
214 |
else
|
|
179
by Scott Moser
remove-image: only use manif if store is instance-store |
215 |
error "bad type: ${itype} for ${id} [${nmanif}]" |
30
by Scott Moser
implement remove-image |
216 |
return 1 |
217 |
fi
|
|
218 |
||
219 |
# its safe to delete it now
|
|
143
by Scott Moser
add cleaning support for ebs root images |
220 |
local out="" |
30
by Scott Moser
implement remove-image |
221 |
if [ ${dry_run} -eq 0 ]; then |
367
by Scott Moser
utilize 'xc2 ximages' to avoid expensive 'xc2 describe-images' |
222 |
out=$(xc2 ximages deregister --region "${region}" "${id}" ) || { |
30
by Scott Moser
implement remove-image |
223 |
error "failed to unregister ${id}"; |
224 |
return 1; |
|
225 |
}
|
|
143
by Scott Moser
add cleaning support for ebs root images |
226 |
local snap
|
227 |
for snap in ${snapshots}; do |
|
343
by Scott Moser
remove-image: improvements to snapshot deleting |
228 |
out=$(xc2 delete-snapshot --region "${region}" "${snap}" ) || { |
143
by Scott Moser
add cleaning support for ebs root images |
229 |
error "Warn: failed to delete snapshot ${snap}: ${out}" |
343
by Scott Moser
remove-image: improvements to snapshot deleting |
230 |
return 1; |
231 |
}
|
|
143
by Scott Moser
add cleaning support for ebs root images |
232 |
done
|
30
by Scott Moser
implement remove-image |
233 |
fi
|
234 |
||
179
by Scott Moser
remove-image: only use manif if store is instance-store |
235 |
if [ "${st_type}" = "instance-store" ]; then |
346
by Scott Moser
remove-manifest: add --message-label argument |
236 |
remove-manifest --message-label "$id" \ |
237 |
${unpub_path:+--unpub-path=${unpub_path}} \ |
|
143
by Scott Moser
add cleaning support for ebs root images |
238 |
"${rpt[@]}" "${manif}" || |
239 |
{ error "failed to remove manifest ${manif}"; return 1; } |
|
344
by Scott Moser
remove-image: give 'delete' or 'deleted' message on deletion of ebs image |
240 |
else
|
345
by Scott Moser
remove-image: improve 'delete' message for ebs |
241 |
local xinfo="$id ${nmanif}${snapshots:+ [${snapshots}]}" |
347
by Scott Moser
remove-image: on actual deletion, write 'deleted' to stdout, not stderr |
242 |
[ $dry_run -eq 0 ] && echo "deleted $xinfo" || error "delete $xinfo" |
143
by Scott Moser
add cleaning support for ebs root images |
243 |
fi
|
30
by Scott Moser
implement remove-image |
244 |
|
245 |
}
|
|
246 |
||
247 |
remove_image "$@" |