Browse code

Merge pull request #82 from cloudbuilders/build_kvm

add build_kvm.sh

sleepsonthefloor authored on 2011/10/20 12:41:49
Showing 3 changed files
... ...
@@ -12,3 +12,7 @@ vim-nox
12 12
 locate # useful when debugging
13 13
 python-virtualenv
14 14
 python-unittest2
15
+iputils-ping
16
+wget
17
+curl
18
+tcpdump
15 19
new file mode 100755
... ...
@@ -0,0 +1,370 @@
0
+#!/usr/bin/env bash
1
+
2
+# Make sure that we have the proper version of ubuntu
3
+UBUNTU_VERSION=`cat /etc/lsb-release | grep CODENAME | sed 's/.*=//g'`
4
+if [ ! "oneiric" = "$UBUNTU_VERSION" ]; then
5
+    if [ ! "natty" = "$UBUNTU_VERSION" ]; then
6
+        echo "This script only works with oneiric and natty"
7
+        exit 1
8
+    fi
9
+fi
10
+
11
+# Echo commands
12
+set -o xtrace
13
+
14
+# Keep track of the current directory
15
+TOOLS_DIR=$(cd $(dirname "$0") && pwd)
16
+TOP_DIR=$TOOLS_DIR/..
17
+
18
+# Configure the root password of the vm
19
+ROOT_PASSWORD=${ROOT_PASSWORD:password}
20
+
21
+# Where to store files and instances
22
+KVMSTACK_DIR=${KVMSTACK_DIR:-/opt/kvmstack}
23
+
24
+# Where to store images
25
+IMAGES_DIR=$KVMSTACK_DIR/images
26
+
27
+# Create images dir
28
+mkdir -p $IMAGES_DIR
29
+
30
+# Move to top devstack dir
31
+cd $TOP_DIR
32
+
33
+# Abort if localrc is not set
34
+if [ ! -e ./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
38
+fi
39
+
40
+# Source params
41
+source ./stackrc
42
+
43
+# Base image (natty by default)
44
+DIST_NAME=${DIST_NAME:-natty}
45
+IMAGE_FNAME=$DIST_NAME.raw
46
+
47
+# Original version of built image
48
+BASE_IMAGE=$KVMSTACK_DIR/images/natty.raw
49
+
50
+# Copy of base image, which we pre-install with tasty treats
51
+BASE_IMAGE_COPY=$IMAGES_DIR/$DIST_NAME.raw.copy
52
+
53
+# Name of our instance, used by libvirt
54
+VM_NAME=${VM_NAME:-kvmstack}
55
+
56
+# Mop up after previous runs
57
+virsh destroy $VM_NAME
58
+
59
+# Where this vm is stored
60
+VM_DIR=$KVMSTACK_DIR/instances/$VM_NAME
61
+
62
+# Create vm dir
63
+mkdir -p $VM_DIR
64
+
65
+# Mount point into copied base image
66
+COPY_DIR=$VM_DIR/copy
67
+mkdir -p $COPY_DIR
68
+
69
+# Create the base image if it does not yet exist
70
+if [ ! -e $IMAGES_DIR/$IMAGE_FNAME ]; then
71
+    cd $TOOLS_DIR
72
+    ./make_image.sh -m -r 5000  natty raw
73
+    mv natty.raw $BASE_IMAGE
74
+    cd $TOP_DIR
75
+fi
76
+
77
+# Create a copy of the base image
78
+if [ ! -e $BASE_IMAGE_COPY ]; then
79
+    cp -p $BASE_IMAGE $BASE_IMAGE_COPY
80
+fi
81
+
82
+# Unmount the copied base image
83
+function unmount_images() {
84
+    # unmount the filesystem
85
+    while df | grep -q $COPY_DIR; do
86
+        umount $COPY_DIR || echo 'ok'
87
+        sleep 1
88
+    done
89
+}
90
+
91
+# Unmount from failed runs
92
+unmount_images
93
+
94
+# Ctrl-c catcher
95
+function kill_unmount() {
96
+    unmount_images
97
+    exit 1
98
+}
99
+
100
+# Install deps
101
+apt-get install -y --force-yes kvm libvirt-bin kpartx
102
+
103
+# Let Ctrl-c kill tail and exit
104
+trap kill_unmount SIGINT
105
+
106
+# Where Openstack code will live in image
107
+DEST=${DEST:-/opt/stack}
108
+
109
+# Mount the file system
110
+mount -o loop,offset=32256 $BASE_IMAGE_COPY  $COPY_DIR
111
+
112
+# git clone only if directory doesn't exist already.  Since ``DEST`` might not
113
+# be owned by the installation user, we create the directory and change the
114
+# ownership to the proper user.
115
+function git_clone {
116
+    if [ ! -d $2 ]; then
117
+        sudo mkdir $2
118
+        sudo chown `whoami` $2
119
+        git clone $1 $2
120
+        cd $2
121
+        # This checkout syntax works for both branches and tags
122
+        git checkout $3
123
+    fi
124
+}
125
+
126
+# Make sure that base requirements are installed
127
+cp /etc/resolv.conf $COPY_DIR/etc/resolv.conf
128
+chroot $COPY_DIR apt-get update
129
+chroot $COPY_DIR apt-get install -y --force-yes `cat files/apts/* | cut -d\# -f1 | egrep -v "(rabbitmq|libvirt-bin|mysql-server)"`
130
+chroot $COPY_DIR apt-get install -y --download-only rabbitmq-server libvirt-bin mysql-server
131
+chroot $COPY_DIR pip install `cat files/pips/*`
132
+
133
+# Clean out code repos if directed to do so
134
+if [ "$CLEAN" = "1" ]; then
135
+    rm -rf $COPY_DIR/$DEST
136
+fi
137
+
138
+# Cache openstack code
139
+mkdir -p $COPY_DIR/$DEST
140
+git_clone $NOVA_REPO $COPY_DIR/$DEST/nova $NOVA_BRANCH
141
+git_clone $GLANCE_REPO $COPY_DIR/$DEST/glance $GLANCE_BRANCH
142
+git_clone $KEYSTONE_REPO $COPY_DIR/$DESTkeystone $KEYSTONE_BRANCH
143
+git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
144
+git_clone $DASH_REPO $COPY_DIR/$DEST/dash $DASH_BRANCH $DASH_TAG
145
+git_clone $NOVACLIENT_REPO $COPY_DIR/$DEST/python-novaclient $NOVACLIENT_BRANCH
146
+git_clone $OPENSTACKX_REPO $COPY_DIR/$DEST/openstackx $OPENSTACKX_BRANCH
147
+git_clone $KEYSTONE_REPO $COPY_DIR/$DEST/keystone $KEYSTONE_BRANCH
148
+git_clone $NOVNC_REPO $COPY_DIR/$DEST/noVNC $NOVNC_BRANCH
149
+
150
+# Back to devstack
151
+cd $TOP_DIR
152
+
153
+# Unmount the filesystems
154
+unmount_images
155
+
156
+# Clean up old runs
157
+cd $VM_DIR
158
+rm -f $VM_DIR/disk
159
+
160
+# Clean up old instance data
161
+qemu-img create -f qcow2 -b $BASE_IMAGE_COPY disk
162
+
163
+# Network configuration variables
164
+BRIDGE=${BRIDGE:-br0}
165
+CONTAINER=${CONTAINER:-STACK}
166
+CONTAINER_IP=${CONTAINER_IP:-192.168.1.50}
167
+CONTAINER_CIDR=${CONTAINER_CIDR:-$CONTAINER_IP/24}
168
+CONTAINER_NETMASK=${CONTAINER_NETMASK:-255.255.255.0}
169
+CONTAINER_GATEWAY=${CONTAINER_GATEWAY:-192.168.1.1}
170
+CONTAINER_MAC=${CONTAINER_MAC:-02:16:3e:07:70:d7}
171
+
172
+# libvirt.xml configuration
173
+LIBVIRT_XML=libvirt.xml
174
+cat > $LIBVIRT_XML <<EOF
175
+<domain type='kvm'>
176
+    <name>$VM_NAME</name>
177
+    <memory>1524288</memory>
178
+    <os>
179
+        <type>hvm</type>
180
+        <bootmenu enable='yes'/>
181
+    </os>
182
+    <features>
183
+        <acpi/>
184
+    </features>
185
+    <vcpu>1</vcpu>
186
+    <devices>
187
+        <disk type='file'>
188
+            <driver type='qcow2'/>
189
+            <source file='$VM_DIR/disk'/>
190
+            <target dev='vda' bus='virtio'/>
191
+        </disk>
192
+
193
+        <interface type='bridge'>
194
+            <source bridge='$BRIDGE'/>
195
+            <mac address='$CONTAINER_MAC'/>
196
+        </interface>
197
+
198
+        <!-- The order is significant here.  File must be defined first -->
199
+        <serial type="file">
200
+            <source path='$VM_DIR/console.log'/>
201
+            <target port='1'/>
202
+        </serial>
203
+
204
+        <console type='pty' tty='/dev/pts/2'>
205
+            <source path='/dev/pts/2'/>
206
+            <target port='0'/>
207
+        </console>
208
+
209
+        <serial type='pty'>
210
+            <source path='/dev/pts/2'/>
211
+            <target port='0'/>
212
+        </serial>
213
+
214
+        <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
215
+    </devices>
216
+</domain>
217
+EOF
218
+
219
+# Mount point for instance fs
220
+ROOTFS=$VM_DIR/root
221
+mkdir -p $ROOTFS
222
+
223
+# Make sure we have nbd-ness
224
+modprobe nbd max_part=63
225
+
226
+# Which NBD device to use?
227
+NBD=${NBD:-/dev/nbd5}
228
+
229
+# Clean up from previous runs
230
+umount $ROOTFS || echo 'ok'
231
+qemu-nbd -d $NBD || echo 'ok'
232
+
233
+# Mount the instance
234
+qemu-nbd -c $NBD disk
235
+mount $NBD $ROOTFS -o offset=32256 -t ext4
236
+
237
+# Configure instance network
238
+INTERFACES=$ROOTFS/etc/network/interfaces
239
+cat > $INTERFACES <<EOF
240
+auto lo
241
+iface lo inet loopback
242
+
243
+auto eth0
244
+iface eth0 inet static
245
+        address $CONTAINER_IP
246
+        netmask $CONTAINER_NETMASK
247
+        gateway $CONTAINER_GATEWAY
248
+EOF
249
+
250
+# User configuration for the instance
251
+chroot $ROOTFS groupadd libvirtd
252
+chroot $ROOTFS useradd stack -s /bin/bash -d $DEST -G libvirtd
253
+cp -pr $TOOLS_DIR/.. $ROOTFS/$DEST/devstack
254
+echo "root:$ROOT_PASSWORD" | chroot $ROOTFS chpasswd
255
+echo "stack:pass" | chroot $ROOTFS chpasswd
256
+echo "stack ALL=(ALL) NOPASSWD: ALL" >> $ROOTFS/etc/sudoers
257
+
258
+# Gracefully cp only if source file/dir exists
259
+function cp_it {
260
+    if [ -e $1 ] || [ -d $1 ]; then
261
+        cp -pRL $1 $2
262
+    fi
263
+}
264
+
265
+# Copy over your ssh keys and env if desired
266
+COPYENV=${COPYENV:-1}
267
+if [ "$COPYENV" = "1" ]; then
268
+    cp_it ~/.ssh $ROOTFS/$DEST/.ssh
269
+    cp_it ~/.ssh/id_rsa.pub $ROOTFS/$DEST/.ssh/authorized_keys
270
+    cp_it ~/.gitconfig $ROOTFS/$DEST/.gitconfig
271
+    cp_it ~/.vimrc $ROOTFS/$DEST/.vimrc
272
+    cp_it ~/.bashrc $ROOTFS/$DEST/.bashrc
273
+fi
274
+
275
+# Configure the runner
276
+RUN_SH=$ROOTFS/$DEST/run.sh
277
+cat > $RUN_SH <<EOF
278
+#!/usr/bin/env bash
279
+
280
+# Kill any existing screens
281
+killall screen
282
+
283
+# Install and run stack.sh
284
+sudo apt-get update
285
+sudo apt-get -y --force-yes install git-core vim-nox sudo
286
+if [ ! -d "$DEST/devstack" ]; then
287
+    git clone git://github.com/cloudbuilders/devstack.git $DEST/devstack
288
+fi
289
+cd $DEST/devstack && $STACKSH_PARAMS FORCE=yes ./stack.sh > /$DEST/run.sh.log
290
+echo >> /$DEST/run.sh.log
291
+echo >> /$DEST/run.sh.log
292
+echo "All done! Time to start clicking." >> /$DEST/run.sh.log
293
+cat $DEST/run.sh.log
294
+EOF
295
+chmod 755 $RUN_SH
296
+
297
+# Make runner launch on boot
298
+RC_LOCAL=$ROOTFS/etc/init.d/local
299
+cat > $RC_LOCAL <<EOF
300
+#!/bin/sh -e
301
+# Reboot if this is our first run to enable console log on natty :(
302
+if [ ! -e /root/firstlaunch ]; then
303
+    touch /root/firstlaunch
304
+    reboot -f
305
+    exit 0
306
+fi
307
+su -c "$DEST/run.sh" stack
308
+EOF
309
+chmod +x $RC_LOCAL
310
+chroot $ROOTFS sudo update-rc.d local defaults 80
311
+
312
+# Make our ip address hostnames look nice at the command prompt
313
+echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/$DEST/.bashrc
314
+echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $ROOTFS/etc/profile
315
+
316
+# Give stack ownership over $DEST so it may do the work needed
317
+chroot $ROOTFS chown -R stack $DEST
318
+
319
+# Change boot params so that we get a console log
320
+sudo sed -e "s/quiet splash/splash console=ttyS0 console=ttyS1,19200n8/g" -i $ROOTFS/boot/grub/menu.lst
321
+sudo sed -e "s/^hiddenmenu//g" -i $ROOTFS/boot/grub/menu.lst
322
+#chroot $ROOTFS grub-install /dev/vda
323
+
324
+# Unmount
325
+umount $ROOTFS || echo 'ok'
326
+qemu-nbd -d $NBD
327
+
328
+# Create the instance
329
+cd $VM_DIR && virsh create libvirt.xml
330
+
331
+# Tail the console log till we are done
332
+WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
333
+if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
334
+    # Done creating the container, let's tail the log
335
+    echo
336
+    echo "============================================================="
337
+    echo "                          -- YAY! --"
338
+    echo "============================================================="
339
+    echo
340
+    echo "We're done launching the vm, about to start tailing the"
341
+    echo "stack.sh log. It will take a second or two to start."
342
+    echo
343
+    echo "Just CTRL-C at any time to stop tailing."
344
+
345
+    while [ ! -e "$VM_DIR/console.log" ]; do
346
+      sleep 1
347
+    done
348
+
349
+    tail -F $VM_DIR/console.log &
350
+
351
+    TAIL_PID=$!
352
+
353
+    function kill_tail() {
354
+        kill $TAIL_PID
355
+        exit 1
356
+    }
357
+ 
358
+    # Let Ctrl-c kill tail and exit
359
+    trap kill_tail SIGINT
360
+
361
+    echo "Waiting stack.sh to finish..."
362
+    while ! cat $VM_DIR/console.log | grep -q 'All done' ; do
363
+        sleep 5
364
+    done
365
+
366
+    kill $TAIL_PID
367
+    echo ""
368
+    echo "Finished - Zip-a-dee Doo-dah!"
369
+fi
... ...
@@ -110,7 +110,7 @@ esac
110 110
 
111 111
 # Install stuff if necessary
112 112
 if [ -z `which vmbuilder` ]; then
113
-    sudo apt-get install ubuntu-vm-builder
113
+    sudo apt-get install -y ubuntu-vm-builder
114 114
 fi
115 115
 
116 116
 if [ -n "$CHROOTONLY" ]; then