blob: 614c118caaaad8ed5164f58cc05942940fd88d89 [file] [log] [blame]
Anthony Young1b7a42e2011-10-19 02:34:06 -07001#!/usr/bin/env bash
2
Anthony Youngfa4b5eb2011-10-19 11:27:02 -07003UBUNTU_VERSION=`cat /etc/lsb-release | grep CODENAME | sed 's/.*=//g'`
4if [ ! "oneiric" = "$UBUNTU_VERSION" ]; then
5 echo "This script only works with oneiric"
6 exit 1
7fi
8
Anthony Young1b7a42e2011-10-19 02:34:06 -07009# Echo commands
10set -o xtrace
11
12# Keep track of the current directory
13TOOLS_DIR=$(cd $(dirname "$0") && pwd)
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070014TOP_DIR=$TOOLS_DIR/..
Anthony Young1b7a42e2011-10-19 02:34:06 -070015
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070016# Configure the root password of the vm
Anthony Young1b7a42e2011-10-19 02:34:06 -070017ROOT_PASSWORD=${ROOT_PASSWORD:password}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070018
19# Where to store files and instances
20KVMSTACK_DIR=${KVMSTACK_DIR:-/opt/kvmstack}
21
22# Where to store images
23IMAGES_DIR=$KVMSTACK_DIR/images
24
25# Create images dir
26mkdir -p $IMAGES_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -070027
28# Move to top devstack dir
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070029cd $TOP_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -070030
31# Abort if localrc is not set
32if [ ! -e ./localrc ]; then
33 echo "You must have a localrc with ALL necessary passwords defined before proceeding."
34 echo "See stack.sh for required passwords."
35 exit 1
36fi
37
38# Source params
39source ./stackrc
40
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070041# Base image (natty by default)
42DIST_NAME=${DIST_NAME:-natty}
43IMAGE_FNAME=$DIST_NAME.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070044
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070045# Original version of built image
46BASE_IMAGE=$KVMSTACK_DIR/images/natty.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070047
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070048# Copy of base image, which we pre-install with tasty treats
49BASE_IMAGE_COPY=$IMAGES_DIR/$DIST_NAME.raw.copy
50
51# Name of our instance, used by libvirt
Anthony Young1b7a42e2011-10-19 02:34:06 -070052VM_NAME=${VM_NAME:-kvmstack}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070053
54# Mop up after previous runs
Anthony Young1b7a42e2011-10-19 02:34:06 -070055virsh destroy $VM_NAME
56
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070057# Where this vm is stored
58VM_DIR=$KVMSTACK_DIR/instances/$VM_NAME
Anthony Young1b7a42e2011-10-19 02:34:06 -070059
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070060# Create vm dir
Anthony Young1b7a42e2011-10-19 02:34:06 -070061mkdir -p $VM_DIR
62
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070063# Mount point into copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070064COPY_DIR=$VM_DIR/copy
65mkdir -p $COPY_DIR
66
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070067# Create the base image if it does not yet exist
Anthony Young1b7a42e2011-10-19 02:34:06 -070068if [ ! -e $IMAGES_DIR/$IMAGE_FNAME ]; then
69 cd $TOOLS_DIR
70 ./make_image.sh -m -r 5000 natty raw
71 mv natty.raw $BASE_IMAGE
72 cd $TOP_DIR
73fi
74
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070075# Create a copy of the base image
76if [ ! -e $BASE_IMAGE_COPY ]; then
77 cp -p $BASE_IMAGE $BASE_IMAGE_COPY
78fi
79
80# Unmount the copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070081function unmount_images() {
82 # unmount the filesystem
83 while df | grep -q $COPY_DIR; do
84 umount $COPY_DIR || echo 'ok'
85 sleep 1
86 done
87}
88
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070089# Unmount from failed runs
Anthony Young1b7a42e2011-10-19 02:34:06 -070090unmount_images
91
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070092# Ctrl-c catcher
93function kill_unmount() {
Anthony Young1b7a42e2011-10-19 02:34:06 -070094 unmount_images
95 exit 1
96}
97
Anthony Young1b7a42e2011-10-19 02:34:06 -070098# Install deps
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070099apt-get install -y --force-yes kvm libvirt-bin kpartx
Anthony Young1b7a42e2011-10-19 02:34:06 -0700100
101# Let Ctrl-c kill tail and exit
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700102trap kill_unmount SIGINT
Anthony Young1b7a42e2011-10-19 02:34:06 -0700103
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700104# Where Openstack code will live in image
Anthony Young1b7a42e2011-10-19 02:34:06 -0700105DEST=${DEST:-/opt/stack}
106
107# Mount the file system
108mount -o loop,offset=32256 $BASE_IMAGE_COPY $COPY_DIR
109
110# git clone only if directory doesn't exist already. Since ``DEST`` might not
111# be owned by the installation user, we create the directory and change the
112# ownership to the proper user.
113function git_clone {
114 if [ ! -d $2 ]; then
115 sudo mkdir $2
116 sudo chown `whoami` $2
117 git clone $1 $2
118 cd $2
119 # This checkout syntax works for both branches and tags
120 git checkout $3
121 fi
122}
123
124# Make sure that base requirements are installed
125cp /etc/resolv.conf $COPY_DIR/etc/resolv.conf
126chroot $COPY_DIR apt-get update
127chroot $COPY_DIR apt-get install -y --force-yes `cat files/apts/* | cut -d\# -f1 | egrep -v "(rabbitmq|libvirt-bin|mysql-server)"`
128chroot $COPY_DIR apt-get install -y --download-only rabbitmq-server libvirt-bin mysql-server
129chroot $COPY_DIR pip install `cat files/pips/*`
130
131# Clean out code repos if directed to do so
132if [ "$CLEAN" = "1" ]; then
133 rm -rf $COPY_DIR/$DEST
134fi
135
136# Cache openstack code
137mkdir -p $COPY_DIR/$DEST
138git_clone $NOVA_REPO $COPY_DIR/$DEST/nova $NOVA_BRANCH
139git_clone $GLANCE_REPO $COPY_DIR/$DEST/glance $GLANCE_BRANCH
140git_clone $KEYSTONE_REPO $COPY_DIR/$DESTkeystone $KEYSTONE_BRANCH
141git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
142git_clone $DASH_REPO $COPY_DIR/$DEST/dash $DASH_BRANCH $DASH_TAG
143git_clone $NOVACLIENT_REPO $COPY_DIR/$DEST/python-novaclient $NOVACLIENT_BRANCH
144git_clone $OPENSTACKX_REPO $COPY_DIR/$DEST/openstackx $OPENSTACKX_BRANCH
145git_clone $KEYSTONE_REPO $COPY_DIR/$DEST/keystone $KEYSTONE_BRANCH
146git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
147
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700148# Back to devstack
149cd $TOP_DIR
150
151# Unmount the filesystems
Anthony Young1b7a42e2011-10-19 02:34:06 -0700152unmount_images
153
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700154# Clean up old runs
155cd $VM_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -0700156rm -f $VM_DIR/disk
157
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700158# Clean up old instance data
Anthony Young1b7a42e2011-10-19 02:34:06 -0700159qemu-img create -f qcow2 -b $BASE_IMAGE_COPY disk
160
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700161# Network configuration variables
Anthony Young1b7a42e2011-10-19 02:34:06 -0700162BRIDGE=${BRIDGE:-br0}
163CONTAINER=${CONTAINER:-STACK}
164CONTAINER_IP=${CONTAINER_IP:-192.168.1.50}
165CONTAINER_CIDR=${CONTAINER_CIDR:-$CONTAINER_IP/24}
166CONTAINER_NETMASK=${CONTAINER_NETMASK:-255.255.255.0}
167CONTAINER_GATEWAY=${CONTAINER_GATEWAY:-192.168.1.1}
168CONTAINER_MAC=${CONTAINER_MAC:-02:16:3e:07:70:d7}
169
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700170# libvirt.xml configuration
Anthony Young1b7a42e2011-10-19 02:34:06 -0700171LIBVIRT_XML=libvirt.xml
172cat > $LIBVIRT_XML <<EOF
173<domain type='kvm'>
174 <name>$VM_NAME</name>
175 <memory>1524288</memory>
176 <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>
183 <vcpu>1</vcpu>
184 <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'/>
193 <mac address='$CONTAINER_MAC'/>
194 </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 Youngfa4b5eb2011-10-19 11:27:02 -0700231# Mount the instance
Anthony Young9c0fdd72011-10-19 20:22:32 -0700232qemu-nbd -c $NBD disk
233mount $NBD $ROOTFS -o offset=32256 -t ext4
Anthony Young1b7a42e2011-10-19 02:34:06 -0700234
235# Configure instance network
236INTERFACES=$ROOTFS/etc/network/interfaces
237cat > $INTERFACES <<EOF
238auto lo
239iface lo inet loopback
240
241auto eth0
242iface eth0 inet static
243 address $CONTAINER_IP
244 netmask $CONTAINER_NETMASK
245 gateway $CONTAINER_GATEWAY
246EOF
247
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700248# User configuration for the instance
Anthony Young1b7a42e2011-10-19 02:34:06 -0700249chroot $ROOTFS groupadd libvirtd
250chroot $ROOTFS useradd stack -s /bin/bash -d $DEST -G libvirtd
251cp -pr $TOOLS_DIR/.. $ROOTFS/$DEST/devstack
252echo "root:$ROOT_PASSWORD" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700253echo "stack:pass" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700254echo "stack ALL=(ALL) NOPASSWD: ALL" >> $ROOTFS/etc/sudoers
255
256# Gracefully cp only if source file/dir exists
257function cp_it {
258 if [ -e $1 ] || [ -d $1 ]; then
259 cp -pRL $1 $2
260 fi
261}
262
263# Copy over your ssh keys and env if desired
264COPYENV=${COPYENV:-1}
265if [ "$COPYENV" = "1" ]; then
266 cp_it ~/.ssh $ROOTFS/$DEST/.ssh
267 cp_it ~/.ssh/id_rsa.pub $ROOTFS/$DEST/.ssh/authorized_keys
268 cp_it ~/.gitconfig $ROOTFS/$DEST/.gitconfig
269 cp_it ~/.vimrc $ROOTFS/$DEST/.vimrc
270 cp_it ~/.bashrc $ROOTFS/$DEST/.bashrc
271fi
272
273# Configure the runner
274RUN_SH=$ROOTFS/$DEST/run.sh
275cat > $RUN_SH <<EOF
276#!/usr/bin/env bash
Anthony Young1b7a42e2011-10-19 02:34:06 -0700277
278# Kill any existing screens
279killall screen
280
281# Install and run stack.sh
282sudo apt-get update
283sudo apt-get -y --force-yes install git-core vim-nox sudo
284if [ ! -d "$DEST/devstack" ]; then
285 git clone git://github.com/cloudbuilders/devstack.git $DEST/devstack
286fi
287cd $DEST/devstack && $STACKSH_PARAMS FORCE=yes ./stack.sh > /$DEST/run.sh.log
288echo >> /$DEST/run.sh.log
289echo >> /$DEST/run.sh.log
290echo "All done! Time to start clicking." >> /$DEST/run.sh.log
Anthony Youngd51812d2011-10-19 20:09:43 -0700291cat $DEST/run.sh.log
Anthony Young1b7a42e2011-10-19 02:34:06 -0700292EOF
Anthony Young1b7a42e2011-10-19 02:34:06 -0700293chmod 755 $RUN_SH
294
295# Make runner launch on boot
296RC_LOCAL=$ROOTFS/etc/init.d/local
297cat > $RC_LOCAL <<EOF
298#!/bin/sh -e
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700299# Reboot if this is our first run to enable console log on natty :(
300if [ ! -e /root/firstlaunch ]; then
301 touch /root/firstlaunch
Anthony Youngd51812d2011-10-19 20:09:43 -0700302 reboot -f
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700303 exit 0
304fi
Anthony Young1b7a42e2011-10-19 02:34:06 -0700305su -c "$DEST/run.sh" stack
306EOF
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700307chmod +x $RC_LOCAL
308chroot $ROOTFS sudo update-rc.d local defaults 80
Anthony Young1b7a42e2011-10-19 02:34:06 -0700309
310# Make our ip address hostnames look nice at the command prompt
311echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/$DEST/.bashrc
312echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/etc/profile
313
314# Give stack ownership over $DEST so it may do the work needed
315chroot $ROOTFS chown -R stack $DEST
316
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700317# Change boot params so that we get a console log
Anthony Youngf6f52272011-10-19 02:58:18 -0700318sudo 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 -0700319sudo sed -e "s/^hiddenmenu//g" -i $ROOTFS/boot/grub/menu.lst
320#chroot $ROOTFS grub-install /dev/vda
Anthony Youngf6f52272011-10-19 02:58:18 -0700321
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700322# Unmount
323umount $ROOTFS || echo 'ok'
Anthony Young9c0fdd72011-10-19 20:22:32 -0700324qemu-nbd -d $NBD
Anthony Young1b7a42e2011-10-19 02:34:06 -0700325
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700326# Create the instance
327cd $VM_DIR && virsh create libvirt.xml
328
329# Tail the console log till we are done
Anthony Youngd51812d2011-10-19 20:09:43 -0700330WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700331if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
332 # Done creating the container, let's tail the log
333 echo
334 echo "============================================================="
335 echo " -- YAY! --"
336 echo "============================================================="
337 echo
338 echo "We're done launching the vm, about to start tailing the"
339 echo "stack.sh log. It will take a second or two to start."
340 echo
341 echo "Just CTRL-C at any time to stop tailing."
342
343 while [ ! -e "$VM_DIR/console.log" ]; do
344 sleep 1
345 done
346
347 tail -F $VM_DIR/console.log &
348
349 TAIL_PID=$!
350
351 function kill_tail() {
352 kill $TAIL_PID
353 exit 1
354 }
355
356 # Let Ctrl-c kill tail and exit
357 trap kill_tail SIGINT
358
359 echo "Waiting stack.sh to finish..."
Anthony Youngd51812d2011-10-19 20:09:43 -0700360 while ! cat $VM_DIR/console.log | grep -q 'All done' ; do
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700361 sleep 5
362 done
363
364 kill $TAIL_PID
365 echo ""
366 echo "Finished - Zip-a-dee Doo-dah!"
367fi