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