Skip to content

Commit 440be4b

Browse files
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
1 parent ae60498 commit 440be4b

File tree

1 file changed

+253
-0
lines changed

1 file changed

+253
-0
lines changed

exercises/boot_from_volume.sh

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

0 commit comments

Comments
 (0)