Browse code

Improvements to DevStack's XenServer scripts

I have ensured:
- template gets re-used on second run
- template includes XenServer tools, and custom user accounts
- take snapshot before first boot, for easy re-run
- make host_ip_iface work with either eth2 or eth3
- make ssh into domU checks looser
- above is all ground work for improved jenkins tests
- added some more comments to make it scripts clearer

Change-Id: I5c45370bf8a1393d669480e196b13f592d29154f

John Garbutt authored on 2012/04/28 02:28:28
Showing 12 changed files
... ...
@@ -81,3 +81,9 @@ Step 5: Do cloudy stuff!
81 81
 * Play with horizon
82 82
 * Play with the CLI
83 83
 * Log bugs to devstack and core projects, and submit fixes!
84
+
85
+Step 6: Run from snapshot
86
+-------------------------
87
+If you want to quicky re-run devstack from a clean state,
88
+using the same settings you used in your previous run,
89
+you can revert the DomU to the snapshot called "before_first_boot"
... ...
@@ -1,46 +1,40 @@
1 1
 #!/bin/bash
2 2
 
3
-set -e
4
-
5
-declare -a on_exit_hooks
6
-
7
-on_exit()
8
-{
9
-    for i in $(seq $((${#on_exit_hooks[*]} - 1)) -1 0)
10
-    do
11
-        eval "${on_exit_hooks[$i]}"
12
-    done
13
-}
14
-
15
-add_on_exit()
16
-{
17
-    local n=${#on_exit_hooks[*]}
18
-    on_exit_hooks[$n]="$*"
19
-    if [[ $n -eq 0 ]]
20
-    then
21
-        trap on_exit EXIT
22
-    fi
23
-}
24
-
25
-# Abort if localrc is not set
26
-if [ ! -e ../../localrc ]; then
27
-    echo "You must have a localrc with ALL necessary passwords defined before proceeding."
28
-    echo "See the xen README for required passwords."
29
-    exit 1
30
-fi
3
+# This script is run by install_os_domU.sh
4
+#
5
+# It modifies the ubuntu image created by install_os_domU.sh
6
+# and previously moodified by prepare_guest_template.sh
7
+#
8
+# This script is responsible for:
9
+# - pushing in the DevStack code
10
+# - creating run.sh, to run the code on boot
11
+# It does this by mounting the disk image of the VM.
12
+#
13
+# The resultant image is then templated and started
14
+# by install_os_domU.sh
15
+
16
+# Exit on errors
17
+set -o errexit
18
+# Echo commands
19
+set -o xtrace
31 20
 
32 21
 # This directory
33 22
 TOP_DIR=$(cd $(dirname "$0") && pwd)
34 23
 
24
+# Include onexit commands
25
+. $TOP_DIR/scripts/on_exit.sh
26
+
35 27
 # Source params - override xenrc params in your localrc to suite your taste
36 28
 source xenrc
37 29
 
38
-# Echo commands
39
-set -o xtrace
40
-
30
+#
31
+# Parameters
32
+#
41 33
 GUEST_NAME="$1"
42 34
 
43
-# Directory where we stage the build
35
+#
36
+# Mount the VDI
37
+#
44 38
 STAGING_DIR=$($TOP_DIR/scripts/manage-vdi open $GUEST_NAME 0 1 | grep -o "/tmp/tmp.[[:alnum:]]*")
45 39
 add_on_exit "$TOP_DIR/scripts/manage-vdi close $GUEST_NAME 0 1"
46 40
 
... ...
@@ -76,7 +70,7 @@ cd $TOP_DIR
76 76
 cat <<EOF >$STAGING_DIR/etc/rc.local
77 77
 # network restart required for getting the right gateway
78 78
 /etc/init.d/networking restart
79
-GUEST_PASSWORD=$GUEST_PASSWORD STAGING_DIR=/ DO_TGZ=0 bash /opt/stack/devstack/tools/xen/prepare_guest.sh > /opt/stack/prepare_guest.log 2>&1
79
+chown -R stack /opt/stack
80 80
 su -c "/opt/stack/run.sh > /opt/stack/run.sh.log 2>&1" stack
81 81
 exit 0
82 82
 EOF
... ...
@@ -85,8 +79,12 @@ EOF
85 85
 echo $GUEST_NAME > $STAGING_DIR/etc/hostname
86 86
 
87 87
 # Hostname must resolve for rabbit
88
+HOSTS_FILE_IP=$PUB_IP
89
+if [ $MGT_IP != "dhcp" ]; then
90
+    HOSTS_FILE_IP=$MGT_IP
91
+fi
88 92
 cat <<EOF >$STAGING_DIR/etc/hosts
89
-$MGT_IP $GUEST_NAME
93
+$HOSTS_FILE_IP $GUEST_NAME
90 94
 127.0.0.1 localhost localhost.localdomain
91 95
 EOF
92 96
 
... ...
@@ -142,8 +140,6 @@ cat <<EOF >$STAGING_DIR/opt/stack/run.sh
142 142
 #!/bin/bash
143 143
 cd /opt/stack/devstack
144 144
 killall screen
145
-UPLOAD_LEGACY_TTY=yes HOST_IP=$PUB_IP VIRT_DRIVER=xenserver FORCE=yes MULTI_HOST=$MULTI_HOST HOST_IP_IFACE=$HOST_IP_IFACE $STACKSH_PARAMS ./stack.sh
145
+VIRT_DRIVER=xenserver FORCE=yes MULTI_HOST=$MULTI_HOST HOST_IP_IFACE=$HOST_IP_IFACE $STACKSH_PARAMS ./stack.sh
146 146
 EOF
147 147
 chmod 755 $STAGING_DIR/opt/stack/run.sh
148
-
149
-echo "Done"
150 148
deleted file mode 100755
... ...
@@ -1,40 +0,0 @@
1
-#!/usr/bin/env bash
2
-
3
-# Echo commands
4
-set -o xtrace
5
-
6
-# Head node host, which runs glance, api, keystone
7
-HEAD_PUB_IP=${HEAD_PUB_IP:-192.168.1.57}
8
-HEAD_MGT_IP=${HEAD_MGT_IP:-172.16.100.57}
9
-
10
-COMPUTE_PUB_IP=${COMPUTE_PUB_IP:-192.168.1.58}
11
-COMPUTE_MGT_IP=${COMPUTE_MGT_IP:-172.16.100.58}
12
-
13
-# Networking params
14
-FLOATING_RANGE=${FLOATING_RANGE:-192.168.1.196/30}
15
-
16
-# Variables common amongst all hosts in the cluster
17
-COMMON_VARS="$STACKSH_PARAMS MYSQL_HOST=$HEAD_MGT_IP RABBIT_HOST=$HEAD_MGT_IP GLANCE_HOSTPORT=$HEAD_MGT_IP:9292 FLOATING_RANGE=$FLOATING_RANGE"
18
-
19
-# Helper to launch containers
20
-function install_domU {
21
-    GUEST_NAME=$1 PUB_IP=$2 MGT_IP=$3 DO_SHUTDOWN=$4 TERMINATE=$TERMINATE STACKSH_PARAMS="$COMMON_VARS $5" ./build_domU.sh
22
-}
23
-
24
-# Launch the head node - headnode uses a non-ip domain name,
25
-# because rabbit won't launch with an ip addr hostname :(
26
-install_domU HEADNODE $HEAD_PUB_IP $HEAD_MGT_IP 1 "ENABLED_SERVICES=g-api,g-reg,key,n-api,n-sch,n-vnc,horizon,mysql,rabbit"
27
-
28
-if [ $HEAD_PUB_IP == "dhcp" ]
29
-then
30
-    guestnet=$(xe vm-list --minimal name-label=HEADNODE params=networks)
31
-    HEAD_PUB_IP=$(echo $guestnet | grep -w -o --only-matching "3/ip: [0-9,.]*;" | cut -d ':' -f2 | cut -d ';' -f 1)
32
-fi
33
-# Wait till the head node is up
34
-while ! curl -L http://$HEAD_PUB_IP | grep -q username; do
35
-    echo "Waiting for head node ($HEAD_PUB_IP) to start..."
36
-    sleep 5
37
-done
38
-
39
-# Build the HA compute host
40
-install_domU COMPUTENODE $COMPUTE_PUB_IP $COMPUTE_MGT_IP 0 "ENABLED_SERVICES=n-cpu,n-net,n-api"
... ...
@@ -1,7 +1,16 @@
1 1
 #!/bin/bash
2 2
 
3
+# This script is a level script
4
+# It must be run on a XenServer or XCP machine
5
+#
6
+# It creates a DomU VM that runs OpenStack services
7
+#
8
+# For more details see: README.md
9
+
3 10
 # Exit on errors
4 11
 set -o errexit
12
+# Echo commands
13
+set -o xtrace
5 14
 
6 15
 # Abort if localrc is not set
7 16
 if [ ! -e ../../localrc ]; then
... ...
@@ -16,12 +25,17 @@ TOP_DIR=$(cd $(dirname "$0") && pwd)
16 16
 # Source lower level functions
17 17
 . $TOP_DIR/../../functions
18 18
 
19
+# Include onexit commands
20
+. $TOP_DIR/scripts/on_exit.sh
21
+
22
+
23
+#
24
+# Get Settings
25
+#
26
+
19 27
 # Source params - override xenrc params in your localrc to suit your taste
20 28
 source xenrc
21 29
 
22
-# Echo commands
23
-set -o xtrace
24
-
25 30
 xe_min()
26 31
 {
27 32
   local cmd="$1"
... ...
@@ -29,22 +43,38 @@ xe_min()
29 29
   xe "$cmd" --minimal "$@"
30 30
 }
31 31
 
32
+
33
+#
34
+# Prepare Dom0
35
+# including installing XenAPI plugins
36
+#
37
+
32 38
 cd $TOP_DIR
33 39
 if [ -f ./master ]
34 40
 then
35 41
     rm -rf ./master
36 42
     rm -rf ./nova
37 43
 fi
44
+
45
+# get nova
38 46
 wget https://github.com/openstack/nova/zipball/master --no-check-certificate
39 47
 unzip -o master -d ./nova
40
-cp -pr ./nova/*/plugins/xenserver/xenapi/etc/xapi.d /etc/
41
-chmod a+x /etc/xapi.d/plugins/*
48
+
49
+# install xapi plugins
50
+XAPI_PLUGIN_DIR=/etc/xapi.d/plugins/
51
+if [ ! -d $XAPI_PLUGIN_DIR ]; then
52
+    # the following is needed when using xcp-xapi
53
+    XAPI_PLUGIN_DIR=/usr/lib/xcp/plugins/
54
+fi
55
+cp -pr ./nova/*/plugins/xenserver/xenapi/etc/xapi.d/plugins/* $XAPI_PLUGIN_DIR
56
+chmod a+x ${XAPI_PLUGIN_DIR}*
42 57
 
43 58
 mkdir -p /boot/guest
44 59
 
45
-GUEST_NAME=${GUEST_NAME:-"DevStackOSDomU"}
46
-SNAME="ubuntusnapshot"
47
-TNAME="ubuntuready"
60
+
61
+#
62
+# Configure Networking
63
+#
48 64
 
49 65
 # Helper to create networks
50 66
 # Uses echo trickery to return network uuid
... ...
@@ -84,7 +114,7 @@ function errorcheck() {
84 84
     fi
85 85
 }
86 86
 
87
-# Create host, vm, mgmt, pub networks
87
+# Create host, vm, mgmt, pub networks on XenServer
88 88
 VM_NET=$(create_network "$VM_BR" "$VM_DEV" "$VM_VLAN" "vmbr")
89 89
 errorcheck
90 90
 MGT_NET=$(create_network "$MGT_BR" "$MGT_DEV" "$MGT_VLAN" "mgtbr")
... ...
@@ -123,28 +153,48 @@ create_vlan $PUB_DEV $PUB_VLAN $PUB_NET
123 123
 create_vlan $VM_DEV $VM_VLAN $VM_NET
124 124
 create_vlan $MGT_DEV $MGT_VLAN $MGT_NET
125 125
 
126
-# dom0 ip
126
+# Get final bridge names
127
+if [ -z $VM_BR ]; then
128
+    VM_BR=$(xe_min network-list  uuid=$VM_NET params=bridge)
129
+fi
130
+if [ -z $MGT_BR ]; then
131
+    MGT_BR=$(xe_min network-list  uuid=$MGT_NET params=bridge)
132
+fi
133
+if [ -z $PUB_BR ]; then
134
+    PUB_BR=$(xe_min network-list  uuid=$PUB_NET params=bridge)
135
+fi
136
+
137
+# dom0 ip, XenAPI is assumed to be listening
127 138
 HOST_IP=${HOST_IP:-`ifconfig xenbr0 | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"`}
128 139
 
129
-# Set up ip forwarding
130
-if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then
131
-    # FIXME: This doesn't work on reboot!
132
-    echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network
140
+# Set up ip forwarding, but skip on xcp-xapi
141
+if [ -a /etc/sysconfig/network]; then
142
+    if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then
143
+      # FIXME: This doesn't work on reboot!
144
+      echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network
145
+    fi
133 146
 fi
134
-
135 147
 # Also, enable ip forwarding in rc.local, since the above trick isn't working
136 148
 if ! grep -q  "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then
137 149
     echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local
138 150
 fi
139
-
140 151
 # Enable ip forwarding at runtime as well
141 152
 echo 1 > /proc/sys/net/ipv4/ip_forward
142 153
 
154
+
155
+#
143 156
 # Shutdown previous runs
157
+#
158
+
144 159
 DO_SHUTDOWN=${DO_SHUTDOWN:-1}
160
+CLEAN_TEMPLATES=${CLEAN_TEMPLATES:-false}
145 161
 if [ "$DO_SHUTDOWN" = "1" ]; then
146 162
     # Shutdown all domU's that created previously
147
-    xe_min vm-list  name-label="$GUEST_NAME" | xargs ./scripts/uninstall-os-vpx.sh
163
+    clean_templates_arg=""
164
+    if $CLEAN_TEMPLATES; then
165
+        clean_templates_arg="--remove-templates"
166
+    fi
167
+    ./scripts/uninstall-os-vpx.sh $clean_templates_arg
148 168
 
149 169
     # Destroy any instances that were launched
150 170
     for uuid in `xe vm-list | grep -1 instance | grep uuid | sed "s/.*\: //g"`; do
... ...
@@ -160,34 +210,18 @@ if [ "$DO_SHUTDOWN" = "1" ]; then
160 160
     done
161 161
 fi
162 162
 
163
-# Start guest
164
-if [ -z $VM_BR ]; then
165
-    VM_BR=$(xe_min network-list  uuid=$VM_NET params=bridge)
166
-fi
167
-if [ -z $MGT_BR ]; then
168
-    MGT_BR=$(xe_min network-list  uuid=$MGT_NET params=bridge)
169
-fi
170
-if [ -z $PUB_BR ]; then
171
-    PUB_BR=$(xe_min network-list  uuid=$PUB_NET params=bridge)
172
-fi
173 163
 
174
-templateuuid=$(xe template-list name-label="$TNAME")
175
-if [ -n "$templateuuid" ]
176
-then
177
-    vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$GUEST_NAME")
178
-else
179
-    template=$(xe_min template-list name-label="Ubuntu 11.10 (64-bit)")
180
-    if [ -z "$template" ]
181
-    then
182
-        cp $TOP_DIR/devstackubuntupreseed.cfg /opt/xensource/www/
183
-        $TOP_DIR/scripts/xenoneirictemplate.sh "${HOST_IP}/devstackubuntupreseed.cfg"
184
-        MIRROR=${MIRROR:-archive.ubuntu.com}
185
-        sed -e "s,d-i mirror/http/hostname string .*,d-i mirror/http/hostname string $MIRROR," \
186
-            -i /opt/xensource/www/devstackubuntupreseed.cfg
187
-    fi
188
-    $TOP_DIR/scripts/install-os-vpx.sh -t "Ubuntu 11.10 (64-bit)" -v $VM_BR -m $MGT_BR -p $PUB_BR -l $GUEST_NAME -r $OSDOMU_MEM_MB -k "flat_network_bridge=${VM_BR}"
164
+#
165
+# Create Ubuntu VM template
166
+# and/or create VM from template
167
+#
189 168
 
190
-    # Wait for install to finish
169
+GUEST_NAME=${GUEST_NAME:-"DevStackOSDomU"}
170
+TNAME="devstack_template_folsom_11.10"
171
+SNAME_PREPARED="template_prepared"
172
+SNAME_FIRST_BOOT="before_first_boot"
173
+
174
+function wait_for_VM_to_halt() {
191 175
     while true
192 176
     do
193 177
         state=$(xe_min vm-list name-label="$GUEST_NAME" power-state=halted)
... ...
@@ -196,72 +230,199 @@ else
196 196
             break
197 197
         else
198 198
             echo "Waiting for "$GUEST_NAME" to finish installation..."
199
-            sleep 30
199
+            sleep 20
200 200
         fi
201 201
     done
202
+}
203
+
204
+templateuuid=$(xe template-list name-label="$TNAME")
205
+if [ -z "$templateuuid" ]; then
206
+    #
207
+    # Install Ubuntu over network
208
+    #
209
+
210
+    # try to find ubuntu template
211
+    ubuntu_template_name="Ubuntu 11.10 for DevStack (64-bit)"
212
+    ubuntu_template=$(xe_min template-list name-label="$ubuntu_template_name")
213
+
214
+    # remove template, if we are in CLEAN_TEMPLATE mode
215
+    if [ -n "$ubuntu_template" ]; then
216
+        if $CLEAN_TEMPLATES; then
217
+            xe template-param-clear param-name=other-config uuid=$ubuntu_template
218
+            xe template-uninstall template-uuid=$ubuntu_template force=true
219
+            ubuntu_template=""
220
+        fi
221
+    fi
222
+
223
+    # always update the preseed file, incase we have a newer one
224
+    PRESEED_URL=${PRESEED_URL:-""}
225
+    if [ -z "$PRESEED_URL" ]; then
226
+        PRESEED_URL="${HOST_IP}/devstackubuntupreseed.cfg"
227
+        HTTP_SERVER_LOCATION="/opt/xensource/www"
228
+        if [ ! -e $HTTP_SERVER_LOCATION ]; then
229
+            HTTP_SERVER_LOCATION="/var/www/html"
230
+            mkdir -p $HTTP_SERVER_LOCATION
231
+        fi
232
+        cp -f $TOP_DIR/devstackubuntupreseed.cfg $HTTP_SERVER_LOCATION
233
+        MIRROR=${MIRROR:-""}
234
+        if [ -n "$MIRROR" ]; then
235
+            sed -e "s,d-i mirror/http/hostname string .*,d-i mirror/http/hostname string $MIRROR," \
236
+                -i "${HTTP_SERVER_LOCATION}/devstackubuntupreseed.cfg"
237
+        fi
238
+    fi
239
+
240
+    if [ -z "$ubuntu_template" ]; then
241
+        $TOP_DIR/scripts/xenoneirictemplate.sh $PRESEED_URL
242
+    fi
202 243
 
244
+    # create a new VM with the given template
245
+    # creating the correct VIFs and metadata
246
+    $TOP_DIR/scripts/install-os-vpx.sh -t "$ubuntu_template_name" -v $VM_BR -m $MGT_BR -p $PUB_BR -l $GUEST_NAME -r $OSDOMU_MEM_MB -k "flat_network_bridge=${VM_BR}"
247
+
248
+    # wait for install to finish
249
+    wait_for_VM_to_halt
250
+
251
+    # set VM to restart after a reboot
203 252
     vm_uuid=$(xe_min vm-list name-label="$GUEST_NAME")
204 253
     xe vm-param-set actions-after-reboot=Restart uuid="$vm_uuid"
205 254
 
255
+    #
256
+    # Prepare VM for DevStack
257
+    #
258
+
259
+    # Install XenServer tools, and other such things
260
+    $TOP_DIR/prepare_guest_template.sh "$GUEST_NAME"
261
+
262
+    # start the VM to run the prepare steps
263
+    xe vm-start vm="$GUEST_NAME"
264
+
265
+    # Wait for prep script to finish and shutdown system
266
+    wait_for_VM_to_halt
267
+
206 268
     # Make template from VM
207
-    snuuid=$(xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME")
208
-    template_uuid=$(xe snapshot-clone uuid=$snuuid new-name-label="$TNAME")
269
+    snuuid=$(xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_PREPARED")
270
+    xe snapshot-clone uuid=$snuuid new-name-label="$TNAME"
271
+else
272
+    #
273
+    # Template already installed, create VM from template
274
+    #
275
+    vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$GUEST_NAME")
209 276
 fi
210 277
 
278
+
279
+#
280
+# Inject DevStack inside VM disk
281
+#
211 282
 $TOP_DIR/build_xva.sh "$GUEST_NAME"
212 283
 
284
+# create a snapshot before the first boot
285
+# to allow a quick re-run with the same settings
286
+xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_FIRST_BOOT"
287
+
288
+
289
+#
290
+# Run DevStack VM
291
+#
213 292
 xe vm-start vm="$GUEST_NAME"
214 293
 
215
-if [ $PUB_IP == "dhcp" ]; then
216
-    PUB_IP=$(xe_min vm-list  name-label=$GUEST_NAME params=networks |  sed -ne 's,^.*3/ip: \([0-9.]*\).*$,\1,p')
294
+
295
+#
296
+# Find IP and optionally wait for stack.sh to complete
297
+#
298
+
299
+function find_ip_by_name() {
300
+  local guest_name="$1"
301
+  local interface="$2"
302
+  local period=10
303
+  max_tries=10
304
+  i=0
305
+  while true
306
+  do
307
+    if [ $i -ge $max_tries ]; then
308
+      echo "Timed out waiting for devstack ip address"
309
+      exit 11
310
+    fi
311
+
312
+    devstackip=$(xe vm-list --minimal \
313
+                 name-label=$guest_name \
314
+                 params=networks | sed -ne "s,^.*${interface}/ip: \([0-9.]*\).*\$,\1,p")
315
+    if [ -z "$devstackip" ]
316
+    then
317
+      sleep $period
318
+      ((i++))
319
+    else
320
+      echo $devstackip
321
+      break
322
+    fi
323
+  done
324
+}
325
+
326
+function ssh_no_check() {
327
+    ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$@"
328
+}
329
+
330
+# Note the XenServer needs to be on the chosen
331
+# network, so XenServer can access Glance API
332
+if [ $HOST_IP_IFACE == "eth2" ]; then
333
+    DOMU_IP=$MGT_IP
334
+    if [ $MGT_IP == "dhcp" ]; then
335
+        DOMU_IP=$(find_ip_by_name $GUEST_NAME 2)
336
+    fi
337
+else
338
+    DOMU_IP=$PUB_IP
339
+    if [ $PUB_IP == "dhcp" ]; then
340
+        DOMU_IP=$(find_ip_by_name $GUEST_NAME 3)
341
+    fi
217 342
 fi
218 343
 
219 344
 # If we have copied our ssh credentials, use ssh to monitor while the installation runs
220 345
 WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
346
+COPYENV=${COPYENV:-1}
221 347
 if [ "$WAIT_TILL_LAUNCH" = "1" ]  && [ -e ~/.ssh/id_rsa.pub  ] && [ "$COPYENV" = "1" ]; then
222
-    # Done creating the container, let's tail the log
223
-    echo
224
-    echo "============================================================="
225
-    echo "                          -- YAY! --"
226
-    echo "============================================================="
227
-    echo
228 348
     echo "We're done launching the vm, about to start tailing the"
229 349
     echo "stack.sh log. It will take a second or two to start."
230 350
     echo
231 351
     echo "Just CTRL-C at any time to stop tailing."
232 352
 
233
-    set +o xtrace
234
-
235
-    while ! ssh -q stack@$PUB_IP "[ -e run.sh.log ]"; do
236
-      sleep 1
353
+    # wait for log to appear
354
+    while ! ssh_no_check -q stack@$DOMU_IP "[ -e run.sh.log ]"; do
355
+        sleep 10
237 356
     done
238 357
 
239
-    ssh stack@$PUB_IP 'tail -f run.sh.log' &
240
-
358
+    # output the run.sh.log
359
+    ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no stack@$DOMU_IP 'tail -f run.sh.log' &
241 360
     TAIL_PID=$!
242 361
 
243 362
     function kill_tail() {
244
-        kill $TAIL_PID
363
+        kill -9 $TAIL_PID
245 364
         exit 1
246 365
     }
247
-
248 366
     # Let Ctrl-c kill tail and exit
249 367
     trap kill_tail SIGINT
250 368
 
251
-    echo "Waiting stack.sh to finish..."
252
-    while ! ssh -q stack@$PUB_IP "grep -q 'stack.sh completed in' run.sh.log"; do
253
-        sleep 1
369
+    # ensure we kill off the tail if we exit the script early
370
+    # for other reasons
371
+    add_on_exit "kill -9 $TAIL_PID || true"
372
+
373
+    # wait silently until stack.sh has finished
374
+    set +o xtrace
375
+    while ! ssh_no_check -q stack@$DOMU_IP "tail run.sh.log | grep -q 'stack.sh completed in'"; do
376
+        sleep 10
254 377
     done
378
+    set -o xtrace
255 379
 
256
-    kill $TAIL_PID
380
+    # kill the tail process now stack.sh has finished
381
+    kill -9 $TAIL_PID
257 382
 
258
-    if ssh -q stack@$PUB_IP "grep -q 'stack.sh failed' run.sh.log"; then
383
+    # check for a failure
384
+    if ssh_no_check -q stack@$DOMU_IP "grep -q 'stack.sh failed' run.sh.log"; then
259 385
         exit 1
260 386
     fi
387
+    echo "################################################################################"
261 388
     echo ""
262
-    echo "Finished - Zip-a-dee Doo-dah!"
263
-    echo "You can then visit the OpenStack Dashboard"
264
-    echo "at http://$PUB_IP, and contact other services at the usual ports."
389
+    echo "All Finished!"
390
+    echo "You can visit the OpenStack Dashboard"
391
+    echo "at http://$DOMU_IP, and contact other services at the usual ports."
265 392
 else
266 393
     echo "################################################################################"
267 394
     echo ""
... ...
@@ -269,10 +430,9 @@ else
269 269
     echo "Now, you can monitor the progress of the stack.sh installation by "
270 270
     echo "tailing /opt/stack/run.sh.log from within your domU."
271 271
     echo ""
272
-    echo "ssh into your domU now: 'ssh stack@$PUB_IP' using your password"
272
+    echo "ssh into your domU now: 'ssh stack@$DOMU_IP' using your password"
273 273
     echo "and then do: 'tail -f /opt/stack/run.sh.log'"
274 274
     echo ""
275 275
     echo "When the script completes, you can then visit the OpenStack Dashboard"
276
-    echo "at http://$PUB_IP, and contact other services at the usual ports."
277
-
276
+    echo "at http://$DOMU_IP, and contact other services at the usual ports."
278 277
 fi
... ...
@@ -1,6 +1,18 @@
1 1
 #!/bin/bash
2 2
 
3
+# This script is run on an Ubuntu VM.
4
+# This script is inserted into the VM by prepare_guest_template.sh
5
+# and is run when that VM boots.
6
+# It customizes a fresh Ubuntu install, so it is ready
7
+# to run stack.sh
8
+#
9
+# This includes installing the XenServer tools,
10
+# creating the user called "stack",
11
+# and shuts down the VM to signal the script has completed
12
+
3 13
 set -x
14
+# Echo commands
15
+set -o xtrace
4 16
 
5 17
 # Configurable nuggets
6 18
 GUEST_PASSWORD=${GUEST_PASSWORD:-secrete}
... ...
@@ -13,7 +25,7 @@ chroot $STAGING_DIR apt-get install -y cracklib-runtime curl wget ssh openssh-se
13 13
 chroot $STAGING_DIR apt-get install -y curl wget ssh openssh-server python-pip git vim-nox sudo
14 14
 chroot $STAGING_DIR pip install xenapi
15 15
 
16
-# Install guest utilities
16
+# Install XenServer guest utilities
17 17
 XEGUEST=xe-guest-utilities_5.6.100-651_amd64.deb
18 18
 wget http://images.ansolabs.com/xen/$XEGUEST -O $XEGUEST
19 19
 cp $XEGUEST $STAGING_DIR/root
... ...
@@ -68,3 +80,12 @@ if [ "$DO_TGZ" = "1" ]; then
68 68
     rm -f stage.tgz
69 69
     tar cfz stage.tgz stage
70 70
 fi
71
+
72
+# remove self from local.rc
73
+# so this script is not run again
74
+rm -rf /etc/rc.local
75
+mv /etc/rc.local.preparebackup /etc/rc.local
76
+cp $STAGING_DIR/etc/rc.local $STAGING_DIR/etc/rc.local.backup
77
+
78
+# shutdown to notify we are done
79
+shutdown -h now
71 80
new file mode 100755
... ...
@@ -0,0 +1,57 @@
0
+#!/bin/bash
1
+
2
+# This script is run by install_os_domU.sh
3
+#
4
+# Parameters:
5
+# - $GUEST_NAME - hostname for the DomU VM
6
+#
7
+# It modifies the ubuntu image created by install_os_domU.sh
8
+#
9
+# This script is responsible for cusomtizing the fresh ubuntu
10
+# image so on boot it runs the prepare_guest.sh script
11
+# that modifies the VM so it is ready to run stack.sh.
12
+# It does this by mounting the disk image of the VM.
13
+#
14
+# The resultant image is started by install_os_domU.sh,
15
+# and once the VM has shutdown, build_xva.sh is run
16
+
17
+# Exit on errors
18
+set -o errexit
19
+# Echo commands
20
+set -o xtrace
21
+
22
+# This directory
23
+TOP_DIR=$(cd $(dirname "$0") && pwd)
24
+
25
+# Include onexit commands
26
+. $TOP_DIR/scripts/on_exit.sh
27
+
28
+# Source params - override xenrc params in your localrc to suite your taste
29
+source xenrc
30
+
31
+#
32
+# Parameters
33
+#
34
+GUEST_NAME="$1"
35
+
36
+# Mount the VDI
37
+STAGING_DIR=$($TOP_DIR/scripts/manage-vdi open $GUEST_NAME 0 1 | grep -o "/tmp/tmp.[[:alnum:]]*")
38
+add_on_exit "$TOP_DIR/scripts/manage-vdi close $GUEST_NAME 0 1"
39
+
40
+# Make sure we have a stage
41
+if [ ! -d $STAGING_DIR/etc ]; then
42
+    echo "Stage is not properly set up!"
43
+    exit 1
44
+fi
45
+
46
+# Copy prepare_guest.sh to VM
47
+mkdir -p $STAGING_DIR/opt/stack/
48
+cp $TOP_DIR/prepare_guest.sh $STAGING_DIR/opt/stack/prepare_guest.sh
49
+
50
+# backup rc.local
51
+cp $STAGING_DIR/etc/rc.local $STAGING_DIR/etc/rc.local.preparebackup
52
+
53
+# run prepare_guest.sh on boot
54
+cat <<EOF >$STAGING_DIR/etc/rc.local
55
+GUEST_PASSWORD=$GUEST_PASSWORD STAGING_DIR=/ DO_TGZ=0 bash /opt/stack/prepare_guest.sh > /opt/stack/prepare_guest.log 2>&1
56
+EOF
... ...
@@ -19,7 +19,12 @@
19 19
 
20 20
 set -eux
21 21
 
22
-. /etc/xensource-inventory
22
+if [ -a /etc/xensource-inventory]
23
+then
24
+    . /etc/xensource-inventory
25
+else
26
+    . /etc/xcp/inventory
27
+fi
23 28
 
24 29
 NAME="XenServer OpenStack VPX"
25 30
 DATA_VDI_SIZE="500MiB"
... ...
@@ -20,6 +20,26 @@ vdi_uuid=$(xe_min vbd-list params=vdi-uuid vm-uuid="$vm_uuid" \
20 20
 
21 21
 dom0_uuid=$(xe_min vm-list is-control-domain=true)
22 22
 
23
+get_mount_device()
24
+{
25
+  vbd_uuid=$1
26
+
27
+  dev=$(xe_min vbd-list params=device uuid="$vbd_uuid")
28
+  if [[ "$dev" =~ "sm/" ]]; then
29
+    DEBIAN_FRONTEND=noninteractive \
30
+        apt-get --option "Dpkg::Options::=--force-confold" --assume-yes \
31
+        install kpartx || true &> /dev/null
32
+    mapping=$(kpartx -av "/dev/$dev" | sed -ne 's,^add map \([a-f0-9\-]*\).*$,\1,p' | sed -ne "s,^\(.*${part}\)\$,\1,p")
33
+    if [ -z "$mapping" ]; then
34
+       echo "Failed to find mapping"
35
+       exit -1
36
+    fi
37
+    echo "mapper/${mapping}"
38
+  else
39
+    echo "/dev/$dev$part"
40
+  fi
41
+}
42
+
23 43
 open_vdi()
24 44
 {
25 45
   vbd_uuid=$(xe vbd-create vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid" \
... ...
@@ -27,26 +47,30 @@ open_vdi()
27 27
   mp=$(mktemp -d)
28 28
   xe vbd-plug uuid="$vbd_uuid"
29 29
 
30
-  udevsettle
31
-  dev=$(xe_min vbd-list params=device uuid="$vbd_uuid")
32
-  mount "/dev/$dev$part" "$mp"
30
+  which_udev=$(which udevsettle) || true
31
+  if [ -n "$which_udev" ]; then
32
+      udevsettle
33
+  else
34
+      udevadm settle
35
+  fi
36
+
37
+  mount_device=$(get_mount_device "$vbd_uuid")
38
+  mount "$mount_device" "$mp"
33 39
   echo "Your vdi is mounted at $mp"
34 40
 }
35 41
 
36 42
 close_vdi()
37 43
 {
38 44
   vbd_uuid=$(xe_min vbd-list vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid")
39
-  dev=$(xe_min vbd-list params=device uuid="$vbd_uuid")
40
-  umount "/dev/$dev$part"
45
+  mount_device=$(get_mount_device "$vbd_uuid")
46
+  umount "$mount_device"
41 47
 
42 48
   xe vbd-unplug uuid=$vbd_uuid
43 49
   xe vbd-destroy uuid=$vbd_uuid
44 50
 }
45 51
 
46
-if [ "$action" == "open" ]
47
-then
52
+if [ "$action" == "open" ]; then
48 53
   open_vdi
49
-elif [ "$action" == "close" ]
50
-then
54
+elif [ "$action" == "close" ]; then
51 55
   close_vdi
52 56
 fi
53 57
new file mode 100755
... ...
@@ -0,0 +1,24 @@
0
+#!/bin/bash
1
+
2
+set -e
3
+set -o xtrace
4
+
5
+declare -a on_exit_hooks
6
+
7
+on_exit()
8
+{
9
+    for i in $(seq $((${#on_exit_hooks[*]} - 1)) -1 0)
10
+    do
11
+        eval "${on_exit_hooks[$i]}"
12
+    done
13
+}
14
+
15
+add_on_exit()
16
+{
17
+    local n=${#on_exit_hooks[*]}
18
+    on_exit_hooks[$n]="$*"
19
+    if [[ $n -eq 0 ]]
20
+    then
21
+        trap on_exit EXIT
22
+    fi
23
+}
... ...
@@ -17,19 +17,19 @@
17 17
 #    under the License.
18 18
 #
19 19
 
20
-remove_data=
21
-if [ "$1" = "--remove-data" ]
22
-then
23
-  remove_data=1
24
-fi
20
+set -ex
25 21
 
26
-set -eu
22
+# By default, don't remove the templates
23
+REMOVE_TEMPLATES=${REMOVE_TEMPLATES:-"false"}
24
+if [ "$1" = "--remove-templates" ]; then
25
+  REMOVE_TEMPLATES=true
26
+fi
27 27
 
28 28
 xe_min()
29 29
 {
30 30
   local cmd="$1"
31 31
   shift
32
-  /opt/xensource/bin/xe "$cmd" --minimal "$@"
32
+  xe "$cmd" --minimal "$@"
33 33
 }
34 34
 
35 35
 destroy_vdi()
... ...
@@ -39,11 +39,8 @@ destroy_vdi()
39 39
   local dev=$(xe_min vbd-list uuid=$vbd_uuid params=userdevice)
40 40
   local vdi_uuid=$(xe_min vbd-list uuid=$vbd_uuid params=vdi-uuid)
41 41
 
42
-  if [ "$type" = 'Disk' ] && [ "$dev" != 'xvda' ] && [ "$dev" != '0' ]
43
-  then
44
-    echo -n "Destroying data disk... "
42
+  if [ "$type" == 'Disk' ] && [ "$dev" != 'xvda' ] && [ "$dev" != '0' ]; then
45 43
     xe vdi-destroy uuid=$vdi_uuid
46
-    echo "done."
47 44
   fi
48 45
 }
49 46
 
... ...
@@ -52,50 +49,36 @@ uninstall()
52 52
   local vm_uuid="$1"
53 53
   local power_state=$(xe_min vm-list uuid=$vm_uuid params=power-state)
54 54
 
55
-  if [ "$power_state" != "halted" ]
56
-  then
57
-    echo -n "Shutting down VM... "
55
+  if [ "$power_state" != "halted" ]; then
58 56
     xe vm-shutdown vm=$vm_uuid force=true
59
-    echo "done."
60 57
   fi
61 58
 
62
-  if [ "$remove_data" = "1" ]
63
-  then
64
-    for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g')
65
-    do
66
-      destroy_vdi "$v"
67
-    done
68
-  fi
59
+  for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g'); do
60
+    destroy_vdi "$v"
61
+  done
69 62
 
70
-  echo -n "Deleting VM... "
71 63
   xe vm-uninstall vm=$vm_uuid force=true >/dev/null
72
-  echo "done."
73 64
 }
74 65
 
75 66
 uninstall_template()
76 67
 {
77 68
   local vm_uuid="$1"
78 69
 
79
-  if [ "$remove_data" = "1" ]
80
-  then
81
-    for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g')
82
-    do
83
-      destroy_vdi "$v"
84
-    done
85
-  fi
70
+  for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g'); do
71
+    destroy_vdi "$v"
72
+  done
86 73
 
87
-  echo -n "Deleting template... "
88 74
   xe template-uninstall template-uuid=$vm_uuid force=true >/dev/null
89
-  echo "done."
90 75
 }
91 76
 
92
-
93
-for u in $(xe_min vm-list other-config:os-vpx=true | sed -e 's/,/ /g')
94
-do
77
+# remove the VMs and their disks
78
+for u in $(xe_min vm-list other-config:os-vpx=true | sed -e 's/,/ /g'); do
95 79
   uninstall "$u"
96 80
 done
97 81
 
98
-for u in $(xe_min template-list other-config:os-vpx=true | sed -e 's/,/ /g')
99
-do
100
-  uninstall_template "$u"
101
-done
82
+# remove the templates
83
+if [ "$REMOVE_TEMPLATES" == "true" ]; then
84
+  for u in $(xe_min template-list other-config:os-vpx=true | sed -e 's/,/ /g'); do
85
+    uninstall_template "$u"
86
+  done
87
+fi
... ...
@@ -3,7 +3,7 @@
3 3
 ## on Xenserver 6.0.2 Net install only
4 4
 ## Original Author: David Markey <david.markey@citrix.com>
5 5
 ## Author: Renuka Apte <renuka.apte@citrix.com>
6
-## This is not an officially supported guest OS on XenServer 6.02
6
+## This is not an officially supported guest OS on XenServer 6.0.2
7 7
 
8 8
 BASE_DIR=$(cd $(dirname "$0") && pwd)
9 9
 source $BASE_DIR/../../../localrc
... ...
@@ -15,11 +15,15 @@ if [[ -z $LENNY ]] ; then
15 15
     exit 1
16 16
 fi
17 17
 
18
-distro="Ubuntu 11.10"
18
+distro="Ubuntu 11.10 for DevStack"
19 19
 arches=("32-bit" "64-bit")
20 20
 
21 21
 preseedurl=${1:-"http://images.ansolabs.com/devstackubuntupreseed.cfg"}
22 22
 
23
+NETINSTALL_LOCALE=${NETINSTALL_LOCALE:-en_US}
24
+NETINSTALL_KEYBOARD=${NETINSTALL_KEYBOARD:-us}
25
+NETINSTALL_IFACE=${NETINSTALL_IFACE:-eth3}
26
+
23 27
 for arch in ${arches[@]} ; do
24 28
     echo "Attempting $distro ($arch)"
25 29
     if [[ -n $(xe template-list name-label="$distro ($arch)" params=uuid --minimal) ]] ; then
... ...
@@ -30,7 +34,11 @@ for arch in ${arches[@]} ; do
30 30
             echo "NETINSTALLIP not set in localrc"
31 31
             exit 1
32 32
         fi
33
-        pvargs="-- quiet console=hvc0 partman/default_filesystem=ext3 locale=en_US console-setup/ask_detect=false keyboard-configuration/layoutcode=us netcfg/choose_interface=eth3 netcfg/get_hostname=os netcfg/get_domain=os auto url=${preseedurl}"
33
+        # Some of these settings can be found in example preseed files
34
+        # however these need to be answered before the netinstall
35
+        # is ready to fetch the preseed file, and as such must be here
36
+        # to get a fully automated install
37
+        pvargs="-- quiet console=hvc0 partman/default_filesystem=ext3 locale=${NETINSTALL_LOCALE} console-setup/ask_detect=false keyboard-configuration/layoutcode=${NETINSTALL_KEYBOARD} netcfg/choose_interface=${NETINSTALL_IFACE} netcfg/get_hostname=os netcfg/get_domain=os auto url=${preseedurl}"
34 38
         if [ "$NETINSTALLIP" != "dhcp" ]
35 39
         then
36 40
             netcfgargs="netcfg/disable_autoconfig=true netcfg/get_nameservers=${NAMESERVERS} netcfg/get_ipaddress=${NETINSTALLIP} netcfg/get_netmask=${NETMASK} netcfg/get_gateway=${GATEWAY} netcfg/confirm_static=true"
... ...
@@ -5,12 +5,15 @@ GUEST_NAME=${GUEST_NAME:-DevStackOSDomU}
5 5
 
6 6
 # Size of image
7 7
 VDI_MB=${VDI_MB:-5000}
8
+OSDOMU_MEM_MB=1024
8 9
 
9 10
 # VM Password
10 11
 GUEST_PASSWORD=${GUEST_PASSWORD:-secrete}
11 12
 
12
-# Host Interface, i.e. the public facing interface on the nova vm
13
-HOST_IP_IFACE=${HOST_IP_IFACE:-eth0}
13
+# Host Interface, i.e. the interface on the nova vm you want to expose the services on
14
+# Usually either eth2 (management network) or eth3 (public network)
15
+# not eth0 (private network with XenServer host) or eth1 (VM traffic network)
16
+HOST_IP_IFACE=${HOST_IP_IFACE:-eth3}
14 17
 
15 18
 # Our nova host's network info
16 19
 VM_IP=${VM_IP:-10.255.255.255} # A host-only ip that let's the interface come up, otherwise unused
... ...
@@ -35,7 +38,5 @@ MGT_BR=${MGT_BR:-""}
35 35
 MGT_VLAN=${MGT_VLAN:-101}
36 36
 MGT_DEV=${MGT_DEV:-eth0}
37 37
 
38
-OSDOMU_MEM_MB=1024
39
-
40 38
 # Source params
41 39
 cd ../.. && source ./stackrc && cd $TOP_DIR