blob: 36457d5db11b21f1baf1433c2fb5c84f53acd6a7 [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# Where to store files and instances
23KVMSTACK_DIR=${KVMSTACK_DIR:-/opt/kvmstack}
24
25# Where to store images
26IMAGES_DIR=$KVMSTACK_DIR/images
27
28# Create images dir
29mkdir -p $IMAGES_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -070030
31# Move to top devstack dir
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070032cd $TOP_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -070033
34# Abort if localrc is not set
35if [ ! -e ./localrc ]; then
36 echo "You must have a localrc with ALL necessary passwords defined before proceeding."
37 echo "See stack.sh for required passwords."
38 exit 1
39fi
40
41# Source params
42source ./stackrc
43
Jesse Andrews7d45a0f2011-10-26 08:51:15 -070044# Configure the root password of the vm to be the same as ``ADMIN_PASSWORD``
45ROOT_PASSWORD=${ADMIN_PASSWORD:-password}
46
47
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070048# Base image (natty by default)
49DIST_NAME=${DIST_NAME:-natty}
50IMAGE_FNAME=$DIST_NAME.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070051
Dean Troyere4f030f2011-10-21 14:28:03 -050052# Name of our instance, used by libvirt
Jesse Andrews82040df2011-10-22 20:56:23 -070053GUEST_NAME=${GUEST_NAME:-kvmstack}
Dean Troyere4f030f2011-10-21 14:28:03 -050054
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070055# Original version of built image
Dean Troyerad57a3a2011-10-21 14:29:30 -050056BASE_IMAGE=$KVMSTACK_DIR/images/$DIST_NAME.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070057
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070058# Copy of base image, which we pre-install with tasty treats
Jesse Andrews82040df2011-10-22 20:56:23 -070059VM_IMAGE=$IMAGES_DIR/$DIST_NAME.$GUEST_NAME.raw
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070060
61# Mop up after previous runs
Jesse Andrews61e0a2e2011-10-24 12:47:13 -070062virsh destroy $GUEST_NAME || true
Anthony Young1b7a42e2011-10-19 02:34:06 -070063
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070064# Where this vm is stored
Jesse Andrews82040df2011-10-22 20:56:23 -070065VM_DIR=$KVMSTACK_DIR/instances/$GUEST_NAME
Anthony Young1b7a42e2011-10-19 02:34:06 -070066
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070067# Create vm dir
Anthony Young1b7a42e2011-10-19 02:34:06 -070068mkdir -p $VM_DIR
69
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070070# Mount point into copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070071COPY_DIR=$VM_DIR/copy
72mkdir -p $COPY_DIR
73
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070074# Create the base image if it does not yet exist
Anthony Young1b7a42e2011-10-19 02:34:06 -070075if [ ! -e $IMAGES_DIR/$IMAGE_FNAME ]; then
76 cd $TOOLS_DIR
Dean Troyerad57a3a2011-10-21 14:29:30 -050077 ./make_image.sh -m -r 5000 $DIST_NAME raw
78 mv $DIST_NAME.raw $BASE_IMAGE
Anthony Young1b7a42e2011-10-19 02:34:06 -070079 cd $TOP_DIR
80fi
81
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070082# Create a copy of the base image
Dean Troyerd0332912011-10-21 14:58:44 -050083if [ ! -e $VM_IMAGE ]; then
84 cp -p $BASE_IMAGE $VM_IMAGE
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070085fi
86
87# Unmount the copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070088function unmount_images() {
89 # unmount the filesystem
90 while df | grep -q $COPY_DIR; do
91 umount $COPY_DIR || echo 'ok'
92 sleep 1
93 done
94}
95
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070096# Unmount from failed runs
Anthony Young1b7a42e2011-10-19 02:34:06 -070097unmount_images
98
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070099# Ctrl-c catcher
100function kill_unmount() {
Anthony Young1b7a42e2011-10-19 02:34:06 -0700101 unmount_images
102 exit 1
103}
104
Jesse Andrews87a73e82011-10-24 17:06:58 -0700105# Install deps if needed
106dpkg -l kvm libvirt-bin kpartx || apt-get install -y --force-yes kvm libvirt-bin kpartx
Anthony Young1b7a42e2011-10-19 02:34:06 -0700107
108# Let Ctrl-c kill tail and exit
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700109trap kill_unmount SIGINT
Anthony Young1b7a42e2011-10-19 02:34:06 -0700110
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700111# Where Openstack code will live in image
Anthony Young1b7a42e2011-10-19 02:34:06 -0700112DEST=${DEST:-/opt/stack}
113
114# Mount the file system
Dean Troyerd0332912011-10-21 14:58:44 -0500115mount -o loop,offset=32256 $VM_IMAGE $COPY_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -0700116
117# git clone only if directory doesn't exist already. Since ``DEST`` might not
118# be owned by the installation user, we create the directory and change the
119# ownership to the proper user.
120function git_clone {
121 if [ ! -d $2 ]; then
122 sudo mkdir $2
123 sudo chown `whoami` $2
124 git clone $1 $2
125 cd $2
126 # This checkout syntax works for both branches and tags
127 git checkout $3
128 fi
129}
130
131# Make sure that base requirements are installed
132cp /etc/resolv.conf $COPY_DIR/etc/resolv.conf
133chroot $COPY_DIR apt-get update
134chroot $COPY_DIR apt-get install -y --force-yes `cat files/apts/* | cut -d\# -f1 | egrep -v "(rabbitmq|libvirt-bin|mysql-server)"`
135chroot $COPY_DIR apt-get install -y --download-only rabbitmq-server libvirt-bin mysql-server
136chroot $COPY_DIR pip install `cat files/pips/*`
137
138# Clean out code repos if directed to do so
139if [ "$CLEAN" = "1" ]; then
140 rm -rf $COPY_DIR/$DEST
141fi
142
143# Cache openstack code
144mkdir -p $COPY_DIR/$DEST
145git_clone $NOVA_REPO $COPY_DIR/$DEST/nova $NOVA_BRANCH
146git_clone $GLANCE_REPO $COPY_DIR/$DEST/glance $GLANCE_BRANCH
147git_clone $KEYSTONE_REPO $COPY_DIR/$DESTkeystone $KEYSTONE_BRANCH
148git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
149git_clone $DASH_REPO $COPY_DIR/$DEST/dash $DASH_BRANCH $DASH_TAG
150git_clone $NOVACLIENT_REPO $COPY_DIR/$DEST/python-novaclient $NOVACLIENT_BRANCH
151git_clone $OPENSTACKX_REPO $COPY_DIR/$DEST/openstackx $OPENSTACKX_BRANCH
152git_clone $KEYSTONE_REPO $COPY_DIR/$DEST/keystone $KEYSTONE_BRANCH
153git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
154
Anthony Youngbabb2e02011-10-20 12:32:58 -0700155# Back to devstack
156cd $TOP_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -0700157
Jesse Andrews1369c052011-10-24 12:38:13 -0700158# Unmount the filesystems
159unmount_images
160
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700161# Network configuration variables
Anthony Young1b7a42e2011-10-19 02:34:06 -0700162BRIDGE=${BRIDGE:-br0}
Jesse Andrews82040df2011-10-22 20:56:23 -0700163GUEST_IP=${GUEST_IP:-192.168.1.50}
164GUEST_CIDR=${GUEST_CIDR:-$GUEST_IP/24}
165GUEST_NETMASK=${GUEST_NETMASK:-255.255.255.0}
166GUEST_GATEWAY=${GUEST_GATEWAY:-192.168.1.1}
167GUEST_MAC=${GUEST_MAC:-"02:16:3e:07:69:`printf '%02X' $(echo $GUEST_IP | sed "s/.*\.//")`"}
168GUEST_RAM=${GUEST_RAM:-1524288}
169GUEST_CORES=${GUEST_CORES:-1}
Anthony Young1b7a42e2011-10-19 02:34:06 -0700170
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700171# libvirt.xml configuration
Jesse Andrewsec1d0312011-10-21 19:22:55 -0700172LIBVIRT_XML=$VM_DIR/libvirt.xml
Anthony Young1b7a42e2011-10-19 02:34:06 -0700173cat > $LIBVIRT_XML <<EOF
174<domain type='kvm'>
Jesse Andrews82040df2011-10-22 20:56:23 -0700175 <name>$GUEST_NAME</name>
176 <memory>$GUEST_RAM</memory>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700177 <os>
Anthony Youngd51812d2011-10-19 20:09:43 -0700178 <type>hvm</type>
179 <bootmenu enable='yes'/>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700180 </os>
181 <features>
182 <acpi/>
183 </features>
Jesse Andrews82040df2011-10-22 20:56:23 -0700184 <vcpu>$GUEST_CORES</vcpu>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700185 <devices>
186 <disk type='file'>
187 <driver type='qcow2'/>
188 <source file='$VM_DIR/disk'/>
189 <target dev='vda' bus='virtio'/>
190 </disk>
191
192 <interface type='bridge'>
193 <source bridge='$BRIDGE'/>
Jesse Andrews82040df2011-10-22 20:56:23 -0700194 <mac address='$GUEST_MAC'/>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700195 </interface>
196
197 <!-- The order is significant here. File must be defined first -->
198 <serial type="file">
199 <source path='$VM_DIR/console.log'/>
200 <target port='1'/>
201 </serial>
202
203 <console type='pty' tty='/dev/pts/2'>
204 <source path='/dev/pts/2'/>
205 <target port='0'/>
206 </console>
207
208 <serial type='pty'>
209 <source path='/dev/pts/2'/>
210 <target port='0'/>
211 </serial>
212
213 <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
214 </devices>
215</domain>
216EOF
217
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700218# Mount point for instance fs
Anthony Young1b7a42e2011-10-19 02:34:06 -0700219ROOTFS=$VM_DIR/root
220mkdir -p $ROOTFS
221
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700222# Make sure we have nbd-ness
Anthony Young1b7a42e2011-10-19 02:34:06 -0700223modprobe nbd max_part=63
224
Anthony Young9c0fdd72011-10-19 20:22:32 -0700225# Which NBD device to use?
226NBD=${NBD:-/dev/nbd5}
227
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700228# Clean up from previous runs
Anthony Young1b7a42e2011-10-19 02:34:06 -0700229umount $ROOTFS || echo 'ok'
Anthony Young9c0fdd72011-10-19 20:22:32 -0700230qemu-nbd -d $NBD || echo 'ok'
Anthony Young1b7a42e2011-10-19 02:34:06 -0700231
Anthony Youngbabb2e02011-10-20 12:32:58 -0700232# Clean up old runs
233cd $VM_DIR
234rm -f $VM_DIR/disk
235
236# Create our instance fs
Dean Troyerd0332912011-10-21 14:58:44 -0500237qemu-img create -f qcow2 -b $VM_IMAGE disk
Anthony Youngbabb2e02011-10-20 12:32:58 -0700238
Anthony Young68565362011-10-24 23:20:12 -0700239# Connect our nbd and wait till it is mountable
Anthony Young9c0fdd72011-10-19 20:22:32 -0700240qemu-nbd -c $NBD disk
Anthony Young68565362011-10-24 23:20:12 -0700241NBD_DEV=`basename $NBD`
242if ! timeout 60 sh -c "while ! [ -e /sys/block/$NBD_DEV/pid ]; do sleep 1; done"; then
243 echo "Couldn't connect $NBD"
244 exit 1
245fi
Anthony Young69937462011-10-20 12:55:46 -0700246
247# Mount the instance
Anthony Young9c0fdd72011-10-19 20:22:32 -0700248mount $NBD $ROOTFS -o offset=32256 -t ext4
Anthony Young1b7a42e2011-10-19 02:34:06 -0700249
250# Configure instance network
251INTERFACES=$ROOTFS/etc/network/interfaces
252cat > $INTERFACES <<EOF
253auto lo
254iface lo inet loopback
255
256auto eth0
257iface eth0 inet static
Jesse Andrews82040df2011-10-22 20:56:23 -0700258 address $GUEST_IP
259 netmask $GUEST_NETMASK
260 gateway $GUEST_GATEWAY
Anthony Young1b7a42e2011-10-19 02:34:06 -0700261EOF
262
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700263# User configuration for the instance
Jesse Andrews7d45a0f2011-10-26 08:51:15 -0700264chroot $ROOTFS groupadd libvirtd || true
Anthony Young1b7a42e2011-10-19 02:34:06 -0700265chroot $ROOTFS useradd stack -s /bin/bash -d $DEST -G libvirtd
266cp -pr $TOOLS_DIR/.. $ROOTFS/$DEST/devstack
267echo "root:$ROOT_PASSWORD" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700268echo "stack:pass" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700269echo "stack ALL=(ALL) NOPASSWD: ALL" >> $ROOTFS/etc/sudoers
270
271# Gracefully cp only if source file/dir exists
272function cp_it {
273 if [ -e $1 ] || [ -d $1 ]; then
274 cp -pRL $1 $2
275 fi
276}
277
278# Copy over your ssh keys and env if desired
279COPYENV=${COPYENV:-1}
280if [ "$COPYENV" = "1" ]; then
281 cp_it ~/.ssh $ROOTFS/$DEST/.ssh
282 cp_it ~/.ssh/id_rsa.pub $ROOTFS/$DEST/.ssh/authorized_keys
283 cp_it ~/.gitconfig $ROOTFS/$DEST/.gitconfig
284 cp_it ~/.vimrc $ROOTFS/$DEST/.vimrc
285 cp_it ~/.bashrc $ROOTFS/$DEST/.bashrc
286fi
287
Jesse Andrews60657722011-10-25 23:41:59 -0700288# pre-cache uec images
289for image_url in ${IMAGE_URLS//,/ }; do
290 IMAGE_FNAME=`basename "$image_url"`
291 if [ ! -f $IMAGES_DIR/$IMAGE_FNAME ]; then
292 wget -c $image_url -O $IMAGES_DIR/$IMAGE_FNAME
293 fi
Jesse Andrews00dcc062011-10-25 23:51:43 -0700294 cp $IMAGES_DIR/$IMAGE_FNAME $ROOTFS/$DEST/devstack/files
Jesse Andrews9173d062011-10-25 23:43:03 -0700295done
Jesse Andrews60657722011-10-25 23:41:59 -0700296
Anthony Young1b7a42e2011-10-19 02:34:06 -0700297# Configure the runner
298RUN_SH=$ROOTFS/$DEST/run.sh
299cat > $RUN_SH <<EOF
300#!/usr/bin/env bash
Anthony Young1b7a42e2011-10-19 02:34:06 -0700301
302# Kill any existing screens
303killall screen
304
305# Install and run stack.sh
306sudo apt-get update
307sudo apt-get -y --force-yes install git-core vim-nox sudo
308if [ ! -d "$DEST/devstack" ]; then
309 git clone git://github.com/cloudbuilders/devstack.git $DEST/devstack
310fi
311cd $DEST/devstack && $STACKSH_PARAMS FORCE=yes ./stack.sh > /$DEST/run.sh.log
312echo >> /$DEST/run.sh.log
313echo >> /$DEST/run.sh.log
314echo "All done! Time to start clicking." >> /$DEST/run.sh.log
Anthony Youngd51812d2011-10-19 20:09:43 -0700315cat $DEST/run.sh.log
Anthony Young1b7a42e2011-10-19 02:34:06 -0700316EOF
Anthony Young1b7a42e2011-10-19 02:34:06 -0700317chmod 755 $RUN_SH
318
319# Make runner launch on boot
320RC_LOCAL=$ROOTFS/etc/init.d/local
321cat > $RC_LOCAL <<EOF
322#!/bin/sh -e
Dean Troyerad57a3a2011-10-21 14:29:30 -0500323# Reboot if this is our first run to enable console log on $DIST_NAME :(
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700324if [ ! -e /root/firstlaunch ]; then
325 touch /root/firstlaunch
Anthony Youngd51812d2011-10-19 20:09:43 -0700326 reboot -f
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700327 exit 0
328fi
Anthony Young1b7a42e2011-10-19 02:34:06 -0700329su -c "$DEST/run.sh" stack
330EOF
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700331chmod +x $RC_LOCAL
332chroot $ROOTFS sudo update-rc.d local defaults 80
Anthony Young1b7a42e2011-10-19 02:34:06 -0700333
334# Make our ip address hostnames look nice at the command prompt
335echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/$DEST/.bashrc
336echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/etc/profile
337
338# Give stack ownership over $DEST so it may do the work needed
339chroot $ROOTFS chown -R stack $DEST
340
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700341# Change boot params so that we get a console log
Anthony Youngf6f52272011-10-19 02:58:18 -0700342sudo 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 -0700343sudo sed -e "s/^hiddenmenu//g" -i $ROOTFS/boot/grub/menu.lst
344#chroot $ROOTFS grub-install /dev/vda
Anthony Youngf6f52272011-10-19 02:58:18 -0700345
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700346# Unmount
347umount $ROOTFS || echo 'ok'
Anthony Young9c0fdd72011-10-19 20:22:32 -0700348qemu-nbd -d $NBD
Anthony Young1b7a42e2011-10-19 02:34:06 -0700349
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700350# Create the instance
351cd $VM_DIR && virsh create libvirt.xml
352
353# Tail the console log till we are done
Anthony Youngd51812d2011-10-19 20:09:43 -0700354WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700355if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
356 # Done creating the container, let's tail the log
357 echo
358 echo "============================================================="
359 echo " -- YAY! --"
360 echo "============================================================="
361 echo
362 echo "We're done launching the vm, about to start tailing the"
363 echo "stack.sh log. It will take a second or two to start."
364 echo
365 echo "Just CTRL-C at any time to stop tailing."
366
367 while [ ! -e "$VM_DIR/console.log" ]; do
368 sleep 1
369 done
370
371 tail -F $VM_DIR/console.log &
372
373 TAIL_PID=$!
374
375 function kill_tail() {
376 kill $TAIL_PID
377 exit 1
378 }
Vishvananda Ishaya9b353672011-10-20 10:07:10 -0700379
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700380 # Let Ctrl-c kill tail and exit
381 trap kill_tail SIGINT
382
383 echo "Waiting stack.sh to finish..."
Anthony Youngd51812d2011-10-19 20:09:43 -0700384 while ! cat $VM_DIR/console.log | grep -q 'All done' ; do
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700385 sleep 5
386 done
387
388 kill $TAIL_PID
Jesse Andrews381591a2011-10-24 22:25:16 -0700389
390 if grep -q "stack.sh failed" $VM_DIR/console.log; then
391 exit 1
392 fi
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700393 echo ""
394 echo "Finished - Zip-a-dee Doo-dah!"
395fi