Browse code

Merge pull request #168 from cloudbuilders/uec-simple

Uec simple

sleepsonthefloor authored on 2011/11/08 03:50:05
Showing 3 changed files
... ...
@@ -103,8 +103,7 @@ if [[ $EUID -eq 0 ]]; then
103 103
 
104 104
     # since this script runs as a normal user, we need to give that user
105 105
     # ability to run sudo
106
-    apt_get update
107
-    apt_get install sudo
106
+    dpkg -l sudo || apt_get update && apt_get install sudo
108 107
 
109 108
     if ! getent passwd stack >/dev/null; then
110 109
         echo "Creating a user called stack"
... ...
@@ -121,7 +120,7 @@ if [[ $EUID -eq 0 ]]; then
121 121
     echo "Copying files to stack user"
122 122
     STACK_DIR="$DEST/${PWD##*/}"
123 123
     cp -r -f "$PWD" "$STACK_DIR"
124
-    chown -R $USER "$STACK_DIR"
124
+    chown -R stack "$STACK_DIR"
125 125
     if [[ "$SHELL_AFTER_RUN" != "no" ]]; then
126 126
         exec su -c "set -e; cd $STACK_DIR; bash stack.sh; bash" stack
127 127
     else
... ...
@@ -912,6 +911,10 @@ function screen_it {
912 912
     NL=`echo -ne '\015'`
913 913
     if [[ "$ENABLED_SERVICES" =~ "$1" ]]; then
914 914
         screen -S stack -X screen -t $1
915
+        # sleep to allow bash to be ready to be send the command - we are
916
+        # creating a new window in screen and then sends characters, so if
917
+        # bash isn't running by the time we send the command, nothing happens
918
+        sleep 1
915 919
         screen -S stack -p $1 -X stuff "$2$NL"
916 920
     fi
917 921
 }
918 922
new file mode 100755
... ...
@@ -0,0 +1,248 @@
0
+#!/usr/bin/env bash
1
+
2
+# Make sure that we have the proper version of ubuntu (only works on natty/oneiric)
3
+if ! egrep -q "oneiric|natty" /etc/lsb-release; then
4
+    echo "This script only works with ubuntu oneiric and natty"
5
+    exit 1
6
+fi
7
+
8
+# Keep track of the current directory
9
+TOOLS_DIR=$(cd $(dirname "$0") && pwd)
10
+TOP_DIR=`cd $TOOLS_DIR/..; pwd`
11
+
12
+cd $TOP_DIR
13
+
14
+# Source params
15
+source ./stackrc
16
+
17
+# Ubuntu distro to install
18
+DIST_NAME=${DIST_NAME:-oneiric}
19
+
20
+# Configure how large the VM should be
21
+GUEST_SIZE=${GUEST_SIZE:-10G}
22
+
23
+# exit on error to stop unexpected errors
24
+set -o errexit
25
+set -o xtrace
26
+
27
+# Abort if localrc is not set
28
+if [ ! -e $TOP_DIR/localrc ]; then
29
+    echo "You must have a localrc with ALL necessary passwords defined before proceeding."
30
+    echo "See stack.sh for required passwords."
31
+    exit 1
32
+fi
33
+
34
+# Install deps if needed
35
+DEPS="kvm libvirt-bin kpartx"
36
+dpkg -l $DEPS || apt-get install -y --force-yes $DEPS
37
+
38
+# Where to store files and instances
39
+WORK_DIR=${WORK_DIR:-/opt/kvmstack}
40
+
41
+# Where to store images
42
+image_dir=$WORK_DIR/images/$DIST_NAME
43
+mkdir -p $image_dir
44
+
45
+# Original version of built image
46
+uec_url=http://uec-images.ubuntu.com/$DIST_NAME/current/$DIST_NAME-server-cloudimg-amd64.tar.gz
47
+tarball=$image_dir/$(basename $uec_url)
48
+
49
+# download the base uec image if we haven't already
50
+if [ ! -f $tarball ]; then
51
+    curl $uec_url -o $tarball
52
+    (cd $image_dir && tar -Sxvzf $tarball)
53
+    resize-part-image $image_dir/*.img $GUEST_SIZE $image_dir/disk
54
+    cp $image_dir/*-vmlinuz-virtual $image_dir/kernel
55
+fi
56
+
57
+
58
+# Configure the root password of the vm to be the same as ``ADMIN_PASSWORD``
59
+ROOT_PASSWORD=${ADMIN_PASSWORD:-password}
60
+
61
+# Name of our instance, used by libvirt
62
+GUEST_NAME=${GUEST_NAME:-devstack}
63
+
64
+# Mop up after previous runs
65
+virsh destroy $GUEST_NAME || true
66
+
67
+# Where this vm is stored
68
+vm_dir=$WORK_DIR/instances/$GUEST_NAME
69
+
70
+# Create vm dir and remove old disk
71
+mkdir -p $vm_dir
72
+rm -f $vm_dir/disk
73
+
74
+# Create a copy of the base image
75
+qemu-img create -f qcow2 -b $image_dir/disk $vm_dir/disk
76
+
77
+# Back to devstack
78
+cd $TOP_DIR
79
+
80
+GUEST_NETWORK=${GUEST_NETWORK:-1}
81
+GUEST_RECREATE_NET=${GUEST_RECREATE_NET:-yes}
82
+GUEST_IP=${GUEST_IP:-192.168.$GUEST_NETWORK.50}
83
+GUEST_CIDR=${GUEST_CIDR:-$GUEST_IP/24}
84
+GUEST_NETMASK=${GUEST_NETMASK:-255.255.255.0}
85
+GUEST_GATEWAY=${GUEST_GATEWAY:-192.168.$GUEST_NETWORK.1}
86
+GUEST_MAC=${GUEST_MAC:-"02:16:3e:07:69:`printf '%02X' $GUEST_NETWORK`"}
87
+GUEST_RAM=${GUEST_RAM:-1524288}
88
+GUEST_CORES=${GUEST_CORES:-1}
89
+
90
+# libvirt.xml configuration
91
+NET_XML=$vm_dir/net.xml
92
+cat > $NET_XML <<EOF
93
+<network>
94
+  <name>devstack-$GUEST_NETWORK</name>
95
+  <bridge name="stackbr%d" />
96
+  <forward/>
97
+  <ip address="$GUEST_GATEWAY" netmask="$GUEST_NETMASK">
98
+    <dhcp>
99
+      <range start='192.168.$GUEST_NETWORK.2' end='192.168.$GUEST_NETWORK.127' />
100
+    </dhcp>
101
+  </ip>
102
+</network>
103
+EOF
104
+
105
+if [[ "$GUEST_RECREATE_NET" == "yes" ]]; then
106
+    virsh net-destroy devstack-$GUEST_NETWORK || true
107
+    # destroying the network isn't enough to delete the leases
108
+    rm -f /var/lib/libvirt/dnsmasq/devstack-$GUEST_NETWORK.leases
109
+    virsh net-create $vm_dir/net.xml
110
+fi
111
+
112
+# libvirt.xml configuration
113
+LIBVIRT_XML=$vm_dir/libvirt.xml
114
+cat > $LIBVIRT_XML <<EOF
115
+<domain type='kvm'>
116
+  <name>$GUEST_NAME</name>
117
+  <memory>$GUEST_RAM</memory>
118
+  <os>
119
+    <type>hvm</type>
120
+    <kernel>$image_dir/kernel</kernel>
121
+    <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>
122
+  </os>
123
+  <features>
124
+    <acpi/>
125
+  </features>
126
+  <clock offset='utc'/>
127
+  <vcpu>$GUEST_CORES</vcpu>
128
+  <devices>
129
+    <disk type='file'>
130
+      <driver type='qcow2'/>
131
+      <source file='$vm_dir/disk'/>
132
+      <target dev='vda' bus='virtio'/>
133
+    </disk>
134
+
135
+    <interface type='network'>
136
+      <source network='devstack-$GUEST_NETWORK'/>
137
+    </interface>
138
+        
139
+    <!-- The order is significant here.  File must be defined first -->
140
+    <serial type="file">
141
+      <source path='$vm_dir/console.log'/>
142
+      <target port='1'/>
143
+    </serial>
144
+
145
+    <console type='pty' tty='/dev/pts/2'>
146
+      <source path='/dev/pts/2'/>
147
+      <target port='0'/>
148
+    </console>
149
+
150
+    <serial type='pty'>
151
+      <source path='/dev/pts/2'/>
152
+      <target port='0'/>
153
+    </serial>
154
+
155
+    <graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='0.0.0.0'/>
156
+  </devices>
157
+</domain>
158
+EOF
159
+
160
+
161
+rm -rf $vm_dir/uec
162
+cp -r $TOOLS_DIR/uec $vm_dir/uec
163
+
164
+# set metadata
165
+cat > $vm_dir/uec/meta-data<<EOF
166
+hostname: $GUEST_NAME
167
+instance-id: i-hop
168
+instance-type: m1.ignore
169
+local-hostname: $GUEST_NAME.local
170
+EOF
171
+
172
+# set metadata
173
+cat > $vm_dir/uec/user-data<<EOF
174
+#!/bin/bash
175
+# hostname needs to resolve for rabbit
176
+sed -i "s/127.0.0.1/127.0.0.1 \`hostname\`/" /etc/hosts
177
+apt-get update
178
+apt-get install git sudo -y
179
+git clone https://github.com/cloudbuilders/devstack.git
180
+cd devstack
181
+git remote set-url origin `cd $TOP_DIR; git remote show origin | grep Fetch | awk '{print $3}'`
182
+git fetch
183
+git checkout `git rev-parse HEAD`
184
+cat > localrc <<LOCAL_EOF
185
+ROOTSLEEP=0
186
+`cat $TOP_DIR/localrc`
187
+LOCAL_EOF
188
+./stack.sh
189
+EOF
190
+
191
+# (re)start a metadata service
192
+(
193
+  pid=`lsof -iTCP@192.168.$GUEST_NETWORK.1:4567 -n | awk '{print $2}' | tail -1`
194
+  [ -z "$pid" ] || kill -9 $pid
195
+)
196
+cd $vm_dir/uec
197
+python meta.py 192.168.$GUEST_NETWORK.1:4567 &
198
+
199
+# Create the instance
200
+virsh create $vm_dir/libvirt.xml
201
+
202
+# Tail the console log till we are done
203
+WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
204
+if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
205
+    set +o xtrace
206
+    # Done creating the container, let's tail the log
207
+    echo
208
+    echo "============================================================="
209
+    echo "                          -- YAY! --"
210
+    echo "============================================================="
211
+    echo
212
+    echo "We're done launching the vm, about to start tailing the"
213
+    echo "stack.sh log. It will take a second or two to start."
214
+    echo
215
+    echo "Just CTRL-C at any time to stop tailing."
216
+
217
+    while [ ! -e "$vm_dir/console.log" ]; do
218
+      sleep 1
219
+    done
220
+
221
+    tail -F $vm_dir/console.log &
222
+
223
+    TAIL_PID=$!
224
+
225
+    function kill_tail() {
226
+        kill $TAIL_PID
227
+        exit 1
228
+    }
229
+
230
+    # Let Ctrl-c kill tail and exit
231
+    trap kill_tail SIGINT
232
+
233
+    echo "Waiting stack.sh to finish..."
234
+    while ! egrep -q '^stack.sh (completed|failed)' $vm_dir/console.log ; do
235
+        sleep 1
236
+    done
237
+
238
+    set -o xtrace
239
+
240
+    kill $TAIL_PID
241
+
242
+    if ! grep -q "^stack.sh completed in" $vm_dir/console.log; then
243
+        exit 1
244
+    fi
245
+    echo ""
246
+    echo "Finished - Zip-a-dee Doo-dah!"
247
+fi
0 248
new file mode 100644
... ...
@@ -0,0 +1,29 @@
0
+import sys
1
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
2
+from SimpleHTTPServer import SimpleHTTPRequestHandler
3
+
4
+def main(host, port, HandlerClass = SimpleHTTPRequestHandler,
5
+         ServerClass = HTTPServer, protocol="HTTP/1.0"):
6
+    """simple http server that listens on a give address:port"""
7
+
8
+    server_address = (host, port)
9
+
10
+    HandlerClass.protocol_version = protocol
11
+    httpd = ServerClass(server_address, HandlerClass)
12
+
13
+    sa = httpd.socket.getsockname()
14
+    print "Serving HTTP on", sa[0], "port", sa[1], "..."
15
+    httpd.serve_forever()
16
+
17
+if __name__ == '__main__':
18
+    if sys.argv[1:]:
19
+        address = sys.argv[1]
20
+    else:
21
+        address = '0.0.0.0'
22
+    if ':' in address:
23
+        host, port = address.split(':')
24
+    else:
25
+        host = address
26
+        port = 8080
27
+
28
+    main(host, int(port))