blob: 4ffd02a21c5e91c2305658b00352a9b6d9fdbc26 [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
Anthony Younge28f7752011-11-09 11:48:09 -080036DEPS="kvm libvirt-bin kpartx cloud-utils"
Jesse Andrewse3c47a32011-11-07 10:44:43 -080037dpkg -l $DEPS || apt-get install -y --force-yes $DEPS
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070038
39# Where to store files and instances
40WORK_DIR=${WORK_DIR:-/opt/kvmstack}
41
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
46# Original version of built image
Jesse Andrews228f2462011-11-05 17:36:14 -070047uec_url=http://uec-images.ubuntu.com/$DIST_NAME/current/$DIST_NAME-server-cloudimg-amd64.tar.gz
Jesse Andrews96dffbc2011-11-05 17:37:33 -070048tarball=$image_dir/$(basename $uec_url)
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070049
50# download the base uec image if we haven't already
Jesse Andrews228f2462011-11-05 17:36:14 -070051if [ ! -f $tarball ]; then
52 curl $uec_url -o $tarball
Jesse Andrews3b768582011-11-05 17:40:20 -070053 (cd $image_dir && tar -Sxvzf $tarball)
Jesse Andrewse3c47a32011-11-07 10:44:43 -080054 resize-part-image $image_dir/*.img $GUEST_SIZE $image_dir/disk
Jesse Andrews228f2462011-11-05 17:36:14 -070055 cp $image_dir/*-vmlinuz-virtual $image_dir/kernel
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070056fi
57
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070058
59# Configure the root password of the vm to be the same as ``ADMIN_PASSWORD``
60ROOT_PASSWORD=${ADMIN_PASSWORD:-password}
61
62# Name of our instance, used by libvirt
63GUEST_NAME=${GUEST_NAME:-devstack}
64
65# Mop up after previous runs
66virsh destroy $GUEST_NAME || true
67
68# Where this vm is stored
Jesse Andrews228f2462011-11-05 17:36:14 -070069vm_dir=$WORK_DIR/instances/$GUEST_NAME
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070070
71# Create vm dir and remove old disk
Jesse Andrews228f2462011-11-05 17:36:14 -070072mkdir -p $vm_dir
73rm -f $vm_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070074
75# Create a copy of the base image
Jesse Andrewsf5a76912011-11-05 17:47:50 -070076qemu-img create -f qcow2 -b $image_dir/disk $vm_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070077
78# Back to devstack
79cd $TOP_DIR
80
81GUEST_NETWORK=${GUEST_NETWORK:-1}
82GUEST_RECREATE_NET=${GUEST_RECREATE_NET:-yes}
83GUEST_IP=${GUEST_IP:-192.168.$GUEST_NETWORK.50}
84GUEST_CIDR=${GUEST_CIDR:-$GUEST_IP/24}
85GUEST_NETMASK=${GUEST_NETMASK:-255.255.255.0}
86GUEST_GATEWAY=${GUEST_GATEWAY:-192.168.$GUEST_NETWORK.1}
87GUEST_MAC=${GUEST_MAC:-"02:16:3e:07:69:`printf '%02X' $GUEST_NETWORK`"}
88GUEST_RAM=${GUEST_RAM:-1524288}
89GUEST_CORES=${GUEST_CORES:-1}
90
91# libvirt.xml configuration
Jesse Andrews228f2462011-11-05 17:36:14 -070092NET_XML=$vm_dir/net.xml
Anthony Young8b47cdf2011-11-09 23:36:18 -080093NET_NAME=${NET_NAME:-devstack-$GUEST_NETWORK}
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070094cat > $NET_XML <<EOF
95<network>
Anthony Young8b47cdf2011-11-09 23:36:18 -080096 <name>$NET_NAME</name>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070097 <bridge name="stackbr%d" />
98 <forward/>
Jesse Andrewsa6282622011-11-05 18:39:33 -070099 <ip address="$GUEST_GATEWAY" netmask="$GUEST_NETMASK">
100 <dhcp>
Jesse Andrews02cc96c2011-11-06 10:29:10 -0800101 <range start='192.168.$GUEST_NETWORK.2' end='192.168.$GUEST_NETWORK.127' />
Jesse Andrewsa6282622011-11-05 18:39:33 -0700102 </dhcp>
103 </ip>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700104</network>
105EOF
106
107if [[ "$GUEST_RECREATE_NET" == "yes" ]]; then
Anthony Young8b47cdf2011-11-09 23:36:18 -0800108 virsh net-destroy $NET_NAME || true
Jesse Andrewsdca89002011-11-06 10:33:33 -0800109 # destroying the network isn't enough to delete the leases
Anthony Young8b47cdf2011-11-09 23:36:18 -0800110 rm -f /var/lib/libvirt/dnsmasq/$NET_NAME.leases
Jesse Andrews228f2462011-11-05 17:36:14 -0700111 virsh net-create $vm_dir/net.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700112fi
113
114# libvirt.xml configuration
Jesse Andrews228f2462011-11-05 17:36:14 -0700115LIBVIRT_XML=$vm_dir/libvirt.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700116cat > $LIBVIRT_XML <<EOF
117<domain type='kvm'>
118 <name>$GUEST_NAME</name>
119 <memory>$GUEST_RAM</memory>
120 <os>
Jesse Andrews228f2462011-11-05 17:36:14 -0700121 <type>hvm</type>
Jesse Andrewsf5a76912011-11-05 17:47:50 -0700122 <kernel>$image_dir/kernel</kernel>
Jesse Andrews438ea572011-11-05 22:33:49 -0700123 <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 -0700124 </os>
125 <features>
126 <acpi/>
127 </features>
128 <clock offset='utc'/>
129 <vcpu>$GUEST_CORES</vcpu>
130 <devices>
131 <disk type='file'>
132 <driver type='qcow2'/>
Jesse Andrews228f2462011-11-05 17:36:14 -0700133 <source file='$vm_dir/disk'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700134 <target dev='vda' bus='virtio'/>
135 </disk>
136
137 <interface type='network'>
Anthony Young72eab222011-11-09 23:38:18 -0800138 <source network='$NET_NAME'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700139 </interface>
140
141 <!-- The order is significant here. File must be defined first -->
142 <serial type="file">
Jesse Andrews228f2462011-11-05 17:36:14 -0700143 <source path='$vm_dir/console.log'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700144 <target port='1'/>
145 </serial>
146
147 <console type='pty' tty='/dev/pts/2'>
148 <source path='/dev/pts/2'/>
149 <target port='0'/>
150 </console>
151
152 <serial type='pty'>
153 <source path='/dev/pts/2'/>
154 <target port='0'/>
155 </serial>
156
157 <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
158 </devices>
159</domain>
160EOF
161
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700162
Jesse Andrewse49f7512011-11-05 22:34:45 -0700163rm -rf $vm_dir/uec
Jesse Andrews9ed6bbd2011-11-05 22:28:46 -0700164cp -r $TOOLS_DIR/uec $vm_dir/uec
165
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700166# set metadata
167cat > $vm_dir/uec/meta-data<<EOF
168hostname: $GUEST_NAME
Jesse Andrewse3c47a32011-11-07 10:44:43 -0800169instance-id: i-hop
170instance-type: m1.ignore
Jesse Andrews7306f3b2011-11-05 23:13:34 -0700171local-hostname: $GUEST_NAME.local
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700172EOF
173
Anthony Young2838f122011-11-10 13:04:40 -0800174# set user-data
Jesse Andrews63cb9232011-11-05 23:16:53 -0700175cat > $vm_dir/uec/user-data<<EOF
Jesse Andrews446a3302011-11-05 23:36:29 -0700176#!/bin/bash
Jesse Andrewsb17c4f32011-11-06 09:25:55 -0800177# hostname needs to resolve for rabbit
Jesse Andrews6e3a4c52011-11-06 09:35:13 -0800178sed -i "s/127.0.0.1/127.0.0.1 \`hostname\`/" /etc/hosts
Jesse Andrews446a3302011-11-05 23:36:29 -0700179apt-get update
Jesse Andrewsc7f72ad2011-11-06 08:00:28 -0800180apt-get install git sudo -y
Jesse Andrews446a3302011-11-05 23:36:29 -0700181git clone https://github.com/cloudbuilders/devstack.git
182cd devstack
Jesse Andrews81881ec2011-11-06 00:22:41 -0700183git remote set-url origin `cd $TOP_DIR; git remote show origin | grep Fetch | awk '{print $3}'`
184git fetch
Jesse Andrews11416bf2011-11-06 00:32:21 -0700185git checkout `git rev-parse HEAD`
Jesse Andrews0c008952011-11-06 00:26:29 -0700186cat > localrc <<LOCAL_EOF
Jesse Andrewsc7f72ad2011-11-06 08:00:28 -0800187ROOTSLEEP=0
Jesse Andrews6b1c26e2011-11-06 00:13:30 -0700188`cat $TOP_DIR/localrc`
Jesse Andrews0c008952011-11-06 00:26:29 -0700189LOCAL_EOF
Anthony Youngb2256822011-11-10 12:57:59 -0800190EOF
191
192# Setup stack user with our key
193if [ -e ~/.ssh/id_rsa.pub ]; then
Anthony Young2838f122011-11-10 13:04:40 -0800194 cat >> $vm_dir/uec/user-data<<EOF
Anthony Youngb2256822011-11-10 12:57:59 -0800195mkdir -p /opt/stack
196useradd stack -s /bin/bash -d /opt/stack -G libvirtd || true
197echo stack:pass | chpasswd
198mkdir -p /opt/stack/.ssh
199echo `cat ~/.ssh/id_rsa.pub` > /opt/stack/.ssh/authorized_keys
200chown -R stack /opt/stack
201chmod 700 /opt/stack/.ssh
202chmod 600 /opt/stack/.ssh/authorized_keys
203
204grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
205 echo "#includedir /etc/sudoers.d" >> /etc/sudoers
206( umask 226 && echo "stack ALL=(ALL) NOPASSWD:ALL" \
207 > /etc/sudoers.d/50_stack_sh )
208EOF
209fi
210
211# Run stack.sh
Anthony Young2838f122011-11-10 13:04:40 -0800212cat >> $vm_dir/uec/user-data<<EOF
Jesse Andrews446a3302011-11-05 23:36:29 -0700213./stack.sh
Jesse Andrews63cb9232011-11-05 23:16:53 -0700214EOF
215
Jesse Andrewsee34f622011-11-05 22:41:57 -0700216# (re)start a metadata service
Jesse Andrews3ce79aa2011-11-05 22:52:20 -0700217(
218 pid=`lsof -iTCP@192.168.$GUEST_NETWORK.1:4567 -n | awk '{print $2}' | tail -1`
Jesse Andrews9645b0c2011-11-05 23:05:33 -0700219 [ -z "$pid" ] || kill -9 $pid
Jesse Andrews3ce79aa2011-11-05 22:52:20 -0700220)
Jesse Andrewsf504e282011-11-05 22:29:35 -0700221cd $vm_dir/uec
222python meta.py 192.168.$GUEST_NETWORK.1:4567 &
Jesse Andrews9ed6bbd2011-11-05 22:28:46 -0700223
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700224# Create the instance
Jesse Andrews63fa7ab2011-11-05 18:49:36 -0700225virsh create $vm_dir/libvirt.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700226
227# Tail the console log till we are done
228WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
229if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
Jesse Andrews228f2462011-11-05 17:36:14 -0700230 set +o xtrace
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700231 # Done creating the container, let's tail the log
232 echo
233 echo "============================================================="
234 echo " -- YAY! --"
235 echo "============================================================="
236 echo
237 echo "We're done launching the vm, about to start tailing the"
238 echo "stack.sh log. It will take a second or two to start."
239 echo
240 echo "Just CTRL-C at any time to stop tailing."
241
Jesse Andrews228f2462011-11-05 17:36:14 -0700242 while [ ! -e "$vm_dir/console.log" ]; do
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700243 sleep 1
244 done
245
Jesse Andrews228f2462011-11-05 17:36:14 -0700246 tail -F $vm_dir/console.log &
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700247
248 TAIL_PID=$!
249
250 function kill_tail() {
251 kill $TAIL_PID
252 exit 1
253 }
254
255 # Let Ctrl-c kill tail and exit
256 trap kill_tail SIGINT
257
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700258 echo "Waiting stack.sh to finish..."
Jesse Andrewsd55a5152011-11-06 08:16:42 -0800259 while ! egrep -q '^stack.sh (completed|failed)' $vm_dir/console.log ; do
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700260 sleep 1
261 done
262
263 set -o xtrace
264
265 kill $TAIL_PID
266
Jesse Andrews228f2462011-11-05 17:36:14 -0700267 if ! grep -q "^stack.sh completed in" $vm_dir/console.log; then
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700268 exit 1
269 fi
270 echo ""
271 echo "Finished - Zip-a-dee Doo-dah!"
272fi