blob: f0e057b66515777fd1b63a3d1256d73269b8a5b7 [file] [log] [blame]
Anthony Youngb62b4ca2011-10-26 22:29:08 -07001#!/bin/bash
2
John Garbuttdaadf742012-04-27 18:28:28 +01003# 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
Renuka Apte0af143b2012-04-02 15:46:53 -070010# Exit on errors
11set -o errexit
John Garbuttdaadf742012-04-27 18:28:28 +010012# Echo commands
13set -o xtrace
Renuka Apte0af143b2012-04-02 15:46:53 -070014
Anthony Youngb62b4ca2011-10-26 22:29:08 -070015# Abort if localrc is not set
16if [ ! -e ../../localrc ]; then
17 echo "You must have a localrc with ALL necessary passwords defined before proceeding."
18 echo "See the xen README for required passwords."
19 exit 1
20fi
21
Anthony Youngaf6ed6b2011-11-02 07:50:27 -050022# This directory
23TOP_DIR=$(cd $(dirname "$0") && pwd)
24
Anthony Youngb3e2f332012-03-16 17:01:49 -070025# Source lower level functions
26. $TOP_DIR/../../functions
27
John Garbuttdaadf742012-04-27 18:28:28 +010028# Include onexit commands
29. $TOP_DIR/scripts/on_exit.sh
30
31
32#
33# Get Settings
34#
35
Anthony Youngb3e2f332012-03-16 17:01:49 -070036# Source params - override xenrc params in your localrc to suit your taste
Anthony Young11889042012-01-12 17:11:56 -080037source xenrc
Anthony Youngaf6ed6b2011-11-02 07:50:27 -050038
Renuka Apte0af143b2012-04-02 15:46:53 -070039xe_min()
40{
41 local cmd="$1"
42 shift
43 xe "$cmd" --minimal "$@"
44}
Anthony Youngb62b4ca2011-10-26 22:29:08 -070045
John Garbuttdaadf742012-04-27 18:28:28 +010046
47#
48# Prepare Dom0
49# including installing XenAPI plugins
50#
51
Renuka Apte0af143b2012-04-02 15:46:53 -070052cd $TOP_DIR
53if [ -f ./master ]
54then
55 rm -rf ./master
56 rm -rf ./nova
Anthony Youngb62b4ca2011-10-26 22:29:08 -070057fi
John Garbuttdaadf742012-04-27 18:28:28 +010058
59# get nova
Maru Newby3a87edd2012-10-25 23:01:06 +000060NOVA_ZIPBALL_URL=${NOVA_ZIPBALL_URL:-$(echo $NOVA_REPO | sed "s:\.git$::;s:$:/zipball/$NOVA_BRANCH:g")}
Bob Ball7fcc1572013-02-20 15:56:25 +000061wget -nv $NOVA_ZIPBALL_URL -O nova-zipball --no-check-certificate
62unzip -q -o nova-zipball -d ./nova
John Garbuttdaadf742012-04-27 18:28:28 +010063
64# install xapi plugins
65XAPI_PLUGIN_DIR=/etc/xapi.d/plugins/
66if [ ! -d $XAPI_PLUGIN_DIR ]; then
67 # the following is needed when using xcp-xapi
68 XAPI_PLUGIN_DIR=/usr/lib/xcp/plugins/
69fi
70cp -pr ./nova/*/plugins/xenserver/xenapi/etc/xapi.d/plugins/* $XAPI_PLUGIN_DIR
Maru Newby2298ca42012-10-25 23:46:42 +000071
72# Install the netwrap xapi plugin to support agent control of dom0 networking
73if [[ "$ENABLED_SERVICES" =~ "q-agt" && "$Q_PLUGIN" = "openvswitch" ]]; then
74 if [ -f ./quantum ]; then
75 rm -rf ./quantum
76 fi
77 # get quantum
78 QUANTUM_ZIPBALL_URL=${QUANTUM_ZIPBALL_URL:-$(echo $QUANTUM_REPO | sed "s:\.git$::;s:$:/zipball/$QUANTUM_BRANCH:g")}
Bob Ball7fcc1572013-02-20 15:56:25 +000079 wget -nv $QUANTUM_ZIPBALL_URL -O quantum-zipball --no-check-certificate
80 unzip -q -o quantum-zipball -d ./quantum
Maru Newby2298ca42012-10-25 23:46:42 +000081 cp -pr ./quantum/*/quantum/plugins/openvswitch/agent/xenapi/etc/xapi.d/plugins/* $XAPI_PLUGIN_DIR
82fi
83
John Garbuttdaadf742012-04-27 18:28:28 +010084chmod a+x ${XAPI_PLUGIN_DIR}*
Renuka Apte0af143b2012-04-02 15:46:53 -070085
86mkdir -p /boot/guest
87
John Garbuttdaadf742012-04-27 18:28:28 +010088
89#
90# Configure Networking
91#
Anthony Youngb62b4ca2011-10-26 22:29:08 -070092
93# Helper to create networks
rootb1153412012-01-19 13:28:21 -080094# Uses echo trickery to return network uuid
Anthony Youngb62b4ca2011-10-26 22:29:08 -070095function create_network() {
rootb1153412012-01-19 13:28:21 -080096 br=$1
97 dev=$2
98 vlan=$3
99 netname=$4
100 if [ -z $br ]
101 then
Renuka Apte0af143b2012-04-02 15:46:53 -0700102 pif=$(xe_min pif-list device=$dev VLAN=$vlan)
rootb1153412012-01-19 13:28:21 -0800103 if [ -z $pif ]
104 then
105 net=$(xe network-create name-label=$netname)
106 else
Renuka Apte0af143b2012-04-02 15:46:53 -0700107 net=$(xe_min network-list PIF-uuids=$pif)
rootb1153412012-01-19 13:28:21 -0800108 fi
109 echo $net
110 return 0
111 fi
Renuka Apte0af143b2012-04-02 15:46:53 -0700112 if [ ! $(xe_min network-list params=bridge | grep -w --only-matching $br) ]
rootb1153412012-01-19 13:28:21 -0800113 then
114 echo "Specified bridge $br does not exist"
115 echo "If you wish to use defaults, please keep the bridge name empty"
116 exit 1
117 else
Renuka Apte0af143b2012-04-02 15:46:53 -0700118 net=$(xe_min network-list bridge=$br)
rootb1153412012-01-19 13:28:21 -0800119 echo $net
120 fi
121}
122
123function errorcheck() {
124 rc=$?
125 if [ $rc -ne 0 ]
126 then
127 exit $rc
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700128 fi
129}
130
John Garbuttdaadf742012-04-27 18:28:28 +0100131# Create host, vm, mgmt, pub networks on XenServer
rootb1153412012-01-19 13:28:21 -0800132VM_NET=$(create_network "$VM_BR" "$VM_DEV" "$VM_VLAN" "vmbr")
133errorcheck
134MGT_NET=$(create_network "$MGT_BR" "$MGT_DEV" "$MGT_VLAN" "mgtbr")
135errorcheck
136PUB_NET=$(create_network "$PUB_BR" "$PUB_DEV" "$PUB_VLAN" "pubbr")
137errorcheck
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700138
139# Helper to create vlans
140function create_vlan() {
rootb1153412012-01-19 13:28:21 -0800141 dev=$1
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700142 vlan=$2
143 net=$3
rootb1153412012-01-19 13:28:21 -0800144 # VLAN -1 refers to no VLAN (physical network)
145 if [ $vlan -eq -1 ]
146 then
147 return
148 fi
Renuka Apte0af143b2012-04-02 15:46:53 -0700149 if [ -z $(xe_min vlan-list tag=$vlan) ]
rootb1153412012-01-19 13:28:21 -0800150 then
Renuka Apte0af143b2012-04-02 15:46:53 -0700151 pif=$(xe_min pif-list network-uuid=$net)
rootb1153412012-01-19 13:28:21 -0800152 # We created a brand new network this time
153 if [ -z $pif ]
154 then
Renuka Apte0af143b2012-04-02 15:46:53 -0700155 pif=$(xe_min pif-list device=$dev VLAN=-1)
rootb1153412012-01-19 13:28:21 -0800156 xe vlan-create pif-uuid=$pif vlan=$vlan network-uuid=$net
157 else
158 echo "VLAN does not exist but PIF attached to this network"
159 echo "How did we reach here?"
160 exit 1
161 fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700162 fi
163}
164
165# Create vlans for vm and management
rootb1153412012-01-19 13:28:21 -0800166create_vlan $PUB_DEV $PUB_VLAN $PUB_NET
167create_vlan $VM_DEV $VM_VLAN $VM_NET
168create_vlan $MGT_DEV $MGT_VLAN $MGT_NET
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700169
John Garbuttdaadf742012-04-27 18:28:28 +0100170# Get final bridge names
171if [ -z $VM_BR ]; then
172 VM_BR=$(xe_min network-list uuid=$VM_NET params=bridge)
173fi
174if [ -z $MGT_BR ]; then
175 MGT_BR=$(xe_min network-list uuid=$MGT_NET params=bridge)
176fi
177if [ -z $PUB_BR ]; then
178 PUB_BR=$(xe_min network-list uuid=$PUB_NET params=bridge)
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700179fi
180
John Garbuttdaadf742012-04-27 18:28:28 +0100181# dom0 ip, XenAPI is assumed to be listening
182HOST_IP=${HOST_IP:-`ifconfig xenbr0 | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"`}
183
184# Set up ip forwarding, but skip on xcp-xapi
John Garbuttd8f1a872012-06-26 11:16:38 +0100185if [ -a /etc/sysconfig/network ]; then
John Garbuttdaadf742012-04-27 18:28:28 +0100186 if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then
187 # FIXME: This doesn't work on reboot!
188 echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network
189 fi
190fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700191# Also, enable ip forwarding in rc.local, since the above trick isn't working
192if ! grep -q "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then
193 echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local
194fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700195# Enable ip forwarding at runtime as well
196echo 1 > /proc/sys/net/ipv4/ip_forward
197
John Garbuttdaadf742012-04-27 18:28:28 +0100198
199#
Anthony Young346e4912011-11-05 00:22:47 -0500200# Shutdown previous runs
John Garbuttdaadf742012-04-27 18:28:28 +0100201#
202
Anthony Young346e4912011-11-05 00:22:47 -0500203DO_SHUTDOWN=${DO_SHUTDOWN:-1}
John Garbuttdaadf742012-04-27 18:28:28 +0100204CLEAN_TEMPLATES=${CLEAN_TEMPLATES:-false}
Anthony Young346e4912011-11-05 00:22:47 -0500205if [ "$DO_SHUTDOWN" = "1" ]; then
Anthony Young40b57372011-11-05 00:30:07 -0500206 # Shutdown all domU's that created previously
John Garbuttdaadf742012-04-27 18:28:28 +0100207 clean_templates_arg=""
208 if $CLEAN_TEMPLATES; then
209 clean_templates_arg="--remove-templates"
210 fi
211 ./scripts/uninstall-os-vpx.sh $clean_templates_arg
Anthony Young346e4912011-11-05 00:22:47 -0500212
213 # Destroy any instances that were launched
214 for uuid in `xe vm-list | grep -1 instance | grep uuid | sed "s/.*\: //g"`; do
215 echo "Shutting down nova instance $uuid"
216 xe vm-unpause uuid=$uuid || true
Armando Migliaccio7a5f7f22012-04-20 22:58:00 +0100217 xe vm-shutdown uuid=$uuid || true
Anthony Young346e4912011-11-05 00:22:47 -0500218 xe vm-destroy uuid=$uuid
219 done
Anthony Youngfa4ecc62011-11-11 10:23:22 -0800220
221 # Destroy orphaned vdis
222 for uuid in `xe vdi-list | grep -1 Glance | grep uuid | sed "s/.*\: //g"`; do
223 xe vdi-destroy uuid=$uuid
224 done
Anthony Young346e4912011-11-05 00:22:47 -0500225fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700226
Renuka Apte0af143b2012-04-02 15:46:53 -0700227
John Garbuttdaadf742012-04-27 18:28:28 +0100228#
229# Create Ubuntu VM template
230# and/or create VM from template
231#
Renuka Apte0af143b2012-04-02 15:46:53 -0700232
John Garbuttdaadf742012-04-27 18:28:28 +0100233GUEST_NAME=${GUEST_NAME:-"DevStackOSDomU"}
John Garbuttd8f1a872012-06-26 11:16:38 +0100234TNAME="devstack_template"
John Garbuttdaadf742012-04-27 18:28:28 +0100235SNAME_PREPARED="template_prepared"
236SNAME_FIRST_BOOT="before_first_boot"
237
238function wait_for_VM_to_halt() {
Bob Ball63c6c2b2013-01-24 13:13:51 +0000239 set +x
240 echo "Waiting for the VM to halt. Progress in-VM can be checked with vncviewer:"
241 mgmt_ip=$(echo $XENAPI_CONNECTION_URL | tr -d -c '1234567890.')
242 domid=$(xe vm-list name-label="$GUEST_NAME" params=dom-id minimal=true)
243 port=$(xenstore-read /local/domain/$domid/console/vnc-port)
244 echo "vncviewer -via $mgmt_ip localhost:${port:2}"
Renuka Apte0af143b2012-04-02 15:46:53 -0700245 while true
246 do
247 state=$(xe_min vm-list name-label="$GUEST_NAME" power-state=halted)
248 if [ -n "$state" ]
249 then
250 break
251 else
Bob Ball63c6c2b2013-01-24 13:13:51 +0000252 echo -n "."
John Garbuttdaadf742012-04-27 18:28:28 +0100253 sleep 20
Renuka Apte0af143b2012-04-02 15:46:53 -0700254 fi
255 done
Bob Ball63c6c2b2013-01-24 13:13:51 +0000256 set -x
John Garbuttdaadf742012-04-27 18:28:28 +0100257}
Renuka Apte0af143b2012-04-02 15:46:53 -0700258
John Garbuttdaadf742012-04-27 18:28:28 +0100259templateuuid=$(xe template-list name-label="$TNAME")
260if [ -z "$templateuuid" ]; then
261 #
262 # Install Ubuntu over network
263 #
264
John Garbuttdaadf742012-04-27 18:28:28 +0100265 # always update the preseed file, incase we have a newer one
266 PRESEED_URL=${PRESEED_URL:-""}
267 if [ -z "$PRESEED_URL" ]; then
268 PRESEED_URL="${HOST_IP}/devstackubuntupreseed.cfg"
269 HTTP_SERVER_LOCATION="/opt/xensource/www"
270 if [ ! -e $HTTP_SERVER_LOCATION ]; then
271 HTTP_SERVER_LOCATION="/var/www/html"
272 mkdir -p $HTTP_SERVER_LOCATION
273 fi
274 cp -f $TOP_DIR/devstackubuntupreseed.cfg $HTTP_SERVER_LOCATION
275 MIRROR=${MIRROR:-""}
276 if [ -n "$MIRROR" ]; then
277 sed -e "s,d-i mirror/http/hostname string .*,d-i mirror/http/hostname string $MIRROR," \
278 -i "${HTTP_SERVER_LOCATION}/devstackubuntupreseed.cfg"
279 fi
280 fi
281
John Garbuttd8f1a872012-06-26 11:16:38 +0100282 # Update the template
283 $TOP_DIR/scripts/install_ubuntu_template.sh $PRESEED_URL
John Garbuttdaadf742012-04-27 18:28:28 +0100284
285 # create a new VM with the given template
286 # creating the correct VIFs and metadata
John Garbuttd8f1a872012-06-26 11:16:38 +0100287 $TOP_DIR/scripts/install-os-vpx.sh -t "$UBUNTU_INST_TEMPLATE_NAME" -v $VM_BR -m $MGT_BR -p $PUB_BR -l $GUEST_NAME -r $OSDOMU_MEM_MB -k "flat_network_bridge=${VM_BR}"
John Garbuttdaadf742012-04-27 18:28:28 +0100288
289 # wait for install to finish
290 wait_for_VM_to_halt
291
292 # set VM to restart after a reboot
Renuka Apte0af143b2012-04-02 15:46:53 -0700293 vm_uuid=$(xe_min vm-list name-label="$GUEST_NAME")
294 xe vm-param-set actions-after-reboot=Restart uuid="$vm_uuid"
295
John Garbuttdaadf742012-04-27 18:28:28 +0100296 #
297 # Prepare VM for DevStack
298 #
299
300 # Install XenServer tools, and other such things
301 $TOP_DIR/prepare_guest_template.sh "$GUEST_NAME"
302
303 # start the VM to run the prepare steps
304 xe vm-start vm="$GUEST_NAME"
305
306 # Wait for prep script to finish and shutdown system
307 wait_for_VM_to_halt
308
Renuka Apte0af143b2012-04-02 15:46:53 -0700309 # Make template from VM
John Garbuttdaadf742012-04-27 18:28:28 +0100310 snuuid=$(xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_PREPARED")
311 xe snapshot-clone uuid=$snuuid new-name-label="$TNAME"
312else
313 #
314 # Template already installed, create VM from template
315 #
316 vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$GUEST_NAME")
Renuka Apte0af143b2012-04-02 15:46:53 -0700317fi
318
John Garbuttdaadf742012-04-27 18:28:28 +0100319
320#
321# Inject DevStack inside VM disk
322#
Renuka Apte0af143b2012-04-02 15:46:53 -0700323$TOP_DIR/build_xva.sh "$GUEST_NAME"
324
John Garbuttdaadf742012-04-27 18:28:28 +0100325# create a snapshot before the first boot
326# to allow a quick re-run with the same settings
327xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_FIRST_BOOT"
328
329
330#
331# Run DevStack VM
332#
Renuka Apte0af143b2012-04-02 15:46:53 -0700333xe vm-start vm="$GUEST_NAME"
Anthony Young3eb8f592011-10-26 23:11:52 -0700334
John Garbuttdaadf742012-04-27 18:28:28 +0100335
336#
337# Find IP and optionally wait for stack.sh to complete
338#
339
340function find_ip_by_name() {
341 local guest_name="$1"
342 local interface="$2"
343 local period=10
344 max_tries=10
345 i=0
346 while true
347 do
348 if [ $i -ge $max_tries ]; then
349 echo "Timed out waiting for devstack ip address"
350 exit 11
351 fi
352
353 devstackip=$(xe vm-list --minimal \
354 name-label=$guest_name \
355 params=networks | sed -ne "s,^.*${interface}/ip: \([0-9.]*\).*\$,\1,p")
356 if [ -z "$devstackip" ]
357 then
358 sleep $period
359 ((i++))
360 else
361 echo $devstackip
362 break
363 fi
364 done
365}
366
367function ssh_no_check() {
368 ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$@"
369}
370
371# Note the XenServer needs to be on the chosen
372# network, so XenServer can access Glance API
373if [ $HOST_IP_IFACE == "eth2" ]; then
374 DOMU_IP=$MGT_IP
375 if [ $MGT_IP == "dhcp" ]; then
376 DOMU_IP=$(find_ip_by_name $GUEST_NAME 2)
377 fi
378else
379 DOMU_IP=$PUB_IP
380 if [ $PUB_IP == "dhcp" ]; then
381 DOMU_IP=$(find_ip_by_name $GUEST_NAME 3)
382 fi
Renuka Aptec56885a2012-02-29 16:09:26 -0800383fi
384
Anthony Young1de18c62011-11-01 14:19:18 -0500385# If we have copied our ssh credentials, use ssh to monitor while the installation runs
386WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
John Garbuttdaadf742012-04-27 18:28:28 +0100387COPYENV=${COPYENV:-1}
Anthony Young1de18c62011-11-01 14:19:18 -0500388if [ "$WAIT_TILL_LAUNCH" = "1" ] && [ -e ~/.ssh/id_rsa.pub ] && [ "$COPYENV" = "1" ]; then
Bob Ball7fcc1572013-02-20 15:56:25 +0000389 set +x
Anthony Young1de18c62011-11-01 14:19:18 -0500390
Bob Ball7fcc1572013-02-20 15:56:25 +0000391 echo "VM Launched - Waiting for startup script"
John Garbuttdaadf742012-04-27 18:28:28 +0100392 # wait for log to appear
393 while ! ssh_no_check -q stack@$DOMU_IP "[ -e run.sh.log ]"; do
394 sleep 10
Anthony Young1de18c62011-11-01 14:19:18 -0500395 done
Bob Ball7fcc1572013-02-20 15:56:25 +0000396 echo -n "Running"
Mate Lakat9efcf602012-12-19 10:23:06 +0000397 while [ `ssh_no_check -q stack@$DOMU_IP pgrep -c run.sh` -ge 1 ]
398 do
John Garbuttdaadf742012-04-27 18:28:28 +0100399 sleep 10
Mate Lakat9efcf602012-12-19 10:23:06 +0000400 echo -n "."
Anthony Young1de18c62011-11-01 14:19:18 -0500401 done
Mate Lakat9efcf602012-12-19 10:23:06 +0000402 echo "done!"
403 set -x
Anthony Young1de18c62011-11-01 14:19:18 -0500404
Mate Lakat9efcf602012-12-19 10:23:06 +0000405 # output the run.sh.log
406 ssh_no_check -q stack@$DOMU_IP 'cat run.sh.log'
Anthony Young1de18c62011-11-01 14:19:18 -0500407
Mate Lakat9efcf602012-12-19 10:23:06 +0000408 # Fail if the expected text is not found
409 ssh_no_check -q stack@$DOMU_IP 'cat run.sh.log' | grep -q 'stack.sh completed in'
410
Bob Ball63c6c2b2013-01-24 13:13:51 +0000411 set +x
John Garbuttdaadf742012-04-27 18:28:28 +0100412 echo "################################################################################"
Anthony Young1de18c62011-11-01 14:19:18 -0500413 echo ""
John Garbuttdaadf742012-04-27 18:28:28 +0100414 echo "All Finished!"
415 echo "You can visit the OpenStack Dashboard"
416 echo "at http://$DOMU_IP, and contact other services at the usual ports."
Anthony Young1de18c62011-11-01 14:19:18 -0500417else
Bob Ball63c6c2b2013-01-24 13:13:51 +0000418 set +x
Anthony Young1de18c62011-11-01 14:19:18 -0500419 echo "################################################################################"
420 echo ""
421 echo "All Finished!"
422 echo "Now, you can monitor the progress of the stack.sh installation by "
423 echo "tailing /opt/stack/run.sh.log from within your domU."
424 echo ""
John Garbuttdaadf742012-04-27 18:28:28 +0100425 echo "ssh into your domU now: 'ssh stack@$DOMU_IP' using your password"
Anthony Young1de18c62011-11-01 14:19:18 -0500426 echo "and then do: 'tail -f /opt/stack/run.sh.log'"
427 echo ""
428 echo "When the script completes, you can then visit the OpenStack Dashboard"
John Garbuttdaadf742012-04-27 18:28:28 +0100429 echo "at http://$DOMU_IP, and contact other services at the usual ports."
Anthony Young1de18c62011-11-01 14:19:18 -0500430fi