blob: 32c7bf660594f3e84877ab495da18264b294f7b0 [file] [log] [blame]
Anthony Young1b7a42e2011-10-19 02:34:06 -07001#!/usr/bin/env bash
2
Jesse Andrews4b8ab922011-10-24 12:42:43 -07003# exit on error to stop unexpected errors
4set -o errexit
5
Anthony Young3ee09ec2011-10-19 20:35:04 -07006# Make sure that we have the proper version of ubuntu
Anthony Youngfa4b5eb2011-10-19 11:27:02 -07007UBUNTU_VERSION=`cat /etc/lsb-release | grep CODENAME | sed 's/.*=//g'`
8if [ ! "oneiric" = "$UBUNTU_VERSION" ]; then
Anthony Young3ee09ec2011-10-19 20:35:04 -07009 if [ ! "natty" = "$UBUNTU_VERSION" ]; then
10 echo "This script only works with oneiric and natty"
11 exit 1
12 fi
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070013fi
14
Anthony Young1b7a42e2011-10-19 02:34:06 -070015# Echo commands
16set -o xtrace
17
18# Keep track of the current directory
19TOOLS_DIR=$(cd $(dirname "$0") && pwd)
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070020TOP_DIR=$TOOLS_DIR/..
Anthony Young1b7a42e2011-10-19 02:34:06 -070021
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070022# Configure the root password of the vm
Jesse Andrewsb169b632011-10-24 12:46:01 -070023ROOT_PASSWORD=${ROOT_PASSWORD:-password}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070024
25# Where to store files and instances
26KVMSTACK_DIR=${KVMSTACK_DIR:-/opt/kvmstack}
27
28# Where to store images
29IMAGES_DIR=$KVMSTACK_DIR/images
30
31# Create images dir
32mkdir -p $IMAGES_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -070033
34# Move to top devstack dir
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070035cd $TOP_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -070036
37# Abort if localrc is not set
38if [ ! -e ./localrc ]; then
39 echo "You must have a localrc with ALL necessary passwords defined before proceeding."
40 echo "See stack.sh for required passwords."
41 exit 1
42fi
43
44# Source params
45source ./stackrc
46
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070047# Base image (natty by default)
48DIST_NAME=${DIST_NAME:-natty}
49IMAGE_FNAME=$DIST_NAME.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070050
Dean Troyere4f030f2011-10-21 14:28:03 -050051# Name of our instance, used by libvirt
Jesse Andrews82040df2011-10-22 20:56:23 -070052GUEST_NAME=${GUEST_NAME:-kvmstack}
Dean Troyere4f030f2011-10-21 14:28:03 -050053
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070054# Original version of built image
Dean Troyerad57a3a2011-10-21 14:29:30 -050055BASE_IMAGE=$KVMSTACK_DIR/images/$DIST_NAME.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070056
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070057# Copy of base image, which we pre-install with tasty treats
Jesse Andrews82040df2011-10-22 20:56:23 -070058VM_IMAGE=$IMAGES_DIR/$DIST_NAME.$GUEST_NAME.raw
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070059
60# Mop up after previous runs
Jesse Andrews61e0a2e2011-10-24 12:47:13 -070061virsh destroy $GUEST_NAME || true
Anthony Young1b7a42e2011-10-19 02:34:06 -070062
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070063# Where this vm is stored
Jesse Andrews82040df2011-10-22 20:56:23 -070064VM_DIR=$KVMSTACK_DIR/instances/$GUEST_NAME
Anthony Young1b7a42e2011-10-19 02:34:06 -070065
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070066# Create vm dir
Anthony Young1b7a42e2011-10-19 02:34:06 -070067mkdir -p $VM_DIR
68
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070069# Mount point into copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070070COPY_DIR=$VM_DIR/copy
71mkdir -p $COPY_DIR
72
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070073# Create the base image if it does not yet exist
Anthony Young1b7a42e2011-10-19 02:34:06 -070074if [ ! -e $IMAGES_DIR/$IMAGE_FNAME ]; then
75 cd $TOOLS_DIR
Dean Troyerad57a3a2011-10-21 14:29:30 -050076 ./make_image.sh -m -r 5000 $DIST_NAME raw
77 mv $DIST_NAME.raw $BASE_IMAGE
Anthony Young1b7a42e2011-10-19 02:34:06 -070078 cd $TOP_DIR
79fi
80
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070081# Create a copy of the base image
Dean Troyerd0332912011-10-21 14:58:44 -050082if [ ! -e $VM_IMAGE ]; then
83 cp -p $BASE_IMAGE $VM_IMAGE
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070084fi
85
86# Unmount the copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070087function unmount_images() {
88 # unmount the filesystem
89 while df | grep -q $COPY_DIR; do
90 umount $COPY_DIR || echo 'ok'
91 sleep 1
92 done
93}
94
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070095# Unmount from failed runs
Anthony Young1b7a42e2011-10-19 02:34:06 -070096unmount_images
97
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070098# Ctrl-c catcher
99function kill_unmount() {
Anthony Young1b7a42e2011-10-19 02:34:06 -0700100 unmount_images
101 exit 1
102}
103
Jesse Andrews87a73e82011-10-24 17:06:58 -0700104# Install deps if needed
105dpkg -l kvm libvirt-bin kpartx || apt-get install -y --force-yes kvm libvirt-bin kpartx
Anthony Young1b7a42e2011-10-19 02:34:06 -0700106
107# Let Ctrl-c kill tail and exit
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700108trap kill_unmount SIGINT
Anthony Young1b7a42e2011-10-19 02:34:06 -0700109
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700110# Where Openstack code will live in image
Anthony Young1b7a42e2011-10-19 02:34:06 -0700111DEST=${DEST:-/opt/stack}
112
113# Mount the file system
Dean Troyerd0332912011-10-21 14:58:44 -0500114mount -o loop,offset=32256 $VM_IMAGE $COPY_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -0700115
116# git clone only if directory doesn't exist already. Since ``DEST`` might not
117# be owned by the installation user, we create the directory and change the
118# ownership to the proper user.
119function git_clone {
120 if [ ! -d $2 ]; then
121 sudo mkdir $2
122 sudo chown `whoami` $2
123 git clone $1 $2
124 cd $2
125 # This checkout syntax works for both branches and tags
126 git checkout $3
127 fi
128}
129
130# Make sure that base requirements are installed
131cp /etc/resolv.conf $COPY_DIR/etc/resolv.conf
132chroot $COPY_DIR apt-get update
133chroot $COPY_DIR apt-get install -y --force-yes `cat files/apts/* | cut -d\# -f1 | egrep -v "(rabbitmq|libvirt-bin|mysql-server)"`
134chroot $COPY_DIR apt-get install -y --download-only rabbitmq-server libvirt-bin mysql-server
135chroot $COPY_DIR pip install `cat files/pips/*`
136
137# Clean out code repos if directed to do so
138if [ "$CLEAN" = "1" ]; then
139 rm -rf $COPY_DIR/$DEST
140fi
141
142# Cache openstack code
143mkdir -p $COPY_DIR/$DEST
144git_clone $NOVA_REPO $COPY_DIR/$DEST/nova $NOVA_BRANCH
145git_clone $GLANCE_REPO $COPY_DIR/$DEST/glance $GLANCE_BRANCH
146git_clone $KEYSTONE_REPO $COPY_DIR/$DESTkeystone $KEYSTONE_BRANCH
147git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
148git_clone $DASH_REPO $COPY_DIR/$DEST/dash $DASH_BRANCH $DASH_TAG
149git_clone $NOVACLIENT_REPO $COPY_DIR/$DEST/python-novaclient $NOVACLIENT_BRANCH
150git_clone $OPENSTACKX_REPO $COPY_DIR/$DEST/openstackx $OPENSTACKX_BRANCH
151git_clone $KEYSTONE_REPO $COPY_DIR/$DEST/keystone $KEYSTONE_BRANCH
152git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
153
Anthony Youngbabb2e02011-10-20 12:32:58 -0700154# Back to devstack
155cd $TOP_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -0700156
Jesse Andrews1369c052011-10-24 12:38:13 -0700157# Unmount the filesystems
158unmount_images
159
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700160# Network configuration variables
Anthony Young1b7a42e2011-10-19 02:34:06 -0700161BRIDGE=${BRIDGE:-br0}
Jesse Andrews82040df2011-10-22 20:56:23 -0700162GUEST_IP=${GUEST_IP:-192.168.1.50}
163GUEST_CIDR=${GUEST_CIDR:-$GUEST_IP/24}
164GUEST_NETMASK=${GUEST_NETMASK:-255.255.255.0}
165GUEST_GATEWAY=${GUEST_GATEWAY:-192.168.1.1}
166GUEST_MAC=${GUEST_MAC:-"02:16:3e:07:69:`printf '%02X' $(echo $GUEST_IP | sed "s/.*\.//")`"}
167GUEST_RAM=${GUEST_RAM:-1524288}
168GUEST_CORES=${GUEST_CORES:-1}
Anthony Young1b7a42e2011-10-19 02:34:06 -0700169
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700170# libvirt.xml configuration
Jesse Andrewsec1d0312011-10-21 19:22:55 -0700171LIBVIRT_XML=$VM_DIR/libvirt.xml
Anthony Young1b7a42e2011-10-19 02:34:06 -0700172cat > $LIBVIRT_XML <<EOF
173<domain type='kvm'>
Jesse Andrews82040df2011-10-22 20:56:23 -0700174 <name>$GUEST_NAME</name>
175 <memory>$GUEST_RAM</memory>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700176 <os>
Anthony Youngd51812d2011-10-19 20:09:43 -0700177 <type>hvm</type>
178 <bootmenu enable='yes'/>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700179 </os>
180 <features>
181 <acpi/>
182 </features>
Jesse Andrews82040df2011-10-22 20:56:23 -0700183 <vcpu>$GUEST_CORES</vcpu>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700184 <devices>
185 <disk type='file'>
186 <driver type='qcow2'/>
187 <source file='$VM_DIR/disk'/>
188 <target dev='vda' bus='virtio'/>
189 </disk>
190
191 <interface type='bridge'>
192 <source bridge='$BRIDGE'/>
Jesse Andrews82040df2011-10-22 20:56:23 -0700193 <mac address='$GUEST_MAC'/>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700194 </interface>
195
196 <!-- The order is significant here. File must be defined first -->
197 <serial type="file">
198 <source path='$VM_DIR/console.log'/>
199 <target port='1'/>
200 </serial>
201
202 <console type='pty' tty='/dev/pts/2'>
203 <source path='/dev/pts/2'/>
204 <target port='0'/>
205 </console>
206
207 <serial type='pty'>
208 <source path='/dev/pts/2'/>
209 <target port='0'/>
210 </serial>
211
212 <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
213 </devices>
214</domain>
215EOF
216
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700217# Mount point for instance fs
Anthony Young1b7a42e2011-10-19 02:34:06 -0700218ROOTFS=$VM_DIR/root
219mkdir -p $ROOTFS
220
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700221# Make sure we have nbd-ness
Anthony Young1b7a42e2011-10-19 02:34:06 -0700222modprobe nbd max_part=63
223
Anthony Young9c0fdd72011-10-19 20:22:32 -0700224# Which NBD device to use?
225NBD=${NBD:-/dev/nbd5}
226
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700227# Clean up from previous runs
Anthony Young1b7a42e2011-10-19 02:34:06 -0700228umount $ROOTFS || echo 'ok'
Anthony Young9c0fdd72011-10-19 20:22:32 -0700229qemu-nbd -d $NBD || echo 'ok'
Anthony Young1b7a42e2011-10-19 02:34:06 -0700230
Anthony Youngbabb2e02011-10-20 12:32:58 -0700231# Clean up old runs
232cd $VM_DIR
233rm -f $VM_DIR/disk
234
235# Create our instance fs
Dean Troyerd0332912011-10-21 14:58:44 -0500236qemu-img create -f qcow2 -b $VM_IMAGE disk
Anthony Youngbabb2e02011-10-20 12:32:58 -0700237
Anthony Young68565362011-10-24 23:20:12 -0700238# Connect our nbd and wait till it is mountable
Anthony Young9c0fdd72011-10-19 20:22:32 -0700239qemu-nbd -c $NBD disk
Anthony Young68565362011-10-24 23:20:12 -0700240NBD_DEV=`basename $NBD`
241if ! timeout 60 sh -c "while ! [ -e /sys/block/$NBD_DEV/pid ]; do sleep 1; done"; then
242 echo "Couldn't connect $NBD"
243 exit 1
244fi
Anthony Young69937462011-10-20 12:55:46 -0700245
246# Mount the instance
Anthony Young9c0fdd72011-10-19 20:22:32 -0700247mount $NBD $ROOTFS -o offset=32256 -t ext4
Anthony Young1b7a42e2011-10-19 02:34:06 -0700248
249# Configure instance network
250INTERFACES=$ROOTFS/etc/network/interfaces
251cat > $INTERFACES <<EOF
252auto lo
253iface lo inet loopback
254
255auto eth0
256iface eth0 inet static
Jesse Andrews82040df2011-10-22 20:56:23 -0700257 address $GUEST_IP
258 netmask $GUEST_NETMASK
259 gateway $GUEST_GATEWAY
Anthony Young1b7a42e2011-10-19 02:34:06 -0700260EOF
261
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700262# User configuration for the instance
Anthony Young1b7a42e2011-10-19 02:34:06 -0700263chroot $ROOTFS groupadd libvirtd
264chroot $ROOTFS useradd stack -s /bin/bash -d $DEST -G libvirtd
265cp -pr $TOOLS_DIR/.. $ROOTFS/$DEST/devstack
266echo "root:$ROOT_PASSWORD" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700267echo "stack:pass" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700268echo "stack ALL=(ALL) NOPASSWD: ALL" >> $ROOTFS/etc/sudoers
269
270# Gracefully cp only if source file/dir exists
271function cp_it {
272 if [ -e $1 ] || [ -d $1 ]; then
273 cp -pRL $1 $2
274 fi
275}
276
277# Copy over your ssh keys and env if desired
278COPYENV=${COPYENV:-1}
279if [ "$COPYENV" = "1" ]; then
280 cp_it ~/.ssh $ROOTFS/$DEST/.ssh
281 cp_it ~/.ssh/id_rsa.pub $ROOTFS/$DEST/.ssh/authorized_keys
282 cp_it ~/.gitconfig $ROOTFS/$DEST/.gitconfig
283 cp_it ~/.vimrc $ROOTFS/$DEST/.vimrc
284 cp_it ~/.bashrc $ROOTFS/$DEST/.bashrc
285fi
286
287# Configure the runner
288RUN_SH=$ROOTFS/$DEST/run.sh
289cat > $RUN_SH <<EOF
290#!/usr/bin/env bash
Anthony Young1b7a42e2011-10-19 02:34:06 -0700291
292# Kill any existing screens
293killall screen
294
295# Install and run stack.sh
296sudo apt-get update
297sudo apt-get -y --force-yes install git-core vim-nox sudo
298if [ ! -d "$DEST/devstack" ]; then
299 git clone git://github.com/cloudbuilders/devstack.git $DEST/devstack
300fi
301cd $DEST/devstack && $STACKSH_PARAMS FORCE=yes ./stack.sh > /$DEST/run.sh.log
302echo >> /$DEST/run.sh.log
303echo >> /$DEST/run.sh.log
304echo "All done! Time to start clicking." >> /$DEST/run.sh.log
Anthony Youngd51812d2011-10-19 20:09:43 -0700305cat $DEST/run.sh.log
Anthony Young1b7a42e2011-10-19 02:34:06 -0700306EOF
Anthony Young1b7a42e2011-10-19 02:34:06 -0700307chmod 755 $RUN_SH
308
309# Make runner launch on boot
310RC_LOCAL=$ROOTFS/etc/init.d/local
311cat > $RC_LOCAL <<EOF
312#!/bin/sh -e
Dean Troyerad57a3a2011-10-21 14:29:30 -0500313# Reboot if this is our first run to enable console log on $DIST_NAME :(
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700314if [ ! -e /root/firstlaunch ]; then
315 touch /root/firstlaunch
Anthony Youngd51812d2011-10-19 20:09:43 -0700316 reboot -f
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700317 exit 0
318fi
Anthony Young1b7a42e2011-10-19 02:34:06 -0700319su -c "$DEST/run.sh" stack
320EOF
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700321chmod +x $RC_LOCAL
322chroot $ROOTFS sudo update-rc.d local defaults 80
Anthony Young1b7a42e2011-10-19 02:34:06 -0700323
324# Make our ip address hostnames look nice at the command prompt
325echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/$DEST/.bashrc
326echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/etc/profile
327
328# Give stack ownership over $DEST so it may do the work needed
329chroot $ROOTFS chown -R stack $DEST
330
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700331# Change boot params so that we get a console log
Anthony Youngf6f52272011-10-19 02:58:18 -0700332sudo sed -e "s/quiet splash/splash console=ttyS0 console=ttyS1,19200n8/g" -i $ROOTFS/boot/grub/menu.lst
Anthony Youngd51812d2011-10-19 20:09:43 -0700333sudo sed -e "s/^hiddenmenu//g" -i $ROOTFS/boot/grub/menu.lst
334#chroot $ROOTFS grub-install /dev/vda
Anthony Youngf6f52272011-10-19 02:58:18 -0700335
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700336# Unmount
337umount $ROOTFS || echo 'ok'
Anthony Young9c0fdd72011-10-19 20:22:32 -0700338qemu-nbd -d $NBD
Anthony Young1b7a42e2011-10-19 02:34:06 -0700339
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700340# Create the instance
341cd $VM_DIR && virsh create libvirt.xml
342
343# Tail the console log till we are done
Anthony Youngd51812d2011-10-19 20:09:43 -0700344WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700345if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
346 # Done creating the container, let's tail the log
347 echo
348 echo "============================================================="
349 echo " -- YAY! --"
350 echo "============================================================="
351 echo
352 echo "We're done launching the vm, about to start tailing the"
353 echo "stack.sh log. It will take a second or two to start."
354 echo
355 echo "Just CTRL-C at any time to stop tailing."
356
357 while [ ! -e "$VM_DIR/console.log" ]; do
358 sleep 1
359 done
360
361 tail -F $VM_DIR/console.log &
362
363 TAIL_PID=$!
364
365 function kill_tail() {
366 kill $TAIL_PID
367 exit 1
368 }
Vishvananda Ishaya9b353672011-10-20 10:07:10 -0700369
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700370 # Let Ctrl-c kill tail and exit
371 trap kill_tail SIGINT
372
373 echo "Waiting stack.sh to finish..."
Anthony Youngd51812d2011-10-19 20:09:43 -0700374 while ! cat $VM_DIR/console.log | grep -q 'All done' ; do
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700375 sleep 5
376 done
377
378 kill $TAIL_PID
Jesse Andrews381591a2011-10-24 22:25:16 -0700379
380 if grep -q "stack.sh failed" $VM_DIR/console.log; then
381 exit 1
382 fi
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700383 echo ""
384 echo "Finished - Zip-a-dee Doo-dah!"
385fi