~philroche/ubuntu-on-ec2/ec2-publishing-scripts-kernel-panic-revert

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 "$@"