blob: 04e1a4591355907c5d5ea9a0ea26d0d3938fcffd [file] [log] [blame]
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -07001#!/usr/bin/env bash
2
Anthony Younge28f7752011-11-09 11:48:09 -08003# Make sure that we have the proper version of ubuntu (only works on oneiric)
4if ! egrep -q "oneiric" /etc/lsb-release; then
Anthony Young593e9aa2011-11-09 12:42:08 -08005 echo "This script only works with ubuntu oneiric."
Jesse Andrewse3c47a32011-11-07 10:44:43 -08006 exit 1
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -07007fi
8
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -07009# Keep track of the current directory
10TOOLS_DIR=$(cd $(dirname "$0") && pwd)
11TOP_DIR=`cd $TOOLS_DIR/..; pwd`
12
Jesse Andrews53d75332011-11-06 07:54:11 -080013cd $TOP_DIR
14
15# Source params
16source ./stackrc
17
18# Ubuntu distro to install
19DIST_NAME=${DIST_NAME:-oneiric}
20
Jesse Andrewse3c47a32011-11-07 10:44:43 -080021# Configure how large the VM should be
22GUEST_SIZE=${GUEST_SIZE:-10G}
23
Jesse Andrews228f2462011-11-05 17:36:14 -070024# exit on error to stop unexpected errors
25set -o errexit
26set -o xtrace
27
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070028# Abort if localrc is not set
29if [ ! -e $TOP_DIR/localrc ]; then
30 echo "You must have a localrc with ALL necessary passwords defined before proceeding."
31 echo "See stack.sh for required passwords."
32 exit 1
33fi
34
35# Install deps if needed
Jesse Andrews26793032011-11-11 13:56:29 -080036DEPS="kvm libvirt-bin kpartx cloud-utils curl"
Anthony Young8326fd22011-11-15 13:03:19 -080037apt-get install -y --force-yes $DEPS || true # allow this to fail gracefully for concurrent builds
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070038
39# Where to store files and instances
Jesse Andrewsd7326d22011-11-20 10:02:26 -080040WORK_DIR=${WORK_DIR:-/opt/uecstack}
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070041
42# Where to store images
Jesse Andrews228f2462011-11-05 17:36:14 -070043image_dir=$WORK_DIR/images/$DIST_NAME
44mkdir -p $image_dir
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070045
Jesse Andrewsd7326d22011-11-20 10:02:26 -080046# Start over with a clean base image, if desired
47if [ $CLEAN_BASE ]; then
48 rm -f $image_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070049fi
50
Jesse Andrewsd7326d22011-11-20 10:02:26 -080051# Get the base image if it does not yet exist
52if [ ! -e $image_dir/disk ]; then
53 $TOOLS_DIR/get_uec_image.sh -r $GUEST_SIZE $DIST_NAME $image_dir/disk $image_dir/kernel
54fi
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070055
Jesse Andrewsd7326d22011-11-20 10:02:26 -080056# Copy over dev environment if COPY_ENV is set.
57# This will also copy over your current devstack.
58if [ $COPY_ENV ]; then
59 cd $TOOLS_DIR
60 ./copy_dev_environment_to_uec.sh $image_dir/disk
61fi
62
63# Option to warm the base image with software requirements.
64if [ $WARM_CACHE ]; then
65 cd $TOOLS_DIR
66 ./warm_apts_and_pips_for_uec.sh $image_dir/disk
67fi
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070068
69# Name of our instance, used by libvirt
70GUEST_NAME=${GUEST_NAME:-devstack}
71
72# Mop up after previous runs
73virsh destroy $GUEST_NAME || true
74
75# Where this vm is stored
Jesse Andrews228f2462011-11-05 17:36:14 -070076vm_dir=$WORK_DIR/instances/$GUEST_NAME
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070077
78# Create vm dir and remove old disk
Jesse Andrews228f2462011-11-05 17:36:14 -070079mkdir -p $vm_dir
80rm -f $vm_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070081
82# Create a copy of the base image
Jesse Andrewsf5a76912011-11-05 17:47:50 -070083qemu-img create -f qcow2 -b $image_dir/disk $vm_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070084
85# Back to devstack
86cd $TOP_DIR
87
88GUEST_NETWORK=${GUEST_NETWORK:-1}
89GUEST_RECREATE_NET=${GUEST_RECREATE_NET:-yes}
90GUEST_IP=${GUEST_IP:-192.168.$GUEST_NETWORK.50}
91GUEST_CIDR=${GUEST_CIDR:-$GUEST_IP/24}
92GUEST_NETMASK=${GUEST_NETMASK:-255.255.255.0}
93GUEST_GATEWAY=${GUEST_GATEWAY:-192.168.$GUEST_NETWORK.1}
94GUEST_MAC=${GUEST_MAC:-"02:16:3e:07:69:`printf '%02X' $GUEST_NETWORK`"}
95GUEST_RAM=${GUEST_RAM:-1524288}
96GUEST_CORES=${GUEST_CORES:-1}
97
98# libvirt.xml configuration
Jesse Andrews228f2462011-11-05 17:36:14 -070099NET_XML=$vm_dir/net.xml
Anthony Young8b47cdf2011-11-09 23:36:18 -0800100NET_NAME=${NET_NAME:-devstack-$GUEST_NETWORK}
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700101cat > $NET_XML <<EOF
102<network>
Anthony Young8b47cdf2011-11-09 23:36:18 -0800103 <name>$NET_NAME</name>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700104 <bridge name="stackbr%d" />
105 <forward/>
Jesse Andrewsa6282622011-11-05 18:39:33 -0700106 <ip address="$GUEST_GATEWAY" netmask="$GUEST_NETMASK">
107 <dhcp>
Jesse Andrews02cc96c2011-11-06 10:29:10 -0800108 <range start='192.168.$GUEST_NETWORK.2' end='192.168.$GUEST_NETWORK.127' />
Jesse Andrewsa6282622011-11-05 18:39:33 -0700109 </dhcp>
110 </ip>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700111</network>
112EOF
113
114if [[ "$GUEST_RECREATE_NET" == "yes" ]]; then
Anthony Young8b47cdf2011-11-09 23:36:18 -0800115 virsh net-destroy $NET_NAME || true
Jesse Andrewsdca89002011-11-06 10:33:33 -0800116 # destroying the network isn't enough to delete the leases
Anthony Young8b47cdf2011-11-09 23:36:18 -0800117 rm -f /var/lib/libvirt/dnsmasq/$NET_NAME.leases
Jesse Andrews228f2462011-11-05 17:36:14 -0700118 virsh net-create $vm_dir/net.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700119fi
120
121# libvirt.xml configuration
Jesse Andrews228f2462011-11-05 17:36:14 -0700122LIBVIRT_XML=$vm_dir/libvirt.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700123cat > $LIBVIRT_XML <<EOF
124<domain type='kvm'>
125 <name>$GUEST_NAME</name>
126 <memory>$GUEST_RAM</memory>
127 <os>
Jesse Andrews228f2462011-11-05 17:36:14 -0700128 <type>hvm</type>
Jesse Andrewsf5a76912011-11-05 17:47:50 -0700129 <kernel>$image_dir/kernel</kernel>
Jesse Andrews438ea572011-11-05 22:33:49 -0700130 <cmdline>root=/dev/vda ro console=ttyS0 init=/usr/lib/cloud-init/uncloud-init ds=nocloud-net;s=http://192.168.$GUEST_NETWORK.1:4567/ ubuntu-pass=ubuntu</cmdline>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700131 </os>
132 <features>
133 <acpi/>
134 </features>
135 <clock offset='utc'/>
136 <vcpu>$GUEST_CORES</vcpu>
137 <devices>
138 <disk type='file'>
139 <driver type='qcow2'/>
Jesse Andrews228f2462011-11-05 17:36:14 -0700140 <source file='$vm_dir/disk'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700141 <target dev='vda' bus='virtio'/>
142 </disk>
143
144 <interface type='network'>
Anthony Young72eab222011-11-09 23:38:18 -0800145 <source network='$NET_NAME'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700146 </interface>
147
148 <!-- The order is significant here. File must be defined first -->
149 <serial type="file">
Jesse Andrews228f2462011-11-05 17:36:14 -0700150 <source path='$vm_dir/console.log'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700151 <target port='1'/>
152 </serial>
153
154 <console type='pty' tty='/dev/pts/2'>
155 <source path='/dev/pts/2'/>
156 <target port='0'/>
157 </console>
158
159 <serial type='pty'>
160 <source path='/dev/pts/2'/>
161 <target port='0'/>
162 </serial>
163
164 <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
165 </devices>
166</domain>
167EOF
168
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700169
Jesse Andrewse49f7512011-11-05 22:34:45 -0700170rm -rf $vm_dir/uec
Jesse Andrews9ed6bbd2011-11-05 22:28:46 -0700171cp -r $TOOLS_DIR/uec $vm_dir/uec
172
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700173# set metadata
174cat > $vm_dir/uec/meta-data<<EOF
175hostname: $GUEST_NAME
Jesse Andrewse3c47a32011-11-07 10:44:43 -0800176instance-id: i-hop
177instance-type: m1.ignore
Jesse Andrews7306f3b2011-11-05 23:13:34 -0700178local-hostname: $GUEST_NAME.local
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700179EOF
180
Anthony Young2838f122011-11-10 13:04:40 -0800181# set user-data
Jesse Andrews63cb9232011-11-05 23:16:53 -0700182cat > $vm_dir/uec/user-data<<EOF
Jesse Andrews446a3302011-11-05 23:36:29 -0700183#!/bin/bash
Jesse Andrewsb17c4f32011-11-06 09:25:55 -0800184# hostname needs to resolve for rabbit
Jesse Andrews6e3a4c52011-11-06 09:35:13 -0800185sed -i "s/127.0.0.1/127.0.0.1 \`hostname\`/" /etc/hosts
Jesse Andrews446a3302011-11-05 23:36:29 -0700186apt-get update
Jesse Andrewsc7f72ad2011-11-06 08:00:28 -0800187apt-get install git sudo -y
Anthony Young760ddde2011-11-10 13:46:52 -0800188# Disable byobu
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800189sudo apt-get remove -y byobu
Anthony Youngb2256822011-11-10 12:57:59 -0800190EOF
191
192# Setup stack user with our key
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800193if [[ -e ~/.ssh/id_rsa.pub ]]; then
Anthony Youngb7661282011-11-10 13:09:25 -0800194 PUB_KEY=`cat ~/.ssh/id_rsa.pub`
Anthony Young2838f122011-11-10 13:04:40 -0800195 cat >> $vm_dir/uec/user-data<<EOF
Anthony Youngb2256822011-11-10 12:57:59 -0800196mkdir -p /opt/stack
Anthony Young331ae292011-12-21 11:55:35 -0800197if [ ! -d /opt/stack/devstack ]; then
198 git clone https://github.com/cloudbuilders/devstack.git /opt/stack/devstack
199 cd /opt/stack/devstack
200 cat > localrc <<LOCAL_EOF
201ROOTSLEEP=0
202`cat $TOP_DIR/localrc`
203LOCAL_EOF
204fi
Anthony Youngff7771e2011-11-10 13:33:31 -0800205useradd -U -G sudo -s /bin/bash -d /opt/stack -m stack
Anthony Youngb2256822011-11-10 12:57:59 -0800206echo stack:pass | chpasswd
207mkdir -p /opt/stack/.ssh
Anthony Youngb7661282011-11-10 13:09:25 -0800208echo "$PUB_KEY" > /opt/stack/.ssh/authorized_keys
Anthony Youngb2256822011-11-10 12:57:59 -0800209chown -R stack /opt/stack
210chmod 700 /opt/stack/.ssh
211chmod 600 /opt/stack/.ssh/authorized_keys
212
213grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
214 echo "#includedir /etc/sudoers.d" >> /etc/sudoers
215( umask 226 && echo "stack ALL=(ALL) NOPASSWD:ALL" \
216 > /etc/sudoers.d/50_stack_sh )
217EOF
218fi
219
220# Run stack.sh
Anthony Young2838f122011-11-10 13:04:40 -0800221cat >> $vm_dir/uec/user-data<<EOF
Anthony Young331ae292011-12-21 11:55:35 -0800222su -c "cd /opt/stack/devstack && ./stack.sh" stack
Jesse Andrews63cb9232011-11-05 23:16:53 -0700223EOF
224
Jesse Andrewsee34f622011-11-05 22:41:57 -0700225# (re)start a metadata service
Jesse Andrews3ce79aa2011-11-05 22:52:20 -0700226(
227 pid=`lsof -iTCP@192.168.$GUEST_NETWORK.1:4567 -n | awk '{print $2}' | tail -1`
Jesse Andrews9645b0c2011-11-05 23:05:33 -0700228 [ -z "$pid" ] || kill -9 $pid
Jesse Andrews3ce79aa2011-11-05 22:52:20 -0700229)
Jesse Andrewsf504e282011-11-05 22:29:35 -0700230cd $vm_dir/uec
231python meta.py 192.168.$GUEST_NETWORK.1:4567 &
Jesse Andrews9ed6bbd2011-11-05 22:28:46 -0700232
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700233# Create the instance
Jesse Andrews63fa7ab2011-11-05 18:49:36 -0700234virsh create $vm_dir/libvirt.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700235
236# Tail the console log till we are done
237WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
238if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
Jesse Andrews228f2462011-11-05 17:36:14 -0700239 set +o xtrace
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700240 # Done creating the container, let's tail the log
241 echo
242 echo "============================================================="
243 echo " -- YAY! --"
244 echo "============================================================="
245 echo
246 echo "We're done launching the vm, about to start tailing the"
247 echo "stack.sh log. It will take a second or two to start."
248 echo
249 echo "Just CTRL-C at any time to stop tailing."
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800250 echo
251
252 if ! timeout 60 sh -c "while [ ! -s /var/lib/libvirt/dnsmasq/$NET_NAME.leases ]; do sleep 1; done"; then
253 echo "Your instance failed to acquire an IP address"
254 exit 1
255 fi
256
257 ip=`cat /var/lib/libvirt/dnsmasq/$NET_NAME.leases | cut -d " " -f3`
258 echo "#############################################################"
259 echo " -- This is your instance's IP: --"
260 echo " $ip"
261 echo "#############################################################"
262
263 sleep 2
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700264
Jesse Andrews228f2462011-11-05 17:36:14 -0700265 while [ ! -e "$vm_dir/console.log" ]; do
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700266 sleep 1
267 done
268
Jesse Andrews228f2462011-11-05 17:36:14 -0700269 tail -F $vm_dir/console.log &
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700270
271 TAIL_PID=$!
272
273 function kill_tail() {
274 kill $TAIL_PID
275 exit 1
276 }
277
278 # Let Ctrl-c kill tail and exit
279 trap kill_tail SIGINT
280
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700281 echo "Waiting stack.sh to finish..."
Jesse Andrewsd55a5152011-11-06 08:16:42 -0800282 while ! egrep -q '^stack.sh (completed|failed)' $vm_dir/console.log ; do
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700283 sleep 1
284 done
285
286 set -o xtrace
287
288 kill $TAIL_PID
289
Jesse Andrews228f2462011-11-05 17:36:14 -0700290 if ! grep -q "^stack.sh completed in" $vm_dir/console.log; then
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700291 exit 1
292 fi
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800293
294 set +o xtrace
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700295 echo ""
296 echo "Finished - Zip-a-dee Doo-dah!"
297fi