~josvaz/ubuntu-on-ec2/ec2-publishing-scripts-lp1613470-udev-cdrom

112 by Scott Moser
add non-working version of ec2-image2ebs
1
#!/bin/bash
2
# vi: ts=4 noexpandtab
3
4
TEMP_D=""
113 by Scott Moser
first generally functional ec2-image2ebs script
5
VOLUME_ID=""
6
VOLUME_ATTACHED=0
7
SNAPSHOT_ID=""
120 by Scott Moser
get rid of the ssh config in ec2-image2ebs.
8
SSH_USER=${SSH_USER:-ubuntu}
113 by Scott Moser
first generally functional ec2-image2ebs script
9
REGARGS=( )
370 by Scott Moser
ec2-image2ebs: retry ssh verify connection. more quiet apt-get.
10
IID=""
115 by Scott Moser
some '--region' argument fixes, use $SSH rather than ssh
11
SSH=${SSH:-"ssh"}
113 by Scott Moser
first generally functional ec2-image2ebs script
12
369 by Scott Moser
ec2-image2ebs, run-instance-and-wait: add prefix, make more quiet
13
error() { echo ${PREFIX:+"${PREFIX}"} "$@" 1>&2; }
556.1.1 by Ben Howard
Inital work
14
fail() {
113 by Scott Moser
first generally functional ec2-image2ebs script
15
	isfalse ${SNAPSHOT_ID} || delete_snapshot "${SNAPSHOT_ID}"
112 by Scott Moser
add non-working version of ec2-image2ebs
16
	[ $# -eq 0 ] || error "$@";
370 by Scott Moser
ec2-image2ebs: retry ssh verify connection. more quiet apt-get.
17
	local out=""
384 by Scott Moser
run-instance-and-wait ec2-image2ebs, use info-instances
18
	[ -z "$IID" ] || out=$(xc2 info-instances "${REGARGS[@]}" "${IID}")
370 by Scott Moser
ec2-image2ebs: retry ssh verify connection. more quiet apt-get.
19
	[ -n "$out" ] || error "$out"
112 by Scott Moser
add non-working version of ec2-image2ebs
20
	exit 1;
21
}
22
debug() {
23
	local level=${1}
24
	shift;
25
	[ "${level}" -gt "${VERBOSITY}" ] && return
634 by Robert Jennings
Remove "error" from debug output
26
	echo "$(date): ${@}" 1>&2
112 by Scott Moser
add non-working version of ec2-image2ebs
27
}
406.1.2 by Scott Moser
remove race condition in detach_vol
28
get_volstate() {
29
	local vol="$1" tmp=""
30
	tmp=$(mktemp "$TEMP_D/describe_vol_out.$vol.XXXXXX") ||
31
		return 1
604 by Ben Howard
Drop all use of EUCA tools due to signing issues
32
	if xc2 describe-volumes "${REGARGS[@]}" "$vol" > "$tmp"; then
406.1.2 by Scott Moser
remove race condition in detach_vol
33
		_RET=$(awk '-F\t' '$1 == "VOLUME" { print $6 }' "$tmp")
34
		rm -f "$tmp"
35
		return 0
36
	fi
604 by Ben Howard
Drop all use of EUCA tools due to signing issues
37
	error "ec2-describe-volumes $vol failed"
406.1.2 by Scott Moser
remove race condition in detach_vol
38
	rm -f "$tmp"
39
	_RET=""
40
}
41
113 by Scott Moser
first generally functional ec2-image2ebs script
42
detach_vol() {
587 by Ben Howard
Be aggressive about calling detach on volumes
43
	local vol="${1}" log=${2:-/dev/null} max=${3:-20} state="" i=0 ret=1;
113 by Scott Moser
first generally functional ec2-image2ebs script
44
	debug 2 "detaching ${vol}"
589 by Robert Jennings
Fix until; do; done syntax
45
	until [ "${i}" -gt "${max}" -o "$state" = "available" ]; do
587 by Ben Howard
Be aggressive about calling detach on volumes
46
		i=$(($i + 1))
47
		retry 3 30 get_volstate "$vol" && state="${_RET}"
48
		debug 2 "volume state after pass $i/$max, state=$state"
49
		case "${state}" in
590 by Robert Jennings
Missing ;; for case statement
50
			available) debug 2 "${vol} is available, returning 0"; ret=0;;
587 by Ben Howard
Be aggressive about calling detach on volumes
51
			in-use)	   debug 2 "${vol} is attached calling for detach";
52
					   retry 3 30 xc2 detach-volume "${REGARGS[@]}" "${vol}" > ${log};
53
					   sleep 60;;
54
		esac
326 by Scott Moser
make detach_vol return false if it doesn't result in detached volume
55
	done
587 by Ben Howard
Be aggressive about calling detach on volumes
56
	error "after $i waits, $vol, state=$state"
326 by Scott Moser
make detach_vol return false if it doesn't result in detached volume
57
	return $ret
113 by Scott Moser
first generally functional ec2-image2ebs script
58
}
59
60
delete_vol() {
61
	local vol=${1}
62
	debug 2 "deleting ${vol}"
327 by Ben Howard
Added support to define specific EC2 regions via EC2_ALL_REGIONS environmental variable
63
113 by Scott Moser
first generally functional ec2-image2ebs script
64
	xc2 delete-volume "${REGARGS[@]}" "${vol}" > ${2:-/dev/null} ||
65
		{ error "failed to delete ${vol}"; return 1; }
66
}
67
delete_snapshot() {
68
	local snap_id=${1}
69
	debug 2 "deleting ${snap_id}"
70
	xc2 delete-snapshot "${REGARGS[@]}" "${snap_id}" > ${2:-/dev/null} ||
71
		{ error "failed to delete ${snap_id}"; return 1; }
72
}
73
74
istrue() {
75
	[ -n "$1" -a "$1" != "0" ]
76
}
77
isfalse() {
78
	[ -z "$1" -o "$1" = "0" ]
79
}
112 by Scott Moser
add non-working version of ec2-image2ebs
80
cleanup() {
585 by Ben Howard
longer timeout on volume detachment
81
	isfalse ${VOLUME_ATTACHED} || detach_vol "${VOLUME_ID}"
584 by Ben Howard
Due to ec2 failures, wrap everything in retry for EBS publication
82
	[ -z "${VOLUME_ID}" ] || retry 3 30 delete_vol "${VOLUME_ID}"
112 by Scott Moser
add non-working version of ec2-image2ebs
83
	[ -z "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
84
}
85
411 by Scott Moser
better handle cleaning up of instances in failed publish-build-ebs
86
killed() {
87
	error "${0##*/} killed"
88
	exit 143 # 143 is exit code of: bash -c 'sleep 3& kill $$'; echo $?
89
}
90
113 by Scott Moser
first generally functional ec2-image2ebs script
91
di_field() {
92
	local field=$1 f=""
556.1.1 by Ben Howard
Inital work
93
	local fields=( itype iid ami host host_int state
113 by Scott Moser
first generally functional ec2-image2ebs script
94
		key_name ami_launch_index product_codes
95
		instance_type launch_time placement kernel
96
		ramdisk )
97
98
	for((i=0;i<${#fields[@]};i++)); do
99
		[ "${fields[$i]}" = "${field}" ] && { f=$(($i+1)) ; break; }
100
	done
101
	[ -n "$f" ] || return 1
102
	local cmd='$1 == "INSTANCE" { print $'$f' }'
103
	_RET=$(awk '-F\t' "$cmd")
104
}
105
116 by Scott Moser
add yet another layer of indirection on ssh
106
xssh() {
107
    local host="$1"
108
	shift;
120 by Scott Moser
get rid of the ssh config in ec2-image2ebs.
109
	debug 2 "${SSH} ${SSH_OPTS} ${SSH_USER:+${SSH_USER}@}$host $*"
110
	${SSH} ${SSH_OPTS} ${SSH_USER:+${SSH_USER}@}$host "$@"
116 by Scott Moser
add yet another layer of indirection on ssh
111
}
112
287 by Scott Moser
ec2-image2ebs: retry the detach volume and delete volume commands
113
# retry(max,sleeptime, cmd)
114
# retry cmd up to max times until it suceeds, sleeping sleeptime in between
115
retry() {
116
    local max=$1 sleep=$2 i=0 ret=0;
117
    shift 2 || { debug 1 "bad input to retry"; return 1; }
118
    while :; do
119
        i=$(($i+1))
120
        "$@" ; ret=$?
121
        [ $ret -eq 0 ] && break
122
        [ $i -eq 1 ] && debug 1 "cmd failed [$i/$max]: $*" ||
123
            debug 2 "cmd failed [$i/$max]: $*"
124
        [ $i -lt $max ] || break
125
        sleep "$sleep"
126
    done
127
    if [ $ret -eq 0 ]; then
128
        [ $i -ne 1 ] && debug 1 "cmd passed [$i/$max]: $*"
129
        return 0
130
    fi
131
    return $ret
132
}
133
561 by Ben Howard
Make discard default mount option for SSD devices
134
write_discard() {
135
cat <<"EOF"
136
discard() {
602 by Ben Howard
Fix for SSD and Lucid
137
	local mnt="${1}"
138
	sudo sed -i -e 's|defaults|defaults,discard|g' "${mnt}/etc/fstab"
561 by Ben Howard
Make discard default mount option for SSD devices
139
}
140
EOF
141
}
142
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
143
write_hvmify() {
144
cat <<"EOF"
145
hvmify() {
146
	local mnt="${1}" vol="${2}"
259 by Scott Moser
fix a syntax error in ec2-image2ebs, and logic error in publish-build-ebs
147
	error "hvmify on ${mnt} for vol=${vol}"
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
148
	sudo sed -i \
149
		-e 's,^#GRUB_TERMINAL=console,GRUB_TERMINAL=console,' \
150
		"${mnt}/etc/default/grub"
643 by Robert C Jennings
Fix bash syntax error
151
	if [ -f "${mnt}/etc/default/grub.d/50-cloudimg-settings.cfg" ] ; then
644 by Robert C Jennings
Append grub options as root
152
		echo GRUB_HIDDEN_TIMEOUT=0.1 | \
153
			sudo tee --append \
154
				"${mnt}/etc/default/grub.d/50-cloudimg-settings.cfg" > /dev/null
642 by Robert C Jennings
Remove 10s grub timeout
155
	fi
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
156
	for m in sys proc dev; do sudo mount --bind "/${m}" "${mnt}/${m}"; done
157
	sudo chroot "${mnt}" update-grub
158
	sudo chroot "${mnt}" grub-install "${vol}"
601 by Ben Howard
Sync devices and force unmount
159
	sync
160
	for m in sys proc dev; do sudo umount -f "${mnt}/${m}"; done;
612 by Scott Moser
ec2-image2ebs: only create ttyS0.conf from tty1.conf if tty1.conf exists
161
	if [ -f "$mnt/etc/init/tty1.conf" ]; then
162
		# no upstart in vivid means no upstart jobs
163
		sudo cp "${mnt}/etc/init/tty1.conf" "${mnt}/etc/init/ttyS0.conf"
164
		sudo sed -i 's,tty1,ttyS0,' "${mnt}/etc/init/ttyS0.conf"
165
	fi
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
166
}
167
EOF
168
}
169
112 by Scott Moser
add non-working version of ec2-image2ebs
170
Usage() {
171
	cat <<EOF
113 by Scott Moser
first generally functional ec2-image2ebs script
172
Usage: ${0##*/} [ options ] instance-id arch imgurl register-name
112 by Scott Moser
add non-working version of ec2-image2ebs
173
556.1.1 by Ben Howard
Inital work
174
   Utilize 'instance-id' to
175
     - download 'imgurl',
113 by Scott Moser
first generally functional ec2-image2ebs script
176
     - populate a ebs snapshot with its content.
177
     - register an ebs boot instance for 'arch' as 'register-name'
112 by Scott Moser
add non-working version of ec2-image2ebs
178
179
   options:
180
       --region r        use '--region r' in ec2 commands
181
       --description d   register image with description 'd'
195 by Scott Moser
ec2-image2ebs: add '--snapshot-desc' argument
182
       --snapshot-desc d create snapshot with description 'd'
112 by Scott Moser
add non-working version of ec2-image2ebs
183
       --kernel aki      register image with kernel 'aki'
184
       --ramdisk ari     register image with ramdisk 'ari'
113 by Scott Moser
first generally functional ec2-image2ebs script
185
       --size s          create volume of size 's' (in Gig)
112 by Scott Moser
add non-working version of ec2-image2ebs
186
       --fstype f        put filesystem of type 'f' on volume
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
187
       --etype  t        "ebs type" type (hvm or ebs)
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
188
       --address         address instance by 'address' rather than looking up
112 by Scott Moser
add non-working version of ec2-image2ebs
189
    -v|--verbose         increase verbosity
369 by Scott Moser
ec2-image2ebs, run-instance-and-wait: add prefix, make more quiet
190
       --prefix P        prefix output messages with 'P'
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
191
       --sriov			 register with 'sriov=simple' for HVM
112 by Scott Moser
add non-working version of ec2-image2ebs
192
EOF
193
}
194
195
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
196
197
short_opts="hv"
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
198
long_opts="etype:,address:,description:,help,fstype:,image-md5:,kernel:,prefix:,ramdisk:,region:,snapshot-desc:,size:,ssh-id:,verbose,sriov"
112 by Scott Moser
add non-working version of ec2-image2ebs
199
getopt_out=$(getopt --name "${0##*/}" \
200
	--options "${short_opts}" --long "${long_opts}" -- "$@") &&
201
	eval set -- "${getopt_out}" ||
202
	bad_Usage
203
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
204
address=""
112 by Scott Moser
add non-working version of ec2-image2ebs
205
description=""
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
206
etype="ebs"
187 by Scott Moser
if --fstype is not passed, default to same fs type as image
207
fstype=""
189 by Scott Moser
correctly get image label through (tested this time),
208
# if fslabel is set to an empty string, then the filesystem label will be
209
# copied from the image.  If non-empty, this label will be used.
210
# if set to 'none' no label will be written
211
fslabel=""
112 by Scott Moser
add non-working version of ec2-image2ebs
212
kernel=""
213
ramdisk=""
214
region=""
215
ssh_id=""
113 by Scott Moser
first generally functional ec2-image2ebs script
216
size="15"
195 by Scott Moser
ec2-image2ebs: add '--snapshot-desc' argument
217
snapshot_desc=""
215 by Scott Moser
ec2-image2ebs: add --image-md5 flag
218
image_md5=""
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
219
sriov=0
112 by Scott Moser
add non-working version of ec2-image2ebs
220
VERBOSITY=0
369 by Scott Moser
ec2-image2ebs, run-instance-and-wait: add prefix, make more quiet
221
PREFIX=""
112 by Scott Moser
add non-working version of ec2-image2ebs
222
223
while [ $# -ne 0 ]; do
224
	cur=${1}; next=${2};
225
	case "$cur" in
226
		-h|--help) Usage; exit 0;;
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
227
		   --address) address=${next}; shift;;
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
228
		   --etype) etype=${next}; shift;;
113 by Scott Moser
first generally functional ec2-image2ebs script
229
		   --description) description=${next}; shift;;
215 by Scott Moser
ec2-image2ebs: add --image-md5 flag
230
		   --image-md5) image_md5=${next}; shift;;
113 by Scott Moser
first generally functional ec2-image2ebs script
231
		   --kernel) kernel=${next}; shift;;
232
		   --ramdisk) ramdisk=${next}; shift;;
233
		   --size) size=${next}; shift;;
234
		   --fstype) fstype=${next}; shift;;
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
235
		   --sriov) sriov=1;;
112 by Scott Moser
add non-working version of ec2-image2ebs
236
		-v|--verbose)
237
			VERBOSITY=$((${VERBOSITY}+1));;
238
		   --region)
239
			region=${next}; shift;;
240
		   --ssh-id)
241
			ssh_id="${next}"; shift;;
195 by Scott Moser
ec2-image2ebs: add '--snapshot-desc' argument
242
		   --snapshot-desc)
243
			snapshot_desc=${next}; shift;;
378 by Scott Moser
ec2-image2ebs: actually honor --prefix arg
244
		   --prefix)
245
			PREFIX="${next}"; shift;;
112 by Scott Moser
add non-working version of ec2-image2ebs
246
		--) shift; break;;
247
	esac
248
	shift;
249
done
250
113 by Scott Moser
first generally functional ec2-image2ebs script
251
[ $# -eq 4 ] ||
252
	bad_Usage "must provide instance-id arch imgurl register-name"
253
556.1.1 by Ben Howard
Inital work
254
REGARGS=( );
113 by Scott Moser
first generally functional ec2-image2ebs script
255
[ -n "${region}" ] && REGARGS=( "--region" "$region" )
256
112 by Scott Moser
add non-working version of ec2-image2ebs
257
iid=${1}
370 by Scott Moser
ec2-image2ebs: retry ssh verify connection. more quiet apt-get.
258
IID=$iid
113 by Scott Moser
first generally functional ec2-image2ebs script
259
arch=${2}
260
imgurl=${3}
261
register_name=${4}
262
195 by Scott Moser
ec2-image2ebs: add '--snapshot-desc' argument
263
[ -z "${snapshot_desc}" ] && snapshot_desc="${register_name}"
264
113 by Scott Moser
first generally functional ec2-image2ebs script
265
case "${arch}" in
266
	i386) ec2_arch=$arch;;
189 by Scott Moser
correctly get image label through (tested this time),
267
	amd64|x86_64) ec2_arch=x86_64;;
113 by Scott Moser
first generally functional ec2-image2ebs script
268
	*) fail "arch ${arch} not supported (i386 or x86_64)";;
269
esac
112 by Scott Moser
add non-working version of ec2-image2ebs
270
133 by Scott Moser
TMPDIR is the variable to define temp dir, not TEMPDIR
271
TEMP_D=$(mktemp -d ${TMPDIR:-/tmp}/${0##*/}.XXXXXX) ||
112 by Scott Moser
add non-working version of ec2-image2ebs
272
	fail "failed to make tmp dir"
411 by Scott Moser
better handle cleaning up of instances in failed publish-build-ebs
273
trap cleanup EXIT
274
trap killed SIGINT SIGTERM
112 by Scott Moser
add non-working version of ec2-image2ebs
275
367 by Scott Moser
utilize 'xc2 ximages' to avoid expensive 'xc2 describe-images'
276
export XC2_XIMAGES_CACHE_D=${XC2_XIMAGES_CACHE_D:-"$TEMP_D/ximgcache"}
277
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
278
rem_workd="/mnt/${0##*/}/${register_name##*/}.${arch}.${etype}"
112 by Scott Moser
add non-working version of ec2-image2ebs
279
rem_src_mnt="${rem_workd}/src_d"
280
rem_trg_mnt="${rem_workd}/trg_d"
281
rem_dl_d="${rem_workd}/dl"
113 by Scott Moser
first generally functional ec2-image2ebs script
282
rem_funcs="${rem_workd}/sh_funcs"
283
desc_instance="${TEMP_D}/instance.info"
284
vol_info="${TEMP_D}/volume.info"
285
vol_attach_info="${TEMP_D}/vol_attach.info"
286
vol_detach_info="${TEMP_D}/vol_detach.info"
287
vol_delete_info="${TEMP_D}/vol_delete.info"
288
create_snapshot_info="${TEMP_D}/create_snapshot.info"
289
desc_snapshot_poll="${TEMP_D}/desc_snapshot.poll"
290
register_info="${TEMP_D}/register.info"
291
vol_attach_dev=/dev/sdi
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
292
alt_attach_dev=/dev/xvdi
113 by Scott Moser
first generally functional ec2-image2ebs script
293
584 by Ben Howard
Due to ec2 failures, wrap everything in retry for EBS publication
294
retry 3 5 xc2 info-instances "${REGARGS[@]}" "${iid}" > "${desc_instance}" ||
113 by Scott Moser
first generally functional ec2-image2ebs script
295
	fail "failed to get information about instance $iid"
296
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
297
if [ -z "$address" ]; then
298
	di_field host < "${desc_instance}" && remaddr=${_RET} &&
299
		[ -n "${remaddr}" ] || fail "failed to read hostname for ${iid}"
300
else
301
	remaddr="$address"
302
fi
113 by Scott Moser
first generally functional ec2-image2ebs script
303
304
di_field placement < "${desc_instance}" && placement=${_RET} &&
305
	[ -n "${placement}" ] || fail "unable to determine availability zone"
306
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
307
debug 2 "${iid} is at ${remaddr} in zone ${placement}"
113 by Scott Moser
first generally functional ec2-image2ebs script
308
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
309
debug 1 "verifying connection to ${remaddr}"
471 by Ben Howard
Increased timeouts due to failures in us-west-1
310
retry 15 30s xssh "${remaddr}" /bin/true ||
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
311
	fail "failed to verify connection to ${remaddr}"
116 by Scott Moser
add yet another layer of indirection on ssh
312
113 by Scott Moser
first generally functional ec2-image2ebs script
313
# [host] attach a volume to the instance, wait for it to become available
584 by Ben Howard
Due to ec2 failures, wrap everything in retry for EBS publication
314
retry 3 5 xc2 create-volume "${REGARGS[@]}" --size "$size" \
115 by Scott Moser
some '--region' argument fixes, use $SSH rather than ssh
315
	--availability-zone "${placement}" > "${vol_info}" &&
113 by Scott Moser
first generally functional ec2-image2ebs script
316
	vol_id=$(awk '-F\t' '{print $2}' < "${vol_info}") && [ -n "${vol_id}" ] ||
317
	fail "failed to create a volume"
318
319
VOLUME_ID=${vol_id}
320
321
debug 2 "created volume ${vol_id}"
322
582 by Ben Howard
Retry on attach due to us-west-1 failures
323
retry 15 30 xc2 attach-volume "${REGARGS[@]}" --device "${vol_attach_dev}" \
113 by Scott Moser
first generally functional ec2-image2ebs script
324
	--instance "${iid}" "${vol_id}" > "${vol_attach_info}" &&
325
	VOLUME_ATTACHED=1 ||
586.1.1 by Robert Jennings
Log volume state for attach/detach failures
326
	(cat ${vol_attach_info} &&
327
	 get_volstate "$vol" &&
328
	 error "volume state is $_RET" &&
329
	 fail "failed to attach volume to ${vol_attach_dev}")
113 by Scott Moser
first generally functional ec2-image2ebs script
330
331
debug 2 "volume ${vol_id} attached to ${iid} at ${vol_attach_dev}"
112 by Scott Moser
add non-working version of ec2-image2ebs
332
297 by Scott Moser
rename uec -> cloud or cloudimg
333
# [instance] download the published tarfile from http://cloud-images.ubuntu.com
112 by Scott Moser
add non-working version of ec2-image2ebs
334
# [instance] extract image, mount loopback
218 by Scott Moser
ec2-image2ebs: test getter=lftp
335
getter="lftp"
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
336
debug 2 "obtaining image on ${remaddr}"
337
xssh "${remaddr}" bash -e <<EOF || fail "failed to download/setup image"
113 by Scott Moser
first generally functional ec2-image2ebs script
338
exec 1>&2
564 by Ben Howard
Further cleanup for EBS workers running out of space
339
[ -e "${rem_workd}" ] && sudo rm -rf "${rem_workd}"
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
340
[ -e "${rem_dl_d}" ] && sudo rm -rf "${rem_dl_d}"
113 by Scott Moser
first generally functional ec2-image2ebs script
341
sudo mkdir -p "${rem_src_mnt}" "${rem_trg_mnt}" "${rem_dl_d}"
556.1.1 by Ben Howard
Inital work
342
sudo chown -R \$(id -u) "${rem_workd}"
113 by Scott Moser
first generally functional ec2-image2ebs script
343
cat > "${rem_funcs}" <<"END"
369 by Scott Moser
ec2-image2ebs, run-instance-and-wait: add prefix, make more quiet
344
error() { echo "$PREFIX\$@" 1>&2; }
147 by Scott Moser
ec2-image2ebs: improve debug/error on no attached device
345
fail() { [ \$# -eq 0 ] || error "\$@" 1>&2; exit 1; }
113 by Scott Moser
first generally functional ec2-image2ebs script
346
[ ${VERBOSITY:-0} -ge 2 ] || exec 2>/dev/null
347
[ ${VERBOSITY:-0} -ge 3 ] && set -x
348
exec 1>&2
349
END
594 by Ben Howard
Use Google DNS resolvers
350
113 by Scott Moser
first generally functional ec2-image2ebs script
351
. ${rem_funcs}
352
214 by Scott Moser
add support for getting with lftp (but disabled at the moment)
353
out="${rem_dl_d}/img.tar.gz"
354
if [ ! -f "\${out}" ]; then
222 by Scott Moser
add download speed message
355
	start=\${SECONDS}
214 by Scott Moser
add support for getting with lftp (but disabled at the moment)
356
	case "$getter" in
357
		lftp)
459 by Scott Moser
improve output of in-instance downloading code
358
			dpkg-query --show lftp >/dev/null 2>&1 ||
375 by Scott Moser
redirect apt stdout to /dev/null for more quiet
359
				sudo env DEBIAN_FRONTEND=noninteractive \
360
					apt-get install lftp -qq >/dev/null
214 by Scott Moser
add support for getting with lftp (but disabled at the moment)
361
			imgurl="${imgurl}"
362
			proto=\${imgurl%%://*}
363
			site=\${imgurl#\${proto}://}; site=\${site%%/*};
364
			path=\${imgurl#\${proto}://\${site}/}
222 by Scott Moser
add download speed message
365
			lftp -c "open \${proto}://\${site}/ && pget \${path} -o \${out}" </dev/null
214 by Scott Moser
add support for getting with lftp (but disabled at the moment)
366
			;;
367
		*)
368
			wget "${imgurl}" --progress=dot:mega -O "\${out}"
369
			;;
370
	esac
222 by Scott Moser
add download speed message
371
	elapsed=\$((\${SECONDS}-\${start}))
372
	[ "\${elapsed}" = "0" ] && elapsed=1
373
	size=\$(stat --format "%s" "\${out}")
225 by Scott Moser
ec2-image2ebs: bash typo fix
374
	rate=\$(((\${size}/1024)/\${elapsed}))
459 by Scott Moser
improve output of in-instance downloading code
375
	error "got \${size} bytes in \${elapsed} seconds. \${rate} kB/s"
214 by Scott Moser
add support for getting with lftp (but disabled at the moment)
376
fi
377
215 by Scott Moser
ec2-image2ebs: add --image-md5 flag
378
if [ -n "${image_md5}" ]; then
379
	printf "%s  %s" "${image_md5}" "img.tar.gz" > "${rem_dl_d}/MD5SUMS"
369 by Scott Moser
ec2-image2ebs, run-instance-and-wait: add prefix, make more quiet
380
	( cd "${rem_dl_d}" && md5sum --check MD5SUMS ) >/dev/null
215 by Scott Moser
ec2-image2ebs: add --image-md5 flag
381
fi
382
113 by Scott Moser
first generally functional ec2-image2ebs script
383
tar -C "${rem_dl_d}" -Sxzf "${rem_dl_d}/img.tar.gz"
562 by Ben Howard
Remove img.tar.gz when done with untaring due to disk space errors
384
sudo rm "${rem_dl_d}/img.tar.gz"
112 by Scott Moser
add non-working version of ec2-image2ebs
385
imgfile=""
386
for f in "${rem_dl_d}/"*; do
387
	case \$f in
388
		*.img) imgfile=\$f; break;;
389
	esac
390
done
391
[ -n "\$imgfile" ] || fail "failed to find *.img in tarball"
188 by Scott Moser
fix typo/bug preventing use of e2label
392
img_label=\$(e2label "\${imgfile}")
187 by Scott Moser
if --fstype is not passed, default to same fs type as image
393
echo "img_label=\"\${img_label}\"" >> "${rem_funcs}"
113 by Scott Moser
first generally functional ec2-image2ebs script
394
sudo mount -o loop \${imgfile} "${rem_src_mnt}"
187 by Scott Moser
if --fstype is not passed, default to same fs type as image
395
396
img_fstype=\$(awk '\$2 == "${rem_src_mnt}" { val=\$3 }; END { print val }' < /proc/mounts)
397
echo "img_fstype=\"\${img_fstype}\"" >> "${rem_funcs}"
112 by Scott Moser
add non-working version of ec2-image2ebs
398
EOF
399
400
# [instance] mkfs on attached volume
401
# [instance] copy data from loopbacked image to ebs volume, sync
113 by Scott Moser
first generally functional ec2-image2ebs script
402
602 by Ben Howard
Fix for SSD and Lucid
403
if [[ "${etype}" =~ ssd ]]; then
561 by Ben Howard
Make discard default mount option for SSD devices
404
	debug 2 "writing discard to rem_funcs ${rem_funcs}"
405
	write_discard | xssh "$remaddr" sh -c "cat >> ${rem_funcs}"
406
fi
407
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
408
if [[ "${etype}" =~ hvm ]]; then
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
409
	debug 2 "writing hvmify to rem_funcs ${rem_funcs}"
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
410
	write_hvmify | xssh "$remaddr" sh -c "cat >> ${rem_funcs}"
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
411
fi
412
322 by Scott Moser
hopefully fix random ssh-keyscan timeouts in run-instance-and-wait
413
debug 2 "copying data on ${remaddr}"
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
414
xssh "$remaddr" bash -e <<EOF || fail "failed to copy data to volume"
113 by Scott Moser
first generally functional ec2-image2ebs script
415
. ${rem_funcs}
416
i=0;
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
417
418
vol_attach_dev=${vol_attach_dev};
419
alt_attach_dev="${alt_attach_dev}";
420
113 by Scott Moser
first generally functional ec2-image2ebs script
421
while [ \$i -lt 180 ]; do
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
422
	[ -e "${vol_attach_dev}" ] && break ||
423
		{ [ -e "\${alt_attach_dev}" ] &&
424
			vol_attach_dev=\${alt_attach_dev} && break; } ||
425
		sleep 2
113 by Scott Moser
first generally functional ec2-image2ebs script
426
	i=\$((\$i+1))
427
done
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
428
429
[ -e "\${vol_attach_dev}" ] || {
430
	error "\${vol_attach_dev} doesn't exist, showing /proc/partitions"
147 by Scott Moser
ec2-image2ebs: improve debug/error on no attached device
431
	cat /proc/partitions 1>&2
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
432
	fail "\${vol_attach_dev} does not exist"
147 by Scott Moser
ec2-image2ebs: improve debug/error on no attached device
433
}
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
434
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
435
fsdev="\${vol_attach_dev}"
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
436
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
437
if [[ "${etype}" =~ hvm ]]; then
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
438
	echo "1,,L,*" | sudo sfdisk "\${vol_attach_dev}" ||
439
		fail "failed to partition \${vol_attach_dev}"
440
	fsdev="\${vol_attach_dev}1"
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
441
fi
442
186 by Scott Moser
use the image filesystems label as the default for the ebs root fs label
443
label=\${img_label}
444
if [ -n "${fslabel}" ]; then
445
   [ "${fslabel}" = "none" ] && fslabel=""
446
   label="${fslabel}"
447
fi
189 by Scott Moser
correctly get image label through (tested this time),
448
xtype=\${img_fstype}
187 by Scott Moser
if --fstype is not passed, default to same fs type as image
449
if [ -n "${fstype}" ]; then
450
   xtype="${fstype}"
451
fi
452
mkfs_args="-t \${xtype}"
453
case "\${xtype}" in
454
	ext*) mkfs_args="\${mkfs_args} -F";;
455
esac
456
369 by Scott Moser
ec2-image2ebs, run-instance-and-wait: add prefix, make more quiet
457
error "creating fs: \$mkfs_args label=\${label} on \$fsdev"
458
sudo mkfs \${mkfs_args} \${label:+-L "\${label}"} "\${fsdev}" >/dev/null
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
459
sudo mount "\${fsdev}" "${rem_trg_mnt}"
114 by Scott Moser
add flags to rsync to preserve more
460
sudo rsync -aXHAS "${rem_src_mnt}/" "${rem_trg_mnt}"
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
461
602 by Ben Howard
Fix for SSD and Lucid
462
suite=\$(sudo chroot ${rem_trg_mnt} lsb_release --codename --short)
610 by Ben Howard
Fix detection of SSD volumes
463
if [[ ! "\${suite}" =~ (lucid|10.04) ]]; then
464
	# Only enable discard for Lucid and later
465
602 by Ben Howard
Fix for SSD and Lucid
466
	if [[ "${etype}" =~ ssd ]]; then
467
		discard "${rem_trg_mnt}"
468
	fi
561 by Ben Howard
Make discard default mount option for SSD devices
469
602 by Ben Howard
Fix for SSD and Lucid
470
	if [[ "${etype}" =~ hvm ]]; then
471
		hvmify "${rem_trg_mnt}" "\${vol_attach_dev}"
472
	fi
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
473
fi
474
587 by Ben Howard
Be aggressive about calling detach on volumes
475
sudo umount -f "${rem_trg_mnt}"
476
sudo umount -f "${rem_src_mnt}"
477
sync
563 by Ben Howard
Remove source locations for ebs worker reuse
478
sudo rm -rf "${rem_src_mnt}"
564 by Ben Howard
Further cleanup for EBS workers running out of space
479
sudo rm -rf "${rem_workd}"
287 by Scott Moser
ec2-image2ebs: retry the detach volume and delete volume commands
480
490 by Ben Howard
Enabled the use of 12.04 as a utility AMI for ebs creation
481
error "copied data to \${vol_attach_dev}"
112 by Scott Moser
add non-working version of ec2-image2ebs
482
EOF
483
484
# [host] detach volume, create-snapshot, delete-volume
585 by Ben Howard
longer timeout on volume detachment
485
detach_vol "${vol_id}" "${vol_detach_info}" ||
586.1.1 by Robert Jennings
Log volume state for attach/detach failures
486
	(get_volstate "$vol" &&
487
	 error "volume state is $_RET" &&
488
 	 fail "failed to detach volume")
113 by Scott Moser
first generally functional ec2-image2ebs script
489
490
VOLUME_ATTACHED=0
491
492
debug 2 "creating snapshot of ${vol_id}"
493
snap_start=${SECONDS}
584 by Ben Howard
Due to ec2 failures, wrap everything in retry for EBS publication
494
retry 10 60 xc2 create-snapshot "${REGARGS[@]}" \
195 by Scott Moser
ec2-image2ebs: add '--snapshot-desc' argument
495
	"--description=${snapshot_desc}" \
144 by Scott Moser
ec2-image2ebs: pass set description of snapshot to register name
496
	"${vol_id}" > "${create_snapshot_info}" &&
584 by Ben Howard
Due to ec2 failures, wrap everything in retry for EBS publication
497
	snapshot_id=$(awk '-F\t' 'END{print $2}' < "${create_snapshot_info}") &&
113 by Scott Moser
first generally functional ec2-image2ebs script
498
	[ -n "${snapshot_id}" ] ||
499
	fail "failed to create snapshot of ${vol_id}"
500
SNAPSHOT_ID=${snapshot_id}
501
584 by Ben Howard
Due to ec2 failures, wrap everything in retry for EBS publication
502
retry 5 60 delete_vol "${vol_id}" "${vol_delete_info}" ||
113 by Scott Moser
first generally functional ec2-image2ebs script
503
	fail "failed to delete volume ${vol_id}"
504
VOLUME_ID=""
505
506
failed_last=0
507
508
debug 2 "waiting for ${snapshot_id} to become complete"
112 by Scott Moser
add non-working version of ec2-image2ebs
509
# [host] wait for snapshot to leave pending
113 by Scott Moser
first generally functional ec2-image2ebs script
510
for((i=0;i<90;i++)); do
584 by Ben Howard
Due to ec2 failures, wrap everything in retry for EBS publication
511
	retry 3 10 xc2 info-snapshots "${REGARGS[@]}" "${snapshot_id}" \
113 by Scott Moser
first generally functional ec2-image2ebs script
512
		> "${desc_snapshot_poll}" && failed_last=0 ||
513
		failed_last=$((${failed_last}+1))
514
	[ "${failed_last}" -lt 30 ] ||
515
		fail "describe-snapshots failed ${failed_last} times in a row"
516
	if [ ${failed_last} -eq 0 ]; then
517
		state=$(awk '-F\t' '{print $4}' < "${desc_snapshot_poll}")
518
		case "${state}" in
519
			pending) :;;
520
			completed) break;;
521
			error) fail "snapshot ${snapshot_id} is in state 'errror'";;
522
			*) error "WARNING: unknown snapshot state \"${state}\"";;
523
		esac
524
		debug 2 "snapshot state is $state after $((${SECONDS}-${snap_start}))s"
525
	fi
471 by Ben Howard
Increased timeouts due to failures in us-west-1
526
	sleep 15
113 by Scott Moser
first generally functional ec2-image2ebs script
527
done
528
529
debug 1 "snapshot complete after $((${SECONDS}-${snap_start})) seconds"
530
112 by Scott Moser
add non-working version of ec2-image2ebs
531
# [host] register
113 by Scott Moser
first generally functional ec2-image2ebs script
532
args=( "${REGARGS[@]}" "--architecture=${ec2_arch}" "--name=${register_name}" )
533
[ -n "${description}" ] && args[${#args[@]}]="--description=${description}"
534
[ -n "${kernel}" ]      && args[${#args[@]}]="--kernel=${kernel}"
535
[ -n "${ramdisk}" ]     && args[${#args[@]}]="--ramdisk=${ramdisk}"
536
239 by Scott Moser
ec2-image2ebs: add comment on use of --block-device-mapping in ec2-register
537
# Note (2010-08-31):
538
#  passing --block-device-mapping as shown here does get block devices
539
#  mapped for the 2 explicit cases.  Other block devices will not be
540
#  present by default, though.  ie, on an m1.large, which should have 2
541
#  ephemeral block devices, you will get only 1.
542
#
543
#  if you do not pass *any* --block-device-mapping, you will get no
544
#  ephemeral block devices.
545
#
546
#  if you pass a long list:
547
#    --block-device-mapping sdb=ephemeral0
548
#    --block-device-mapping sdc=ephemeral1
549
#    --block-device-mapping sdd=ephemeral2
550
#    --block-device-mapping sde=ephemeral3
551
#
552
#  then you will get that all appropriate block devices for the given size
553
#  when you run it (ie, m1.large will have sdb and sdc), but the
554
#  metadata will also have entries for sdd and sde.  That fact will *not*
555
#  prevent you from attaching a volume as '--device /dev/sde'
556
#
557
#  the end result of all of this is that almost all ubuntu EBS instances
558
#  will only have a single ephemeral device node unless the user
559
#  changes arguments at launch time.
258 by Scott Moser
initial commit for publishing to hvm instances (cluster compute)
560
case "${ec2_arch}:${etype}" in
556.1.1 by Ben Howard
Inital work
561
	x86_64:ebs*)
113 by Scott Moser
first generally functional ec2-image2ebs script
562
		args[${#args[@]}]="--block-device-mapping"
563
 		args[${#args[@]}]="/dev/sdb=ephemeral0"
564
		;;
556.1.1 by Ben Howard
Inital work
565
	i386:ebs*)
113 by Scott Moser
first generally functional ec2-image2ebs script
566
		args[${#args[@]}]="--block-device-mapping"
567
 		args[${#args[@]}]="/dev/sda2=ephemeral0"
568
		;;
556.1.1 by Ben Howard
Inital work
569
	x86_64:hvm*)
263 by Scott Moser
add appropriate block-device-mappings for hvm types
570
		args[${#args[@]}]="--block-device-mapping"
571
 		args[${#args[@]}]="/dev/sdb=ephemeral0"
572
		args[${#args[@]}]="--block-device-mapping"
573
 		args[${#args[@]}]="/dev/sdc=ephemeral1"
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
574
		[ "${sriov:-0}" -eq 1 ] &&
575
			 args[${#args[@]}]="--sriov=simple"
556.1.1 by Ben Howard
Inital work
576
		;;
577
esac
578
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
579
# Handle the specific mappings
580
debug 1 "ec2-images2ebs: etype is ${etype}"
556.1.1 by Ben Howard
Inital work
581
case "${etype}" in
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
582
	*ssd)
583
		# SSDs use the gp2 disk type
556.1.1 by Ben Howard
Inital work
584
		args[${#args[@]}]="--block-device-mapping"
585
		args[${#args[@]}]="/dev/sda1=${snapshot_id}::true:gp2"
586
		;;
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
587
	*io1)
570 by Ben Howard
Removed provisioned IOPS setting per AWS request
588
		# Provisioned IOPs use io1
556.1.1 by Ben Howard
Inital work
589
		args[${#args[@]}]="--block-device-mapping"
572 by Ben Howard
Reduce PIOPS to the proper amount. Since these are 8GB volumes, the max 30:1 ratio is 240
590
		args[${#args[@]}]="/dev/sda1=${snapshot_id}::true:io1:200"
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
591
		;;
592
	*)
593
		args[${#args[@]}]="--snapshot"
556.1.1 by Ben Howard
Inital work
594
		args[${#args[@]}]="${snapshot_id}"
595
		;;
596
esac
113 by Scott Moser
first generally functional ec2-image2ebs script
597
556.1.2 by Ben Howard
Working code for production of EBS io1 and SSD disks for both paravirtual
598
[[ "${etype}" =~ hvm ]] && args[${#args[@]}]="--virtualization-type=hvm"
599
113 by Scott Moser
first generally functional ec2-image2ebs script
600
debug 1 "registering: register ${args[*]}"
581 by Ben Howard
Retry around image registration due to us-west-2 failures
601
retry 15 30 xc2 ximages register "${args[@]}" > "${register_info}" &&
602
	new_ami=$(awk '-F\t' 'END{print $2}' < "${register_info}") &&
113 by Scott Moser
first generally functional ec2-image2ebs script
603
	[ -n "${new_ami}" ] && SNAPSHOT_ID="" ||
604
	fail "failed to register: xc2 register ${args[*]}"
605
146 by Scott Moser
ec2-image2ebs: add debug statement with new_ami in it
606
debug 1 "published ${register_name} as ${new_ami}"
113 by Scott Moser
first generally functional ec2-image2ebs script
607
echo "${new_ami}"
112 by Scott Moser
add non-working version of ec2-image2ebs
608
exit 0