blob: 59ed649c49388d7c1eccb730feee2a55345b7c83 [file] [log] [blame]
Anthony Young1b7a42e2011-10-19 02:34:06 -07001#!/usr/bin/env bash
2
Anthony Young3ee09ec2011-10-19 20:35:04 -07003# Make sure that we have the proper version of ubuntu
Anthony Youngfa4b5eb2011-10-19 11:27:02 -07004UBUNTU_VERSION=`cat /etc/lsb-release | grep CODENAME | sed 's/.*=//g'`
5if [ ! "oneiric" = "$UBUNTU_VERSION" ]; then
Anthony Young3ee09ec2011-10-19 20:35:04 -07006 if [ ! "natty" = "$UBUNTU_VERSION" ]; then
7 echo "This script only works with oneiric and natty"
8 exit 1
9 fi
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070010fi
11
Anthony Young1b7a42e2011-10-19 02:34:06 -070012# Echo commands
13set -o xtrace
14
15# Keep track of the current directory
16TOOLS_DIR=$(cd $(dirname "$0") && pwd)
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070017TOP_DIR=$TOOLS_DIR/..
Anthony Young1b7a42e2011-10-19 02:34:06 -070018
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070019# Configure the root password of the vm
Anthony Young1b7a42e2011-10-19 02:34:06 -070020ROOT_PASSWORD=${ROOT_PASSWORD:password}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070021
22# 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
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070044# Base image (natty by default)
45DIST_NAME=${DIST_NAME:-natty}
46IMAGE_FNAME=$DIST_NAME.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070047
Dean Troyere4f030f2011-10-21 14:28:03 -050048# Name of our instance, used by libvirt
Jesse Andrews82040df2011-10-22 20:56:23 -070049GUEST_NAME=${GUEST_NAME:-kvmstack}
Dean Troyere4f030f2011-10-21 14:28:03 -050050
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070051# Original version of built image
Dean Troyerad57a3a2011-10-21 14:29:30 -050052BASE_IMAGE=$KVMSTACK_DIR/images/$DIST_NAME.raw
Anthony Young1b7a42e2011-10-19 02:34:06 -070053
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070054# Copy of base image, which we pre-install with tasty treats
Jesse Andrews82040df2011-10-22 20:56:23 -070055VM_IMAGE=$IMAGES_DIR/$DIST_NAME.$GUEST_NAME.raw
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070056
57# Mop up after previous runs
Jesse Andrews82040df2011-10-22 20:56:23 -070058virsh destroy $GUEST_NAME
Anthony Young1b7a42e2011-10-19 02:34:06 -070059
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070060# Where this vm is stored
Jesse Andrews82040df2011-10-22 20:56:23 -070061VM_DIR=$KVMSTACK_DIR/instances/$GUEST_NAME
Anthony Young1b7a42e2011-10-19 02:34:06 -070062
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070063# Create vm dir
Anthony Young1b7a42e2011-10-19 02:34:06 -070064mkdir -p $VM_DIR
65
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070066# Mount point into copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070067COPY_DIR=$VM_DIR/copy
68mkdir -p $COPY_DIR
69
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070070# Create the base image if it does not yet exist
Anthony Young1b7a42e2011-10-19 02:34:06 -070071if [ ! -e $IMAGES_DIR/$IMAGE_FNAME ]; then
72 cd $TOOLS_DIR
Dean Troyerad57a3a2011-10-21 14:29:30 -050073 ./make_image.sh -m -r 5000 $DIST_NAME raw
74 mv $DIST_NAME.raw $BASE_IMAGE
Anthony Young1b7a42e2011-10-19 02:34:06 -070075 cd $TOP_DIR
76fi
77
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070078# Create a copy of the base image
Dean Troyerd0332912011-10-21 14:58:44 -050079if [ ! -e $VM_IMAGE ]; then
80 cp -p $BASE_IMAGE $VM_IMAGE
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070081fi
82
83# Unmount the copied base image
Anthony Young1b7a42e2011-10-19 02:34:06 -070084function unmount_images() {
85 # unmount the filesystem
86 while df | grep -q $COPY_DIR; do
87 umount $COPY_DIR || echo 'ok'
88 sleep 1
89 done
90}
91
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070092# Unmount from failed runs
Anthony Young1b7a42e2011-10-19 02:34:06 -070093unmount_images
94
Anthony Youngfa4b5eb2011-10-19 11:27:02 -070095# Ctrl-c catcher
96function kill_unmount() {
Anthony Young1b7a42e2011-10-19 02:34:06 -070097 unmount_images
98 exit 1
99}
100
Anthony Young1b7a42e2011-10-19 02:34:06 -0700101# Install deps
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700102apt-get install -y --force-yes kvm libvirt-bin kpartx
Anthony Young1b7a42e2011-10-19 02:34:06 -0700103
104# Let Ctrl-c kill tail and exit
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700105trap kill_unmount SIGINT
Anthony Young1b7a42e2011-10-19 02:34:06 -0700106
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700107# Where Openstack code will live in image
Anthony Young1b7a42e2011-10-19 02:34:06 -0700108DEST=${DEST:-/opt/stack}
109
110# Mount the file system
Dean Troyerd0332912011-10-21 14:58:44 -0500111mount -o loop,offset=32256 $VM_IMAGE $COPY_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -0700112
113# git clone only if directory doesn't exist already. Since ``DEST`` might not
114# be owned by the installation user, we create the directory and change the
115# ownership to the proper user.
116function git_clone {
117 if [ ! -d $2 ]; then
118 sudo mkdir $2
119 sudo chown `whoami` $2
120 git clone $1 $2
121 cd $2
122 # This checkout syntax works for both branches and tags
123 git checkout $3
124 fi
125}
126
127# Make sure that base requirements are installed
128cp /etc/resolv.conf $COPY_DIR/etc/resolv.conf
129chroot $COPY_DIR apt-get update
130chroot $COPY_DIR apt-get install -y --force-yes `cat files/apts/* | cut -d\# -f1 | egrep -v "(rabbitmq|libvirt-bin|mysql-server)"`
131chroot $COPY_DIR apt-get install -y --download-only rabbitmq-server libvirt-bin mysql-server
132chroot $COPY_DIR pip install `cat files/pips/*`
133
134# Clean out code repos if directed to do so
135if [ "$CLEAN" = "1" ]; then
136 rm -rf $COPY_DIR/$DEST
137fi
138
139# Cache openstack code
140mkdir -p $COPY_DIR/$DEST
141git_clone $NOVA_REPO $COPY_DIR/$DEST/nova $NOVA_BRANCH
142git_clone $GLANCE_REPO $COPY_DIR/$DEST/glance $GLANCE_BRANCH
143git_clone $KEYSTONE_REPO $COPY_DIR/$DESTkeystone $KEYSTONE_BRANCH
144git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
145git_clone $DASH_REPO $COPY_DIR/$DEST/dash $DASH_BRANCH $DASH_TAG
146git_clone $NOVACLIENT_REPO $COPY_DIR/$DEST/python-novaclient $NOVACLIENT_BRANCH
147git_clone $OPENSTACKX_REPO $COPY_DIR/$DEST/openstackx $OPENSTACKX_BRANCH
148git_clone $KEYSTONE_REPO $COPY_DIR/$DEST/keystone $KEYSTONE_BRANCH
149git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
150
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700151# Unmount the filesystems
Anthony Young1b7a42e2011-10-19 02:34:06 -0700152unmount_images
153
Anthony Youngbabb2e02011-10-20 12:32:58 -0700154# Back to devstack
155cd $TOP_DIR
Anthony Young1b7a42e2011-10-19 02:34:06 -0700156
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700157# Network configuration variables
Anthony Young1b7a42e2011-10-19 02:34:06 -0700158BRIDGE=${BRIDGE:-br0}
Jesse Andrews82040df2011-10-22 20:56:23 -0700159GUEST_IP=${GUEST_IP:-192.168.1.50}
160GUEST_CIDR=${GUEST_CIDR:-$GUEST_IP/24}
161GUEST_NETMASK=${GUEST_NETMASK:-255.255.255.0}
162GUEST_GATEWAY=${GUEST_GATEWAY:-192.168.1.1}
163GUEST_MAC=${GUEST_MAC:-"02:16:3e:07:69:`printf '%02X' $(echo $GUEST_IP | sed "s/.*\.//")`"}
164GUEST_RAM=${GUEST_RAM:-1524288}
165GUEST_CORES=${GUEST_CORES:-1}
Anthony Young1b7a42e2011-10-19 02:34:06 -0700166
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700167# libvirt.xml configuration
Jesse Andrewsec1d0312011-10-21 19:22:55 -0700168LIBVIRT_XML=$VM_DIR/libvirt.xml
Anthony Young1b7a42e2011-10-19 02:34:06 -0700169cat > $LIBVIRT_XML <<EOF
170<domain type='kvm'>
Jesse Andrews82040df2011-10-22 20:56:23 -0700171 <name>$GUEST_NAME</name>
172 <memory>$GUEST_RAM</memory>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700173 <os>
Anthony Youngd51812d2011-10-19 20:09:43 -0700174 <type>hvm</type>
175 <bootmenu enable='yes'/>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700176 </os>
177 <features>
178 <acpi/>
179 </features>
Jesse Andrews82040df2011-10-22 20:56:23 -0700180 <vcpu>$GUEST_CORES</vcpu>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700181 <devices>
182 <disk type='file'>
183 <driver type='qcow2'/>
184 <source file='$VM_DIR/disk'/>
185 <target dev='vda' bus='virtio'/>
186 </disk>
187
188 <interface type='bridge'>
189 <source bridge='$BRIDGE'/>
Jesse Andrews82040df2011-10-22 20:56:23 -0700190 <mac address='$GUEST_MAC'/>
Anthony Young1b7a42e2011-10-19 02:34:06 -0700191 </interface>
192
193 <!-- The order is significant here. File must be defined first -->
194 <serial type="file">
195 <source path='$VM_DIR/console.log'/>
196 <target port='1'/>
197 </serial>
198
199 <console type='pty' tty='/dev/pts/2'>
200 <source path='/dev/pts/2'/>
201 <target port='0'/>
202 </console>
203
204 <serial type='pty'>
205 <source path='/dev/pts/2'/>
206 <target port='0'/>
207 </serial>
208
209 <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
210 </devices>
211</domain>
212EOF
213
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700214# Mount point for instance fs
Anthony Young1b7a42e2011-10-19 02:34:06 -0700215ROOTFS=$VM_DIR/root
216mkdir -p $ROOTFS
217
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700218# Make sure we have nbd-ness
Anthony Young1b7a42e2011-10-19 02:34:06 -0700219modprobe nbd max_part=63
220
Anthony Young9c0fdd72011-10-19 20:22:32 -0700221# Which NBD device to use?
222NBD=${NBD:-/dev/nbd5}
223
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700224# Clean up from previous runs
Anthony Young1b7a42e2011-10-19 02:34:06 -0700225umount $ROOTFS || echo 'ok'
Anthony Young9c0fdd72011-10-19 20:22:32 -0700226qemu-nbd -d $NBD || echo 'ok'
Anthony Young1b7a42e2011-10-19 02:34:06 -0700227
Anthony Youngbabb2e02011-10-20 12:32:58 -0700228# Clean up old runs
229cd $VM_DIR
230rm -f $VM_DIR/disk
231
232# Create our instance fs
Dean Troyerd0332912011-10-21 14:58:44 -0500233qemu-img create -f qcow2 -b $VM_IMAGE disk
Anthony Youngbabb2e02011-10-20 12:32:58 -0700234
Anthony Young69937462011-10-20 12:55:46 -0700235sleep 5
236
Anthony Young9c0fdd72011-10-19 20:22:32 -0700237qemu-nbd -c $NBD disk
Anthony Young69937462011-10-20 12:55:46 -0700238
239sleep 5
240
241# Mount the instance
Anthony Young9c0fdd72011-10-19 20:22:32 -0700242mount $NBD $ROOTFS -o offset=32256 -t ext4
Anthony Young1b7a42e2011-10-19 02:34:06 -0700243
244# Configure instance network
245INTERFACES=$ROOTFS/etc/network/interfaces
246cat > $INTERFACES <<EOF
247auto lo
248iface lo inet loopback
249
250auto eth0
251iface eth0 inet static
Jesse Andrews82040df2011-10-22 20:56:23 -0700252 address $GUEST_IP
253 netmask $GUEST_NETMASK
254 gateway $GUEST_GATEWAY
Anthony Young1b7a42e2011-10-19 02:34:06 -0700255EOF
256
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700257# User configuration for the instance
Anthony Young1b7a42e2011-10-19 02:34:06 -0700258chroot $ROOTFS groupadd libvirtd
259chroot $ROOTFS useradd stack -s /bin/bash -d $DEST -G libvirtd
260cp -pr $TOOLS_DIR/.. $ROOTFS/$DEST/devstack
261echo "root:$ROOT_PASSWORD" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700262echo "stack:pass" | chroot $ROOTFS chpasswd
Anthony Young1b7a42e2011-10-19 02:34:06 -0700263echo "stack ALL=(ALL) NOPASSWD: ALL" >> $ROOTFS/etc/sudoers
264
265# Gracefully cp only if source file/dir exists
266function cp_it {
267 if [ -e $1 ] || [ -d $1 ]; then
268 cp -pRL $1 $2
269 fi
270}
271
272# Copy over your ssh keys and env if desired
273COPYENV=${COPYENV:-1}
274if [ "$COPYENV" = "1" ]; then
275 cp_it ~/.ssh $ROOTFS/$DEST/.ssh
276 cp_it ~/.ssh/id_rsa.pub $ROOTFS/$DEST/.ssh/authorized_keys
277 cp_it ~/.gitconfig $ROOTFS/$DEST/.gitconfig
278 cp_it ~/.vimrc $ROOTFS/$DEST/.vimrc
279 cp_it ~/.bashrc $ROOTFS/$DEST/.bashrc
280fi
281
282# Configure the runner
283RUN_SH=$ROOTFS/$DEST/run.sh
284cat > $RUN_SH <<EOF
285#!/usr/bin/env bash
Anthony Young1b7a42e2011-10-19 02:34:06 -0700286
287# Kill any existing screens
288killall screen
289
290# Install and run stack.sh
291sudo apt-get update
292sudo apt-get -y --force-yes install git-core vim-nox sudo
293if [ ! -d "$DEST/devstack" ]; then
294 git clone git://github.com/cloudbuilders/devstack.git $DEST/devstack
295fi
296cd $DEST/devstack && $STACKSH_PARAMS FORCE=yes ./stack.sh > /$DEST/run.sh.log
297echo >> /$DEST/run.sh.log
298echo >> /$DEST/run.sh.log
299echo "All done! Time to start clicking." >> /$DEST/run.sh.log
Anthony Youngd51812d2011-10-19 20:09:43 -0700300cat $DEST/run.sh.log
Anthony Young1b7a42e2011-10-19 02:34:06 -0700301EOF
Anthony Young1b7a42e2011-10-19 02:34:06 -0700302chmod 755 $RUN_SH
303
304# Make runner launch on boot
305RC_LOCAL=$ROOTFS/etc/init.d/local
306cat > $RC_LOCAL <<EOF
307#!/bin/sh -e
Dean Troyerad57a3a2011-10-21 14:29:30 -0500308# Reboot if this is our first run to enable console log on $DIST_NAME :(
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700309if [ ! -e /root/firstlaunch ]; then
310 touch /root/firstlaunch
Anthony Youngd51812d2011-10-19 20:09:43 -0700311 reboot -f
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700312 exit 0
313fi
Anthony Young1b7a42e2011-10-19 02:34:06 -0700314su -c "$DEST/run.sh" stack
315EOF
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700316chmod +x $RC_LOCAL
317chroot $ROOTFS sudo update-rc.d local defaults 80
Anthony Young1b7a42e2011-10-19 02:34:06 -0700318
319# Make our ip address hostnames look nice at the command prompt
320echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/$DEST/.bashrc
321echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/etc/profile
322
323# Give stack ownership over $DEST so it may do the work needed
324chroot $ROOTFS chown -R stack $DEST
325
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700326# Change boot params so that we get a console log
Anthony Youngf6f52272011-10-19 02:58:18 -0700327sudo 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 -0700328sudo sed -e "s/^hiddenmenu//g" -i $ROOTFS/boot/grub/menu.lst
329#chroot $ROOTFS grub-install /dev/vda
Anthony Youngf6f52272011-10-19 02:58:18 -0700330
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700331# Unmount
332umount $ROOTFS || echo 'ok'
Anthony Young9c0fdd72011-10-19 20:22:32 -0700333qemu-nbd -d $NBD
Anthony Young1b7a42e2011-10-19 02:34:06 -0700334
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700335# Create the instance
336cd $VM_DIR && virsh create libvirt.xml
337
338# Tail the console log till we are done
Anthony Youngd51812d2011-10-19 20:09:43 -0700339WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700340if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
341 # Done creating the container, let's tail the log
342 echo
343 echo "============================================================="
344 echo " -- YAY! --"
345 echo "============================================================="
346 echo
347 echo "We're done launching the vm, about to start tailing the"
348 echo "stack.sh log. It will take a second or two to start."
349 echo
350 echo "Just CTRL-C at any time to stop tailing."
351
352 while [ ! -e "$VM_DIR/console.log" ]; do
353 sleep 1
354 done
355
356 tail -F $VM_DIR/console.log &
357
358 TAIL_PID=$!
359
360 function kill_tail() {
361 kill $TAIL_PID
362 exit 1
363 }
Vishvananda Ishaya9b353672011-10-20 10:07:10 -0700364
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700365 # Let Ctrl-c kill tail and exit
366 trap kill_tail SIGINT
367
368 echo "Waiting stack.sh to finish..."
Anthony Youngd51812d2011-10-19 20:09:43 -0700369 while ! cat $VM_DIR/console.log | grep -q 'All done' ; do
Anthony Youngfa4b5eb2011-10-19 11:27:02 -0700370 sleep 5
371 done
372
373 kill $TAIL_PID
374 echo ""
375 echo "Finished - Zip-a-dee Doo-dah!"
376fi