Browse code

Add exercise that boots an instance from a volume.

* Launches a cirros builder instance
* Mounts a disk to the builder instance
* Creates a bootable volume from builder
* Launches the volume-backed instance
* Update glance syntax
* Don't require instance-to-web communication (that only works with
fully configured floating ips)
* Add footer/header

Change-Id: Ia6dcf399ee49154aaf4e597b060164c2f41cf3d2

Anthony Young authored on 2012/02/11 14:42:39
Showing 1 changed files
1 1
new file mode 100755
... ...
@@ -0,0 +1,253 @@
0
+#!/usr/bin/env bash
1
+
2
+# **boot_from_volume.sh**
3
+
4
+# This script demonstrates how to boot from a volume.  It does the following:
5
+#  *  Create a 'builder' instance
6
+#  *  Attach a volume to the instance
7
+#  *  Format and install an os onto the volume
8
+#  *  Detach volume from builder, and then boot volume-backed instance
9
+
10
+echo "**************************************************"
11
+echo "Begin DevStack Exercise: $0"
12
+echo "**************************************************"
13
+
14
+# This script exits on an error so that errors don't compound and you see
15
+# only the first error that occured.
16
+set -o errexit
17
+
18
+# Print the commands being run so that we can see the command that triggers
19
+# an error.  It is also useful for following allowing as the install occurs.
20
+set -o xtrace
21
+
22
+
23
+# Settings
24
+# ========
25
+
26
+# Keep track of the current directory
27
+EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
28
+TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
29
+
30
+# Import common functions
31
+source $TOP_DIR/functions
32
+
33
+# Import configuration
34
+source $TOP_DIR/openrc
35
+
36
+# Import exercise configuration
37
+source $TOP_DIR/exerciserc
38
+
39
+# Boot this image, use first AMI image if unset
40
+DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-ami}
41
+
42
+# Instance type
43
+DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
44
+
45
+# Default floating IP pool name
46
+DEFAULT_FLOATING_POOL=${DEFAULT_FLOATING_POOL:-nova}
47
+
48
+# Grab the id of the image to launch
49
+IMAGE=`glance -f index | egrep $DEFAULT_IMAGE_NAME | head -1 | cut -d" " -f1`
50
+
51
+die_if_not_set IMAGE "Failure getting image"
52
+
53
+# Instance and volume names
54
+INSTANCE_NAME=${INSTANCE_NAME:-test_instance}
55
+VOL_INSTANCE_NAME=${VOL_INSTANCE_NAME:-test_vol_instance}
56
+VOL_NAME=${VOL_NAME:-test_volume}
57
+
58
+# Clean-up from previous runs
59
+nova delete $VOL_INSTANCE_NAME || true
60
+nova delete $INSTANCE_NAME || true
61
+
62
+# Wait till server is gone
63
+if ! timeout $ACTIVE_TIMEOUT sh -c "while nova show $INSTANCE_NAME; do sleep 1; done"; then
64
+    echo "server didn't terminate!"
65
+    exit 1
66
+fi
67
+
68
+# Configure Security Groups
69
+SECGROUP=${SECGROUP:-test_secgroup}
70
+nova secgroup-delete $SECGROUP || true
71
+nova secgroup-create $SECGROUP "$SECGROUP description"
72
+nova secgroup-add-rule $SECGROUP icmp -1 -1 0.0.0.0/0
73
+nova secgroup-add-rule $SECGROUP tcp 22 22 0.0.0.0/0
74
+
75
+# Determinine instance type
76
+INSTANCE_TYPE=`nova flavor-list | grep $DEFAULT_INSTANCE_TYPE | cut -d"|" -f2`
77
+if [[ -z "$INSTANCE_TYPE" ]]; then
78
+    # grab the first flavor in the list to launch if default doesn't exist
79
+   INSTANCE_TYPE=`nova flavor-list | head -n 4 | tail -n 1 | cut -d"|" -f2`
80
+fi
81
+
82
+# Setup Keypair
83
+KEY_NAME=test_key
84
+KEY_FILE=key.pem
85
+nova keypair-delete $KEY_NAME || true
86
+nova keypair-add $KEY_NAME > $KEY_FILE
87
+chmod 600 $KEY_FILE
88
+
89
+# Boot our instance
90
+VM_UUID=`nova boot --flavor $INSTANCE_TYPE --image $IMAGE --security_groups=$SECGROUP --key_name $KEY_NAME $INSTANCE_NAME | grep ' id ' | cut -d"|" -f3 | sed 's/ //g'`
91
+
92
+# check that the status is active within ACTIVE_TIMEOUT seconds
93
+if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova show $VM_UUID | grep status | grep -q ACTIVE; do sleep 1; done"; then
94
+    echo "server didn't become active!"
95
+    exit 1
96
+fi
97
+
98
+# Delete the old volume
99
+nova volume-delete $VOL_NAME || true
100
+
101
+# Free every floating ips - setting FREE_ALL_FLOATING_IPS=True in localrc will make life easier for testers
102
+if [ "$FREE_ALL_FLOATING_IPS" = "True" ]; then
103
+    nova floating-ip-list | grep nova | cut -d "|" -f2 | tr -d " " | xargs -n1 nova floating-ip-delete || true
104
+fi
105
+
106
+# Allocate floating ip
107
+FLOATING_IP=`nova floating-ip-create | grep $DEFAULT_FLOATING_POOL | cut -d '|' -f2 | tr -d ' '`
108
+
109
+# Make sure the ip gets allocated
110
+if ! timeout $ASSOCIATE_TIMEOUT sh -c "while ! nova floating-ip-list | grep -q $FLOATING_IP; do sleep 1; done"; then
111
+    echo "Floating IP not allocated"
112
+    exit 1
113
+fi
114
+
115
+# Add floating ip to our server
116
+nova add-floating-ip $VM_UUID $FLOATING_IP
117
+
118
+# Test we can ping our floating ip within ASSOCIATE_TIMEOUT seconds
119
+if ! timeout $ASSOCIATE_TIMEOUT sh -c "while ! ping -c1 -w1 $FLOATING_IP; do sleep 1; done"; then
120
+    echo "Couldn't ping server with floating ip"
121
+    exit 1
122
+fi
123
+
124
+# Create our volume
125
+nova volume-create --display_name=$VOL_NAME 1
126
+
127
+# Wait for volume to activate
128
+if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova volume-list | grep $VOL_NAME | grep available; do sleep 1; done"; then
129
+    echo "Volume $VOL_NAME not created"
130
+    exit 1
131
+fi
132
+
133
+# FIXME (anthony) - python-novaclient should accept a volume_name for the attachment param?
134
+DEVICE=/dev/vdb
135
+VOLUME_ID=`nova volume-list | grep $VOL_NAME  | cut -d '|' -f 2 | tr -d ' '`
136
+nova volume-attach $INSTANCE_NAME $VOLUME_ID $DEVICE
137
+
138
+# Wait till volume is attached
139
+if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova volume-list | grep $VOL_NAME | grep in-use; do sleep 1; done"; then
140
+    echo "Volume $VOL_NAME not created"
141
+    exit 1
142
+fi
143
+
144
+# The following script builds our bootable volume.
145
+# To do this, ssh to the builder instance, mount volume, and build a volume-backed image.
146
+STAGING_DIR=/tmp/stage
147
+CIRROS_DIR=/tmp/cirros
148
+ssh -o StrictHostKeyChecking=no -i $KEY_FILE cirros@$FLOATING_IP << EOF
149
+set -o errexit
150
+set -o xtrace
151
+sudo mkdir -p $STAGING_DIR
152
+sudo mkfs.ext3 -b 1024 $DEVICE 1048576
153
+sudo mount $DEVICE $STAGING_DIR
154
+# The following lines create a writable empty file so that we can scp
155
+# the actual file
156
+sudo touch $STAGING_DIR/cirros-0.3.0-x86_64-rootfs.img.gz
157
+sudo chown cirros $STAGING_DIR/cirros-0.3.0-x86_64-rootfs.img.gz
158
+EOF
159
+
160
+# Download cirros
161
+if [ ! -e cirros-0.3.0-x86_64-rootfs.img.gz ]; then
162
+    wget http://images.ansolabs.com/cirros-0.3.0-x86_64-rootfs.img.gz
163
+fi
164
+
165
+# Copy cirros onto the volume
166
+scp -o StrictHostKeyChecking=no -i $KEY_FILE cirros-0.3.0-x86_64-rootfs.img.gz cirros@$FLOATING_IP:$STAGING_DIR
167
+
168
+# Unpack cirros into volume
169
+ssh -o StrictHostKeyChecking=no -i $KEY_FILE cirros@$FLOATING_IP << EOF
170
+set -o errexit
171
+set -o xtrace
172
+cd $STAGING_DIR
173
+sudo mkdir -p $CIRROS_DIR
174
+sudo gunzip cirros-0.3.0-x86_64-rootfs.img.gz
175
+sudo mount cirros-0.3.0-x86_64-rootfs.img $CIRROS_DIR
176
+
177
+# Copy cirros into our volume
178
+sudo cp -pr $CIRROS_DIR/* $STAGING_DIR/
179
+
180
+cd
181
+sync
182
+sudo umount $CIRROS_DIR
183
+# The following typically fails.  Don't know why.
184
+sudo umount $STAGING_DIR || true
185
+EOF
186
+
187
+# Detach the volume from the builder instance
188
+nova volume-detach $INSTANCE_NAME $VOLUME_ID
189
+
190
+# Boot instance from volume!  This is done with the --block_device_mapping param.
191
+# The format of mapping is:
192
+# <dev_name>=<id>:<type>:<size(GB)>:<delete_on_terminate>
193
+# Leaving the middle two fields blank appears to do-the-right-thing
194
+VOL_VM_UUID=`nova boot --flavor $INSTANCE_TYPE --image $IMAGE --block_device_mapping vda=$VOLUME_ID:::0 --security_groups=$SECGROUP --key_name $KEY_NAME $VOL_INSTANCE_NAME | grep ' id ' | cut -d"|" -f3 | sed 's/ //g'`
195
+
196
+# Check that the status is active within ACTIVE_TIMEOUT seconds
197
+if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova show $VOL_VM_UUID | grep status | grep -q ACTIVE; do sleep 1; done"; then
198
+    echo "server didn't become active!"
199
+    exit 1
200
+fi
201
+
202
+# Add floating ip to our server
203
+nova remove-floating-ip  $VM_UUID $FLOATING_IP
204
+
205
+# Gratuitous sleep, probably hiding a race condition :/
206
+sleep 1
207
+
208
+# Add floating ip to our server
209
+nova add-floating-ip $VOL_VM_UUID $FLOATING_IP
210
+
211
+# Test we can ping our floating ip within ASSOCIATE_TIMEOUT seconds
212
+if ! timeout $ASSOCIATE_TIMEOUT sh -c "while ! ping -c1 -w1 $FLOATING_IP; do sleep 1; done"; then
213
+    echo "Couldn't ping volume-backed server with floating ip"
214
+    exit 1
215
+fi
216
+
217
+# Make sure our volume-backed instance launched
218
+ssh -o StrictHostKeyChecking=no -i $KEY_FILE cirros@$FLOATING_IP << EOF
219
+echo "success!"
220
+EOF
221
+
222
+# Delete volume backed instance
223
+nova delete $VOL_INSTANCE_NAME
224
+
225
+# Wait till our volume is no longer in-use
226
+if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova volume-list | grep $VOL_NAME | grep available; do sleep 1; done"; then
227
+    echo "Volume $VOL_NAME not created"
228
+    exit 1
229
+fi
230
+
231
+# Delete the volume
232
+nova volume-delete $VOL_NAME
233
+
234
+# Delete instance
235
+nova delete $INSTANCE_NAME
236
+
237
+# Wait for termination
238
+if ! timeout $ACTIVE_TIMEOUT sh -c "while nova show $INSTANCE_NAME; do sleep 1; done"; then
239
+    echo "server didn't terminate!"
240
+    exit 1
241
+fi
242
+
243
+# De-allocate the floating ip
244
+nova floating-ip-delete $FLOATING_IP
245
+
246
+# Delete secgroup
247
+nova secgroup-delete $SECGROUP
248
+
249
+set +o xtrace
250
+echo "**************************************************"
251
+echo "End DevStack Exercise: $0"
252
+echo "**************************************************"