blob: 7c3b839209108bbe67aa433b12c4bb9577b6cb89 [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
Mate Lakata8bf0f22013-03-07 18:37:31 +000023THIS_DIR=$(cd $(dirname "$0") && pwd)
Anthony Youngaf6ed6b2011-11-02 07:50:27 -050024
Anthony Youngb3e2f332012-03-16 17:01:49 -070025# Source lower level functions
Mate Lakata8bf0f22013-03-07 18:37:31 +000026. $THIS_DIR/../../functions
Anthony Youngb3e2f332012-03-16 17:01:49 -070027
John Garbuttdaadf742012-04-27 18:28:28 +010028# Include onexit commands
Mate Lakata8bf0f22013-03-07 18:37:31 +000029. $THIS_DIR/scripts/on_exit.sh
John Garbuttdaadf742012-04-27 18:28:28 +010030
Mate Lakat57e3da92013-03-22 16:34:05 +000031# xapi functions
32. $THIS_DIR/functions
33
John Garbuttdaadf742012-04-27 18:28:28 +010034
35#
36# Get Settings
37#
38
Anthony Youngb3e2f332012-03-16 17:01:49 -070039# Source params - override xenrc params in your localrc to suit your taste
Anthony Young11889042012-01-12 17:11:56 -080040source xenrc
Anthony Youngaf6ed6b2011-11-02 07:50:27 -050041
Renuka Apte0af143b2012-04-02 15:46:53 -070042xe_min()
43{
44 local cmd="$1"
45 shift
46 xe "$cmd" --minimal "$@"
47}
Anthony Youngb62b4ca2011-10-26 22:29:08 -070048
John Garbuttdaadf742012-04-27 18:28:28 +010049#
50# Prepare Dom0
51# including installing XenAPI plugins
52#
53
Mate Lakata8bf0f22013-03-07 18:37:31 +000054cd $THIS_DIR
John Garbuttdaadf742012-04-27 18:28:28 +010055
Mate Lakat57e3da92013-03-22 16:34:05 +000056# Install plugins
John Garbuttdaadf742012-04-27 18:28:28 +010057
Mate Lakat57e3da92013-03-22 16:34:05 +000058## Nova plugins
59NOVA_ZIPBALL_URL=${NOVA_ZIPBALL_URL:-$(zip_snapshot_location $NOVA_REPO $NOVA_BRANCH)}
60install_xapi_plugins_from_zipball $NOVA_ZIPBALL_URL
Maru Newby2298ca42012-10-25 23:46:42 +000061
Mate Lakat57e3da92013-03-22 16:34:05 +000062## Install the netwrap xapi plugin to support agent control of dom0 networking
Maru Newby2298ca42012-10-25 23:46:42 +000063if [[ "$ENABLED_SERVICES" =~ "q-agt" && "$Q_PLUGIN" = "openvswitch" ]]; then
Mate Lakat57e3da92013-03-22 16:34:05 +000064 QUANTUM_ZIPBALL_URL=${QUANTUM_ZIPBALL_URL:-$(zip_snapshot_location $QUANTUM_REPO $QUANTUM_BRANCH)}
65 install_xapi_plugins_from_zipball $QUANTUM_ZIPBALL_URL
Maru Newby2298ca42012-10-25 23:46:42 +000066fi
67
Mate Lakat57e3da92013-03-22 16:34:05 +000068create_directory_for_kernels
John Garbuttdaadf742012-04-27 18:28:28 +010069
70#
71# Configure Networking
72#
Anthony Youngb62b4ca2011-10-26 22:29:08 -070073
74# Helper to create networks
rootb1153412012-01-19 13:28:21 -080075# Uses echo trickery to return network uuid
Anthony Youngb62b4ca2011-10-26 22:29:08 -070076function create_network() {
rootb1153412012-01-19 13:28:21 -080077 br=$1
78 dev=$2
79 vlan=$3
80 netname=$4
81 if [ -z $br ]
82 then
Renuka Apte0af143b2012-04-02 15:46:53 -070083 pif=$(xe_min pif-list device=$dev VLAN=$vlan)
rootb1153412012-01-19 13:28:21 -080084 if [ -z $pif ]
85 then
86 net=$(xe network-create name-label=$netname)
87 else
Renuka Apte0af143b2012-04-02 15:46:53 -070088 net=$(xe_min network-list PIF-uuids=$pif)
rootb1153412012-01-19 13:28:21 -080089 fi
90 echo $net
91 return 0
92 fi
Renuka Apte0af143b2012-04-02 15:46:53 -070093 if [ ! $(xe_min network-list params=bridge | grep -w --only-matching $br) ]
rootb1153412012-01-19 13:28:21 -080094 then
95 echo "Specified bridge $br does not exist"
96 echo "If you wish to use defaults, please keep the bridge name empty"
97 exit 1
98 else
Renuka Apte0af143b2012-04-02 15:46:53 -070099 net=$(xe_min network-list bridge=$br)
rootb1153412012-01-19 13:28:21 -0800100 echo $net
101 fi
102}
103
104function errorcheck() {
105 rc=$?
106 if [ $rc -ne 0 ]
107 then
108 exit $rc
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700109 fi
110}
111
John Garbuttdaadf742012-04-27 18:28:28 +0100112# Create host, vm, mgmt, pub networks on XenServer
rootb1153412012-01-19 13:28:21 -0800113VM_NET=$(create_network "$VM_BR" "$VM_DEV" "$VM_VLAN" "vmbr")
114errorcheck
115MGT_NET=$(create_network "$MGT_BR" "$MGT_DEV" "$MGT_VLAN" "mgtbr")
116errorcheck
117PUB_NET=$(create_network "$PUB_BR" "$PUB_DEV" "$PUB_VLAN" "pubbr")
118errorcheck
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700119
120# Helper to create vlans
121function create_vlan() {
rootb1153412012-01-19 13:28:21 -0800122 dev=$1
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700123 vlan=$2
124 net=$3
rootb1153412012-01-19 13:28:21 -0800125 # VLAN -1 refers to no VLAN (physical network)
126 if [ $vlan -eq -1 ]
127 then
128 return
129 fi
Renuka Apte0af143b2012-04-02 15:46:53 -0700130 if [ -z $(xe_min vlan-list tag=$vlan) ]
rootb1153412012-01-19 13:28:21 -0800131 then
Renuka Apte0af143b2012-04-02 15:46:53 -0700132 pif=$(xe_min pif-list network-uuid=$net)
rootb1153412012-01-19 13:28:21 -0800133 # We created a brand new network this time
134 if [ -z $pif ]
135 then
Renuka Apte0af143b2012-04-02 15:46:53 -0700136 pif=$(xe_min pif-list device=$dev VLAN=-1)
rootb1153412012-01-19 13:28:21 -0800137 xe vlan-create pif-uuid=$pif vlan=$vlan network-uuid=$net
138 else
139 echo "VLAN does not exist but PIF attached to this network"
140 echo "How did we reach here?"
141 exit 1
142 fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700143 fi
144}
145
146# Create vlans for vm and management
rootb1153412012-01-19 13:28:21 -0800147create_vlan $PUB_DEV $PUB_VLAN $PUB_NET
148create_vlan $VM_DEV $VM_VLAN $VM_NET
149create_vlan $MGT_DEV $MGT_VLAN $MGT_NET
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700150
John Garbuttdaadf742012-04-27 18:28:28 +0100151# Get final bridge names
152if [ -z $VM_BR ]; then
153 VM_BR=$(xe_min network-list uuid=$VM_NET params=bridge)
154fi
155if [ -z $MGT_BR ]; then
156 MGT_BR=$(xe_min network-list uuid=$MGT_NET params=bridge)
157fi
158if [ -z $PUB_BR ]; then
159 PUB_BR=$(xe_min network-list uuid=$PUB_NET params=bridge)
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700160fi
161
John Garbuttdaadf742012-04-27 18:28:28 +0100162# dom0 ip, XenAPI is assumed to be listening
163HOST_IP=${HOST_IP:-`ifconfig xenbr0 | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"`}
164
165# Set up ip forwarding, but skip on xcp-xapi
John Garbuttd8f1a872012-06-26 11:16:38 +0100166if [ -a /etc/sysconfig/network ]; then
John Garbuttdaadf742012-04-27 18:28:28 +0100167 if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then
168 # FIXME: This doesn't work on reboot!
169 echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network
170 fi
171fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700172# Also, enable ip forwarding in rc.local, since the above trick isn't working
173if ! grep -q "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then
174 echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local
175fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700176# Enable ip forwarding at runtime as well
177echo 1 > /proc/sys/net/ipv4/ip_forward
178
John Garbuttdaadf742012-04-27 18:28:28 +0100179
180#
Anthony Young346e4912011-11-05 00:22:47 -0500181# Shutdown previous runs
John Garbuttdaadf742012-04-27 18:28:28 +0100182#
183
Anthony Young346e4912011-11-05 00:22:47 -0500184DO_SHUTDOWN=${DO_SHUTDOWN:-1}
John Garbuttdaadf742012-04-27 18:28:28 +0100185CLEAN_TEMPLATES=${CLEAN_TEMPLATES:-false}
Anthony Young346e4912011-11-05 00:22:47 -0500186if [ "$DO_SHUTDOWN" = "1" ]; then
Anthony Young40b57372011-11-05 00:30:07 -0500187 # Shutdown all domU's that created previously
John Garbuttdaadf742012-04-27 18:28:28 +0100188 clean_templates_arg=""
189 if $CLEAN_TEMPLATES; then
190 clean_templates_arg="--remove-templates"
191 fi
192 ./scripts/uninstall-os-vpx.sh $clean_templates_arg
Anthony Young346e4912011-11-05 00:22:47 -0500193
194 # Destroy any instances that were launched
195 for uuid in `xe vm-list | grep -1 instance | grep uuid | sed "s/.*\: //g"`; do
196 echo "Shutting down nova instance $uuid"
197 xe vm-unpause uuid=$uuid || true
Armando Migliaccio7a5f7f22012-04-20 22:58:00 +0100198 xe vm-shutdown uuid=$uuid || true
Anthony Young346e4912011-11-05 00:22:47 -0500199 xe vm-destroy uuid=$uuid
200 done
Anthony Youngfa4ecc62011-11-11 10:23:22 -0800201
202 # Destroy orphaned vdis
203 for uuid in `xe vdi-list | grep -1 Glance | grep uuid | sed "s/.*\: //g"`; do
204 xe vdi-destroy uuid=$uuid
205 done
Anthony Young346e4912011-11-05 00:22:47 -0500206fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700207
Renuka Apte0af143b2012-04-02 15:46:53 -0700208
John Garbuttdaadf742012-04-27 18:28:28 +0100209#
210# Create Ubuntu VM template
211# and/or create VM from template
212#
Renuka Apte0af143b2012-04-02 15:46:53 -0700213
John Garbuttdaadf742012-04-27 18:28:28 +0100214GUEST_NAME=${GUEST_NAME:-"DevStackOSDomU"}
John Garbuttd8f1a872012-06-26 11:16:38 +0100215TNAME="devstack_template"
John Garbuttdaadf742012-04-27 18:28:28 +0100216SNAME_PREPARED="template_prepared"
217SNAME_FIRST_BOOT="before_first_boot"
218
219function wait_for_VM_to_halt() {
Bob Ball63c6c2b2013-01-24 13:13:51 +0000220 set +x
221 echo "Waiting for the VM to halt. Progress in-VM can be checked with vncviewer:"
222 mgmt_ip=$(echo $XENAPI_CONNECTION_URL | tr -d -c '1234567890.')
223 domid=$(xe vm-list name-label="$GUEST_NAME" params=dom-id minimal=true)
224 port=$(xenstore-read /local/domain/$domid/console/vnc-port)
225 echo "vncviewer -via $mgmt_ip localhost:${port:2}"
Renuka Apte0af143b2012-04-02 15:46:53 -0700226 while true
227 do
228 state=$(xe_min vm-list name-label="$GUEST_NAME" power-state=halted)
229 if [ -n "$state" ]
230 then
231 break
232 else
Bob Ball63c6c2b2013-01-24 13:13:51 +0000233 echo -n "."
John Garbuttdaadf742012-04-27 18:28:28 +0100234 sleep 20
Renuka Apte0af143b2012-04-02 15:46:53 -0700235 fi
236 done
Bob Ball63c6c2b2013-01-24 13:13:51 +0000237 set -x
John Garbuttdaadf742012-04-27 18:28:28 +0100238}
Renuka Apte0af143b2012-04-02 15:46:53 -0700239
John Garbuttdaadf742012-04-27 18:28:28 +0100240templateuuid=$(xe template-list name-label="$TNAME")
241if [ -z "$templateuuid" ]; then
242 #
243 # Install Ubuntu over network
244 #
245
John Garbuttdaadf742012-04-27 18:28:28 +0100246 # always update the preseed file, incase we have a newer one
247 PRESEED_URL=${PRESEED_URL:-""}
248 if [ -z "$PRESEED_URL" ]; then
249 PRESEED_URL="${HOST_IP}/devstackubuntupreseed.cfg"
250 HTTP_SERVER_LOCATION="/opt/xensource/www"
251 if [ ! -e $HTTP_SERVER_LOCATION ]; then
252 HTTP_SERVER_LOCATION="/var/www/html"
253 mkdir -p $HTTP_SERVER_LOCATION
254 fi
Mate Lakata8bf0f22013-03-07 18:37:31 +0000255 cp -f $THIS_DIR/devstackubuntupreseed.cfg $HTTP_SERVER_LOCATION
John Garbuttdaadf742012-04-27 18:28:28 +0100256 MIRROR=${MIRROR:-""}
257 if [ -n "$MIRROR" ]; then
258 sed -e "s,d-i mirror/http/hostname string .*,d-i mirror/http/hostname string $MIRROR," \
259 -i "${HTTP_SERVER_LOCATION}/devstackubuntupreseed.cfg"
260 fi
261 fi
262
John Garbuttd8f1a872012-06-26 11:16:38 +0100263 # Update the template
Mate Lakata8bf0f22013-03-07 18:37:31 +0000264 $THIS_DIR/scripts/install_ubuntu_template.sh $PRESEED_URL
John Garbuttdaadf742012-04-27 18:28:28 +0100265
266 # create a new VM with the given template
267 # creating the correct VIFs and metadata
Mate Lakata8bf0f22013-03-07 18:37:31 +0000268 $THIS_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 +0100269
270 # wait for install to finish
271 wait_for_VM_to_halt
272
273 # set VM to restart after a reboot
Renuka Apte0af143b2012-04-02 15:46:53 -0700274 vm_uuid=$(xe_min vm-list name-label="$GUEST_NAME")
275 xe vm-param-set actions-after-reboot=Restart uuid="$vm_uuid"
276
John Garbuttdaadf742012-04-27 18:28:28 +0100277 #
278 # Prepare VM for DevStack
279 #
280
281 # Install XenServer tools, and other such things
Mate Lakata8bf0f22013-03-07 18:37:31 +0000282 $THIS_DIR/prepare_guest_template.sh "$GUEST_NAME"
John Garbuttdaadf742012-04-27 18:28:28 +0100283
284 # start the VM to run the prepare steps
285 xe vm-start vm="$GUEST_NAME"
286
287 # Wait for prep script to finish and shutdown system
288 wait_for_VM_to_halt
289
Renuka Apte0af143b2012-04-02 15:46:53 -0700290 # Make template from VM
John Garbuttdaadf742012-04-27 18:28:28 +0100291 snuuid=$(xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_PREPARED")
292 xe snapshot-clone uuid=$snuuid new-name-label="$TNAME"
293else
294 #
295 # Template already installed, create VM from template
296 #
297 vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$GUEST_NAME")
Renuka Apte0af143b2012-04-02 15:46:53 -0700298fi
299
John Garbuttdaadf742012-04-27 18:28:28 +0100300
301#
302# Inject DevStack inside VM disk
303#
Mate Lakata8bf0f22013-03-07 18:37:31 +0000304$THIS_DIR/build_xva.sh "$GUEST_NAME"
Renuka Apte0af143b2012-04-02 15:46:53 -0700305
John Garbuttdaadf742012-04-27 18:28:28 +0100306# create a snapshot before the first boot
307# to allow a quick re-run with the same settings
308xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_FIRST_BOOT"
309
310
311#
312# Run DevStack VM
313#
Renuka Apte0af143b2012-04-02 15:46:53 -0700314xe vm-start vm="$GUEST_NAME"
Anthony Young3eb8f592011-10-26 23:11:52 -0700315
John Garbuttdaadf742012-04-27 18:28:28 +0100316
317#
318# Find IP and optionally wait for stack.sh to complete
319#
320
321function find_ip_by_name() {
322 local guest_name="$1"
323 local interface="$2"
324 local period=10
325 max_tries=10
326 i=0
327 while true
328 do
329 if [ $i -ge $max_tries ]; then
330 echo "Timed out waiting for devstack ip address"
331 exit 11
332 fi
333
334 devstackip=$(xe vm-list --minimal \
335 name-label=$guest_name \
336 params=networks | sed -ne "s,^.*${interface}/ip: \([0-9.]*\).*\$,\1,p")
337 if [ -z "$devstackip" ]
338 then
339 sleep $period
340 ((i++))
341 else
342 echo $devstackip
343 break
344 fi
345 done
346}
347
348function ssh_no_check() {
349 ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$@"
350}
351
352# Note the XenServer needs to be on the chosen
353# network, so XenServer can access Glance API
354if [ $HOST_IP_IFACE == "eth2" ]; then
355 DOMU_IP=$MGT_IP
356 if [ $MGT_IP == "dhcp" ]; then
357 DOMU_IP=$(find_ip_by_name $GUEST_NAME 2)
358 fi
359else
360 DOMU_IP=$PUB_IP
361 if [ $PUB_IP == "dhcp" ]; then
362 DOMU_IP=$(find_ip_by_name $GUEST_NAME 3)
363 fi
Renuka Aptec56885a2012-02-29 16:09:26 -0800364fi
365
Anthony Young1de18c62011-11-01 14:19:18 -0500366# If we have copied our ssh credentials, use ssh to monitor while the installation runs
367WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
John Garbuttdaadf742012-04-27 18:28:28 +0100368COPYENV=${COPYENV:-1}
Anthony Young1de18c62011-11-01 14:19:18 -0500369if [ "$WAIT_TILL_LAUNCH" = "1" ] && [ -e ~/.ssh/id_rsa.pub ] && [ "$COPYENV" = "1" ]; then
Bob Ball7fcc1572013-02-20 15:56:25 +0000370 set +x
Anthony Young1de18c62011-11-01 14:19:18 -0500371
Bob Ball7fcc1572013-02-20 15:56:25 +0000372 echo "VM Launched - Waiting for startup script"
John Garbuttdaadf742012-04-27 18:28:28 +0100373 # wait for log to appear
374 while ! ssh_no_check -q stack@$DOMU_IP "[ -e run.sh.log ]"; do
375 sleep 10
Anthony Young1de18c62011-11-01 14:19:18 -0500376 done
Bob Ball7fcc1572013-02-20 15:56:25 +0000377 echo -n "Running"
Mate Lakat9efcf602012-12-19 10:23:06 +0000378 while [ `ssh_no_check -q stack@$DOMU_IP pgrep -c run.sh` -ge 1 ]
379 do
John Garbuttdaadf742012-04-27 18:28:28 +0100380 sleep 10
Mate Lakat9efcf602012-12-19 10:23:06 +0000381 echo -n "."
Anthony Young1de18c62011-11-01 14:19:18 -0500382 done
Mate Lakat9efcf602012-12-19 10:23:06 +0000383 echo "done!"
384 set -x
Anthony Young1de18c62011-11-01 14:19:18 -0500385
Mate Lakat9efcf602012-12-19 10:23:06 +0000386 # output the run.sh.log
387 ssh_no_check -q stack@$DOMU_IP 'cat run.sh.log'
Anthony Young1de18c62011-11-01 14:19:18 -0500388
Mate Lakat9efcf602012-12-19 10:23:06 +0000389 # Fail if the expected text is not found
390 ssh_no_check -q stack@$DOMU_IP 'cat run.sh.log' | grep -q 'stack.sh completed in'
391
Bob Ball63c6c2b2013-01-24 13:13:51 +0000392 set +x
John Garbuttdaadf742012-04-27 18:28:28 +0100393 echo "################################################################################"
Anthony Young1de18c62011-11-01 14:19:18 -0500394 echo ""
John Garbuttdaadf742012-04-27 18:28:28 +0100395 echo "All Finished!"
396 echo "You can visit the OpenStack Dashboard"
397 echo "at http://$DOMU_IP, and contact other services at the usual ports."
Anthony Young1de18c62011-11-01 14:19:18 -0500398else
Bob Ball63c6c2b2013-01-24 13:13:51 +0000399 set +x
Anthony Young1de18c62011-11-01 14:19:18 -0500400 echo "################################################################################"
401 echo ""
402 echo "All Finished!"
403 echo "Now, you can monitor the progress of the stack.sh installation by "
404 echo "tailing /opt/stack/run.sh.log from within your domU."
405 echo ""
John Garbuttdaadf742012-04-27 18:28:28 +0100406 echo "ssh into your domU now: 'ssh stack@$DOMU_IP' using your password"
Anthony Young1de18c62011-11-01 14:19:18 -0500407 echo "and then do: 'tail -f /opt/stack/run.sh.log'"
408 echo ""
409 echo "When the script completes, you can then visit the OpenStack Dashboard"
John Garbuttdaadf742012-04-27 18:28:28 +0100410 echo "at http://$DOMU_IP, and contact other services at the usual ports."
Anthony Young1de18c62011-11-01 14:19:18 -0500411fi