blob: 48819c95e761a17215d68abdd6bfbdc9ac618731 [file] [log] [blame]
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -07001#!/usr/bin/env bash
2
Dean Troyere62ba4d2012-06-27 22:07:34 -05003# **build_uec.sh**
4
Anthony Younge28f7752011-11-09 11:48:09 -08005# Make sure that we have the proper version of ubuntu (only works on oneiric)
6if ! egrep -q "oneiric" /etc/lsb-release; then
Anthony Young593e9aa2011-11-09 12:42:08 -08007 echo "This script only works with ubuntu oneiric."
Jesse Andrewse3c47a32011-11-07 10:44:43 -08008 exit 1
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -07009fi
10
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070011# Keep track of the current directory
12TOOLS_DIR=$(cd $(dirname "$0") && pwd)
Dean Troyer7f9aa712012-01-31 12:11:56 -060013TOP_DIR=$(cd $TOOLS_DIR/..; pwd)
14
15# Import common functions
16. $TOP_DIR/functions
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070017
Jesse Andrews53d75332011-11-06 07:54:11 -080018cd $TOP_DIR
19
20# Source params
21source ./stackrc
22
23# Ubuntu distro to install
24DIST_NAME=${DIST_NAME:-oneiric}
25
Jesse Andrewse3c47a32011-11-07 10:44:43 -080026# Configure how large the VM should be
27GUEST_SIZE=${GUEST_SIZE:-10G}
28
Jesse Andrews228f2462011-11-05 17:36:14 -070029# exit on error to stop unexpected errors
30set -o errexit
31set -o xtrace
32
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070033# Abort if localrc is not set
34if [ ! -e $TOP_DIR/localrc ]; then
35 echo "You must have a localrc with ALL necessary passwords defined before proceeding."
36 echo "See stack.sh for required passwords."
37 exit 1
38fi
39
40# Install deps if needed
Jesse Andrews26793032011-11-11 13:56:29 -080041DEPS="kvm libvirt-bin kpartx cloud-utils curl"
Dean Troyer7f9aa712012-01-31 12:11:56 -060042apt_get install -y --force-yes $DEPS || true # allow this to fail gracefully for concurrent builds
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070043
44# Where to store files and instances
Jesse Andrewsd7326d22011-11-20 10:02:26 -080045WORK_DIR=${WORK_DIR:-/opt/uecstack}
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070046
47# Where to store images
Jesse Andrews228f2462011-11-05 17:36:14 -070048image_dir=$WORK_DIR/images/$DIST_NAME
49mkdir -p $image_dir
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070050
Jesse Andrewsd7326d22011-11-20 10:02:26 -080051# Start over with a clean base image, if desired
52if [ $CLEAN_BASE ]; then
53 rm -f $image_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070054fi
55
Jesse Andrewsd7326d22011-11-20 10:02:26 -080056# Get the base image if it does not yet exist
57if [ ! -e $image_dir/disk ]; then
58 $TOOLS_DIR/get_uec_image.sh -r $GUEST_SIZE $DIST_NAME $image_dir/disk $image_dir/kernel
59fi
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070060
Jesse Andrewsd7326d22011-11-20 10:02:26 -080061# Copy over dev environment if COPY_ENV is set.
62# This will also copy over your current devstack.
63if [ $COPY_ENV ]; then
64 cd $TOOLS_DIR
65 ./copy_dev_environment_to_uec.sh $image_dir/disk
66fi
67
68# Option to warm the base image with software requirements.
69if [ $WARM_CACHE ]; then
70 cd $TOOLS_DIR
71 ./warm_apts_and_pips_for_uec.sh $image_dir/disk
72fi
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070073
74# Name of our instance, used by libvirt
75GUEST_NAME=${GUEST_NAME:-devstack}
76
77# Mop up after previous runs
78virsh destroy $GUEST_NAME || true
79
80# Where this vm is stored
Jesse Andrews228f2462011-11-05 17:36:14 -070081vm_dir=$WORK_DIR/instances/$GUEST_NAME
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070082
83# Create vm dir and remove old disk
Jesse Andrews228f2462011-11-05 17:36:14 -070084mkdir -p $vm_dir
85rm -f $vm_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070086
87# Create a copy of the base image
Jesse Andrewsf5a76912011-11-05 17:47:50 -070088qemu-img create -f qcow2 -b $image_dir/disk $vm_dir/disk
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -070089
90# Back to devstack
91cd $TOP_DIR
92
93GUEST_NETWORK=${GUEST_NETWORK:-1}
94GUEST_RECREATE_NET=${GUEST_RECREATE_NET:-yes}
95GUEST_IP=${GUEST_IP:-192.168.$GUEST_NETWORK.50}
96GUEST_CIDR=${GUEST_CIDR:-$GUEST_IP/24}
97GUEST_NETMASK=${GUEST_NETMASK:-255.255.255.0}
98GUEST_GATEWAY=${GUEST_GATEWAY:-192.168.$GUEST_NETWORK.1}
99GUEST_MAC=${GUEST_MAC:-"02:16:3e:07:69:`printf '%02X' $GUEST_NETWORK`"}
100GUEST_RAM=${GUEST_RAM:-1524288}
101GUEST_CORES=${GUEST_CORES:-1}
102
103# libvirt.xml configuration
Jesse Andrews228f2462011-11-05 17:36:14 -0700104NET_XML=$vm_dir/net.xml
Anthony Young8b47cdf2011-11-09 23:36:18 -0800105NET_NAME=${NET_NAME:-devstack-$GUEST_NETWORK}
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700106cat > $NET_XML <<EOF
107<network>
Anthony Young8b47cdf2011-11-09 23:36:18 -0800108 <name>$NET_NAME</name>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700109 <bridge name="stackbr%d" />
110 <forward/>
Jesse Andrewsa6282622011-11-05 18:39:33 -0700111 <ip address="$GUEST_GATEWAY" netmask="$GUEST_NETMASK">
112 <dhcp>
Jesse Andrews02cc96c2011-11-06 10:29:10 -0800113 <range start='192.168.$GUEST_NETWORK.2' end='192.168.$GUEST_NETWORK.127' />
Jesse Andrewsa6282622011-11-05 18:39:33 -0700114 </dhcp>
115 </ip>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700116</network>
117EOF
118
119if [[ "$GUEST_RECREATE_NET" == "yes" ]]; then
Anthony Young8b47cdf2011-11-09 23:36:18 -0800120 virsh net-destroy $NET_NAME || true
Jesse Andrewsdca89002011-11-06 10:33:33 -0800121 # destroying the network isn't enough to delete the leases
Anthony Young8b47cdf2011-11-09 23:36:18 -0800122 rm -f /var/lib/libvirt/dnsmasq/$NET_NAME.leases
Jesse Andrews228f2462011-11-05 17:36:14 -0700123 virsh net-create $vm_dir/net.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700124fi
125
126# libvirt.xml configuration
Jesse Andrews228f2462011-11-05 17:36:14 -0700127LIBVIRT_XML=$vm_dir/libvirt.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700128cat > $LIBVIRT_XML <<EOF
129<domain type='kvm'>
130 <name>$GUEST_NAME</name>
131 <memory>$GUEST_RAM</memory>
132 <os>
Jesse Andrews228f2462011-11-05 17:36:14 -0700133 <type>hvm</type>
Jesse Andrewsf5a76912011-11-05 17:47:50 -0700134 <kernel>$image_dir/kernel</kernel>
Jesse Andrews438ea572011-11-05 22:33:49 -0700135 <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 -0700136 </os>
137 <features>
138 <acpi/>
139 </features>
140 <clock offset='utc'/>
141 <vcpu>$GUEST_CORES</vcpu>
142 <devices>
143 <disk type='file'>
144 <driver type='qcow2'/>
Jesse Andrews228f2462011-11-05 17:36:14 -0700145 <source file='$vm_dir/disk'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700146 <target dev='vda' bus='virtio'/>
147 </disk>
148
149 <interface type='network'>
Anthony Young72eab222011-11-09 23:38:18 -0800150 <source network='$NET_NAME'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700151 </interface>
Hengqing Hu3b719e52012-03-09 16:03:00 +0800152
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700153 <!-- The order is significant here. File must be defined first -->
154 <serial type="file">
Jesse Andrews228f2462011-11-05 17:36:14 -0700155 <source path='$vm_dir/console.log'/>
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700156 <target port='1'/>
157 </serial>
158
159 <console type='pty' tty='/dev/pts/2'>
160 <source path='/dev/pts/2'/>
161 <target port='0'/>
162 </console>
163
164 <serial type='pty'>
165 <source path='/dev/pts/2'/>
166 <target port='0'/>
167 </serial>
168
169 <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
170 </devices>
171</domain>
172EOF
173
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700174
Jesse Andrewse49f7512011-11-05 22:34:45 -0700175rm -rf $vm_dir/uec
Jesse Andrews9ed6bbd2011-11-05 22:28:46 -0700176cp -r $TOOLS_DIR/uec $vm_dir/uec
177
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700178# set metadata
179cat > $vm_dir/uec/meta-data<<EOF
180hostname: $GUEST_NAME
Jesse Andrewse3c47a32011-11-07 10:44:43 -0800181instance-id: i-hop
182instance-type: m1.ignore
Jesse Andrews7306f3b2011-11-05 23:13:34 -0700183local-hostname: $GUEST_NAME.local
Jesse Andrewsd7ce7af2011-11-05 22:47:28 -0700184EOF
185
Anthony Young2838f122011-11-10 13:04:40 -0800186# set user-data
Jesse Andrews63cb9232011-11-05 23:16:53 -0700187cat > $vm_dir/uec/user-data<<EOF
Jesse Andrews446a3302011-11-05 23:36:29 -0700188#!/bin/bash
Jesse Andrewsb17c4f32011-11-06 09:25:55 -0800189# hostname needs to resolve for rabbit
Jesse Andrews6e3a4c52011-11-06 09:35:13 -0800190sed -i "s/127.0.0.1/127.0.0.1 \`hostname\`/" /etc/hosts
Jesse Andrews446a3302011-11-05 23:36:29 -0700191apt-get update
Jesse Andrewsc7f72ad2011-11-06 08:00:28 -0800192apt-get install git sudo -y
Anthony Young760ddde2011-11-10 13:46:52 -0800193# Disable byobu
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800194sudo apt-get remove -y byobu
Anthony Youngb2256822011-11-10 12:57:59 -0800195EOF
196
197# Setup stack user with our key
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800198if [[ -e ~/.ssh/id_rsa.pub ]]; then
Anthony Youngb7661282011-11-10 13:09:25 -0800199 PUB_KEY=`cat ~/.ssh/id_rsa.pub`
Anthony Young2838f122011-11-10 13:04:40 -0800200 cat >> $vm_dir/uec/user-data<<EOF
Anthony Youngb2256822011-11-10 12:57:59 -0800201mkdir -p /opt/stack
Anthony Young331ae292011-12-21 11:55:35 -0800202if [ ! -d /opt/stack/devstack ]; then
203 git clone https://github.com/cloudbuilders/devstack.git /opt/stack/devstack
204 cd /opt/stack/devstack
205 cat > localrc <<LOCAL_EOF
206ROOTSLEEP=0
207`cat $TOP_DIR/localrc`
208LOCAL_EOF
209fi
Anthony Youngff7771e2011-11-10 13:33:31 -0800210useradd -U -G sudo -s /bin/bash -d /opt/stack -m stack
Anthony Youngb2256822011-11-10 12:57:59 -0800211echo stack:pass | chpasswd
212mkdir -p /opt/stack/.ssh
Anthony Youngb7661282011-11-10 13:09:25 -0800213echo "$PUB_KEY" > /opt/stack/.ssh/authorized_keys
Anthony Youngb2256822011-11-10 12:57:59 -0800214chown -R stack /opt/stack
215chmod 700 /opt/stack/.ssh
216chmod 600 /opt/stack/.ssh/authorized_keys
217
218grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
219 echo "#includedir /etc/sudoers.d" >> /etc/sudoers
220( umask 226 && echo "stack ALL=(ALL) NOPASSWD:ALL" \
221 > /etc/sudoers.d/50_stack_sh )
222EOF
223fi
224
225# Run stack.sh
Anthony Young2838f122011-11-10 13:04:40 -0800226cat >> $vm_dir/uec/user-data<<EOF
Anthony Young331ae292011-12-21 11:55:35 -0800227su -c "cd /opt/stack/devstack && ./stack.sh" stack
Jesse Andrews63cb9232011-11-05 23:16:53 -0700228EOF
229
Jesse Andrewsee34f622011-11-05 22:41:57 -0700230# (re)start a metadata service
Jesse Andrews3ce79aa2011-11-05 22:52:20 -0700231(
232 pid=`lsof -iTCP@192.168.$GUEST_NETWORK.1:4567 -n | awk '{print $2}' | tail -1`
Jesse Andrews9645b0c2011-11-05 23:05:33 -0700233 [ -z "$pid" ] || kill -9 $pid
Jesse Andrews3ce79aa2011-11-05 22:52:20 -0700234)
Jesse Andrewsf504e282011-11-05 22:29:35 -0700235cd $vm_dir/uec
236python meta.py 192.168.$GUEST_NETWORK.1:4567 &
Jesse Andrews9ed6bbd2011-11-05 22:28:46 -0700237
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700238# Create the instance
Jesse Andrews63fa7ab2011-11-05 18:49:36 -0700239virsh create $vm_dir/libvirt.xml
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700240
241# Tail the console log till we are done
242WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
243if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
Jesse Andrews228f2462011-11-05 17:36:14 -0700244 set +o xtrace
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700245 # Done creating the container, let's tail the log
246 echo
247 echo "============================================================="
248 echo " -- YAY! --"
249 echo "============================================================="
250 echo
251 echo "We're done launching the vm, about to start tailing the"
252 echo "stack.sh log. It will take a second or two to start."
253 echo
254 echo "Just CTRL-C at any time to stop tailing."
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800255 echo
256
257 if ! timeout 60 sh -c "while [ ! -s /var/lib/libvirt/dnsmasq/$NET_NAME.leases ]; do sleep 1; done"; then
258 echo "Your instance failed to acquire an IP address"
259 exit 1
260 fi
261
262 ip=`cat /var/lib/libvirt/dnsmasq/$NET_NAME.leases | cut -d " " -f3`
263 echo "#############################################################"
264 echo " -- This is your instance's IP: --"
265 echo " $ip"
266 echo "#############################################################"
267
268 sleep 2
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700269
Jesse Andrews228f2462011-11-05 17:36:14 -0700270 while [ ! -e "$vm_dir/console.log" ]; do
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700271 sleep 1
272 done
273
Jesse Andrews228f2462011-11-05 17:36:14 -0700274 tail -F $vm_dir/console.log &
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700275
276 TAIL_PID=$!
277
278 function kill_tail() {
279 kill $TAIL_PID
280 exit 1
281 }
282
283 # Let Ctrl-c kill tail and exit
284 trap kill_tail SIGINT
285
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700286 echo "Waiting stack.sh to finish..."
Jesse Andrewsd55a5152011-11-06 08:16:42 -0800287 while ! egrep -q '^stack.sh (completed|failed)' $vm_dir/console.log ; do
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700288 sleep 1
289 done
290
291 set -o xtrace
292
293 kill $TAIL_PID
294
Jesse Andrews228f2462011-11-05 17:36:14 -0700295 if ! grep -q "^stack.sh completed in" $vm_dir/console.log; then
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700296 exit 1
297 fi
Jesse Andrewsd7326d22011-11-20 10:02:26 -0800298
299 set +o xtrace
Jesse Andrews8b3eb5f2011-11-05 16:05:14 -0700300 echo ""
301 echo "Finished - Zip-a-dee Doo-dah!"
302fi