... | ... |
@@ -130,9 +130,10 @@ NOVNC_DIR=$DEST/noVNC |
130 | 130 |
# Specify which services to launch. These generally correspond to screen tabs |
131 | 131 |
ENABLED_SERVICES=${ENABLED_SERVICES:-g-api,g-reg,key,n-api,n-cpu,n-net,n-sch,n-vnc,dash,mysql,rabbit} |
132 | 132 |
|
133 |
-# Nova hypervisor configuration. We default to **kvm** but will drop back to |
|
134 |
-# **qemu** if we are unable to load the kvm module. Stack.sh can also install |
|
135 |
-# an **LXC** based system. |
|
133 |
+# Nova hypervisor configuration. We default to libvirt whth **kvm** but will |
|
134 |
+# drop back to **qemu** if we are unable to load the kvm module. Stack.sh can |
|
135 |
+# also install an **LXC** based system. |
|
136 |
+VIRT_DRIVER=${VIRT_DRIVER:-libvirt} |
|
136 | 137 |
LIBVIRT_TYPE=${LIBVIRT_TYPE:-kvm} |
137 | 138 |
|
138 | 139 |
# nova supports pluggable schedulers. ``SimpleScheduler`` should work in most |
... | ... |
@@ -572,14 +573,30 @@ add_nova_flag "--ec2_dmz_host=$EC2_DMZ_HOST" |
572 | 572 |
add_nova_flag "--rabbit_host=$RABBIT_HOST" |
573 | 573 |
add_nova_flag "--rabbit_password=$RABBIT_PASSWORD" |
574 | 574 |
add_nova_flag "--glance_api_servers=$GLANCE_HOSTPORT" |
575 |
-add_nova_flag "--flat_network_bridge=$FLAT_NETWORK_BRIDGE" |
|
576 |
-if [ -n "$FLAT_INTERFACE" ]; then |
|
577 |
- add_nova_flag "--flat_interface=$FLAT_INTERFACE" |
|
578 |
-fi |
|
579 | 575 |
if [ -n "$MULTI_HOST" ]; then |
580 | 576 |
add_nova_flag "--multi_host=$MULTI_HOST" |
581 | 577 |
fi |
582 | 578 |
|
579 |
+# XenServer |
|
580 |
+# --------- |
|
581 |
+ |
|
582 |
+if [ "$VIRT_DRIVER" = 'xenserver' ]; then |
|
583 |
+ read_password XENAPI_PASSWORD "ENTER A PASSWORD TO USE FOR XEN." |
|
584 |
+ add_nova_flag "--connection_type=xenapi" |
|
585 |
+ add_nova_flag "--xenapi_connection_url=http://169.254.0.1" |
|
586 |
+ add_nova_flag "--xenapi_connection_username=root" |
|
587 |
+ add_nova_flag "--xenapi_connection_password=$XENAPI_PASSWORD" |
|
588 |
+ add_nova_flag "--flat_injected=False" |
|
589 |
+ add_nova_flag "--flat_interface=eth1" |
|
590 |
+ add_nova_flag "--flat_network_bridge=xapi1" |
|
591 |
+ add_nova_flag "--public_interface=eth3" |
|
592 |
+else |
|
593 |
+ add_nova_flag "--flat_network_bridge=$FLAT_NETWORK_BRIDGE" |
|
594 |
+ if [ -n "$FLAT_INTERFACE" ]; then |
|
595 |
+ add_nova_flag "--flat_interface=$FLAT_INTERFACE" |
|
596 |
+ fi |
|
597 |
+fi |
|
598 |
+ |
|
583 | 599 |
# Nova Database |
584 | 600 |
# ~~~~~~~~~~~~~ |
585 | 601 |
|
... | ... |
@@ -712,6 +729,20 @@ if [[ "$ENABLED_SERVICES" =~ "g-reg" ]]; then |
712 | 712 |
# Create a directory for the downloaded image tarballs. |
713 | 713 |
mkdir -p $FILES/images |
714 | 714 |
|
715 |
+ # Option to upload legacy ami-tty, which works with xenserver |
|
716 |
+ if [ $UPLOAD_LEGACY_TTY ]; then |
|
717 |
+ if [ ! -f $FILES/tty.tgz ]; then |
|
718 |
+ wget -c http://images.ansolabs.com/tty.tgz -O $FILES/tty.tgz |
|
719 |
+ fi |
|
720 |
+ |
|
721 |
+ tar -zxf $FILES/tty.tgz -C $FILES/images |
|
722 |
+ RVAL=`glance add -A $SERVICE_TOKEN name="tty-kernel" is_public=true container_format=aki disk_format=aki < $FILES/images/aki-tty/image` |
|
723 |
+ KERNEL_ID=`echo $RVAL | cut -d":" -f2 | tr -d " "` |
|
724 |
+ RVAL=`glance add -A $SERVICE_TOKEN name="tty-ramdisk" is_public=true container_format=ari disk_format=ari < $FILES/images/ari-tty/image` |
|
725 |
+ RAMDISK_ID=`echo $RVAL | cut -d":" -f2 | tr -d " "` |
|
726 |
+ glance add -A $SERVICE_TOKEN name="tty" is_public=true container_format=ami disk_format=ami kernel_id=$KERNEL_ID ramdisk_id=$RAMDISK_ID < $FILES/images/ami-tty/image |
|
727 |
+ fi |
|
728 |
+ |
|
715 | 729 |
for image_url in ${IMAGE_URLS//,/ }; do |
716 | 730 |
# Downloads the image (uec ami+aki style), then extracts it. |
717 | 731 |
IMAGE_FNAME=`echo "$image_url" | python -c "import sys; print sys.stdin.read().split('/')[-1]"` |
718 | 732 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,51 @@ |
0 |
+Getting Started With XenServer 5.6 and Devstack |
|
1 |
+=============================================== |
|
2 |
+The purpose of the code in this directory it to help developers bootstrap |
|
3 |
+a XenServer 5.6 + Openstack development environment. This file gives |
|
4 |
+some pointers on how to get started. |
|
5 |
+ |
|
6 |
+Install Xenserver |
|
7 |
+----------------- |
|
8 |
+Install XenServer 5.6 on a clean box. |
|
9 |
+Here are some sample Xenserver network settings for when you are just |
|
10 |
+getting started (I used settings like this using a lappy + cheap wifi router): |
|
11 |
+ |
|
12 |
+* XenServer Host IP: 192.168.1.10 |
|
13 |
+* XenServer Netmask: 255.255.255.0 |
|
14 |
+* XenServer Gateway: 192.168.1.1 |
|
15 |
+* XenServer DNS: 192.168.1.1 |
|
16 |
+ |
|
17 |
+Prepare DOM0 |
|
18 |
+------------ |
|
19 |
+At this point, your server is missing some critical software that you will |
|
20 |
+need to run devstack (like git). Do this to install required software: |
|
21 |
+ |
|
22 |
+ ./prepare_dom0.sh |
|
23 |
+ |
|
24 |
+This script will also clone devstack in /root/devstack |
|
25 |
+ |
|
26 |
+Configure your localrc |
|
27 |
+---------------------- |
|
28 |
+Devstack uses a localrc for user-specific configuration. Note that while |
|
29 |
+the first 4 passwords are arbitrary, the XENAPI_PASSWORD must be your dom0 |
|
30 |
+root password. And of course, use a real password if this machine is exposed. |
|
31 |
+ |
|
32 |
+ cd /root/devstack |
|
33 |
+ |
|
34 |
+ cat > /root/devstack/localrc <<EOF |
|
35 |
+ MYSQL_PASSWORD=my_super_secret |
|
36 |
+ SERVICE_TOKEN=my_super_secret |
|
37 |
+ ADMIN_PASSWORD=my_super_secret |
|
38 |
+ RABBIT_PASSWORD=my_super_secret |
|
39 |
+ # IMPORTANT: The following must be set to your dom0 root password! |
|
40 |
+ XENAPI_PASSWORD=my_super_secret |
|
41 |
+ EOF |
|
42 |
+ |
|
43 |
+Run ./build_domU.sh |
|
44 |
+------------------ |
|
45 |
+This script does a lot of stuff, it is probably best to read it in its entirety. |
|
46 |
+But in a nutshell, it performs the following: |
|
47 |
+ |
|
48 |
+* Configures bridges and vlans for public, private, and management nets |
|
49 |
+* Creates XVAs for a HEAD and COMPUTE host |
|
50 |
+* Launches those 2 instances into an HA FlatDHCP Configuration |
0 | 51 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,288 @@ |
0 |
+#!/bin/bash |
|
1 |
+ |
|
2 |
+# Abort if localrc is not set |
|
3 |
+if [ ! -e ../../localrc ]; then |
|
4 |
+ echo "You must have a localrc with ALL necessary passwords defined before proceeding." |
|
5 |
+ echo "See the xen README for required passwords." |
|
6 |
+ exit 1 |
|
7 |
+fi |
|
8 |
+ |
|
9 |
+# Echo commands |
|
10 |
+set -o xtrace |
|
11 |
+ |
|
12 |
+# Name of this guest |
|
13 |
+GUEST_NAME=${GUEST_NAME:-ALLINONE} |
|
14 |
+ |
|
15 |
+# dom0 ip |
|
16 |
+HOST_IP=${HOST_IP:-`ifconfig xenbr0 | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"`} |
|
17 |
+ |
|
18 |
+# Our nova host's network info |
|
19 |
+MGT_IP=${MGT_IP:-172.16.100.1} |
|
20 |
+PUB_IP=${PUB_IP:-192.168.1.55} |
|
21 |
+ |
|
22 |
+# Public network |
|
23 |
+PUB_BR=${PUB_BR:-xenbr0} |
|
24 |
+PUB_NETMASK=${PUB_NETMASK:-255.255.255.0} |
|
25 |
+ |
|
26 |
+# VM network params |
|
27 |
+VM_NETMASK=${VM_NETMASK:-255.255.255.0} |
|
28 |
+VM_BR=${VM_BR:-xapi1} |
|
29 |
+VM_VLAN=${VM_VLAN:-100} |
|
30 |
+ |
|
31 |
+# MGMT network params |
|
32 |
+MGT_NETMASK=${MGT_NETMASK:-255.255.255.0} |
|
33 |
+MGT_BR=${MGT_BR:-xapi2} |
|
34 |
+MGT_VLAN=${MGT_VLAN:-101} |
|
35 |
+ |
|
36 |
+# VM Password |
|
37 |
+PASSWORD=${PASSWORD:-secrete} |
|
38 |
+ |
|
39 |
+# Size of image |
|
40 |
+VDI_MB=${VDI_MB:-2500} |
|
41 |
+ |
|
42 |
+# This directory |
|
43 |
+TOP_DIR=$(cd $(dirname "$0") && pwd) |
|
44 |
+ |
|
45 |
+# Make sure we have git |
|
46 |
+if ! which git; then |
|
47 |
+ GITDIR=/tmp/git-1.7.7 |
|
48 |
+ cd /tmp |
|
49 |
+ rm -rf $GITDIR* |
|
50 |
+ wget http://git-core.googlecode.com/files/git-1.7.7.tar.gz |
|
51 |
+ tar xfv git-1.7.7.tar.gz |
|
52 |
+ cd $GITDIR |
|
53 |
+ ./configure |
|
54 |
+ make install |
|
55 |
+ cd $TOP_DIR |
|
56 |
+fi |
|
57 |
+ |
|
58 |
+# Helper to create networks |
|
59 |
+function create_network() { |
|
60 |
+ if ! xe network-list | grep bridge | grep -q $1; then |
|
61 |
+ echo "Creating bridge $1" |
|
62 |
+ xe network-create name-label=$1 |
|
63 |
+ fi |
|
64 |
+} |
|
65 |
+ |
|
66 |
+# Create host, vm, mgmt, pub networks |
|
67 |
+create_network xapi0 |
|
68 |
+create_network $VM_BR |
|
69 |
+create_network $MGT_BR |
|
70 |
+create_network $PUB_BR |
|
71 |
+ |
|
72 |
+# Get the uuid for our physical (public) interface |
|
73 |
+PIF=`xe pif-list --minimal device=eth0` |
|
74 |
+ |
|
75 |
+# Create networks/bridges for vm and management |
|
76 |
+VM_NET=`xe network-list --minimal bridge=$VM_BR` |
|
77 |
+MGT_NET=`xe network-list --minimal bridge=$MGT_BR` |
|
78 |
+ |
|
79 |
+# Helper to create vlans |
|
80 |
+function create_vlan() { |
|
81 |
+ pif=$1 |
|
82 |
+ vlan=$2 |
|
83 |
+ net=$3 |
|
84 |
+ if ! xe vlan-list | grep tag | grep -q $vlan; then |
|
85 |
+ xe vlan-create pif-uuid=$pif vlan=$vlan network-uuid=$net |
|
86 |
+ fi |
|
87 |
+} |
|
88 |
+ |
|
89 |
+# Create vlans for vm and management |
|
90 |
+create_vlan $PIF $VM_VLAN $VM_NET |
|
91 |
+create_vlan $PIF $MGT_VLAN $MGT_NET |
|
92 |
+ |
|
93 |
+# Setup host-only nat rules |
|
94 |
+HOST_NET=169.254.0.0/16 |
|
95 |
+if ! iptables -L -v -t nat | grep -q $HOST_NET; then |
|
96 |
+ iptables -t nat -A POSTROUTING -s $HOST_NET -j SNAT --to-source $HOST_IP |
|
97 |
+ iptables -I FORWARD 1 -s $HOST_NET -j ACCEPT |
|
98 |
+ /etc/init.d/iptables save |
|
99 |
+fi |
|
100 |
+ |
|
101 |
+# Set up ip forwarding |
|
102 |
+if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then |
|
103 |
+ # FIXME: This doesn't work on reboot! |
|
104 |
+ echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network |
|
105 |
+fi |
|
106 |
+ |
|
107 |
+# Also, enable ip forwarding in rc.local, since the above trick isn't working |
|
108 |
+if ! grep -q "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then |
|
109 |
+ echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local |
|
110 |
+fi |
|
111 |
+ |
|
112 |
+# Enable ip forwarding at runtime as well |
|
113 |
+echo 1 > /proc/sys/net/ipv4/ip_forward |
|
114 |
+ |
|
115 |
+# Directory where we stage the build |
|
116 |
+STAGING_DIR=$TOP_DIR/stage |
|
117 |
+ |
|
118 |
+# Option to clean out old stuff |
|
119 |
+CLEAN=${CLEAN:-0} |
|
120 |
+if [ "$CLEAN" = "1" ]; then |
|
121 |
+ rm -rf $STAGING_DIR |
|
122 |
+fi |
|
123 |
+ |
|
124 |
+# Download our base image. This image is made using prepare_guest.sh |
|
125 |
+BASE_IMAGE_URL=${BASE_IMAGE_URL:-http://images.ansolabs.com/xen/stage.tgz} |
|
126 |
+if [ ! -e $STAGING_DIR ]; then |
|
127 |
+ if [ ! -e /tmp/stage.tgz ]; then |
|
128 |
+ wget $BASE_IMAGE_URL -O /tmp/stage.tgz |
|
129 |
+ fi |
|
130 |
+ tar xfz /tmp/stage.tgz |
|
131 |
+ cd $TOP_DIR |
|
132 |
+fi |
|
133 |
+ |
|
134 |
+# Free up precious disk space |
|
135 |
+rm -f /tmp/stage.tgz |
|
136 |
+ |
|
137 |
+# Make sure we have a stage |
|
138 |
+if [ ! -d $STAGING_DIR/etc ]; then |
|
139 |
+ echo "Stage is not properly set up!" |
|
140 |
+ exit 1 |
|
141 |
+fi |
|
142 |
+ |
|
143 |
+# Directory where our conf files are stored |
|
144 |
+FILES_DIR=$TOP_DIR/files |
|
145 |
+ |
|
146 |
+# Directory for supporting script files |
|
147 |
+SCRIPT_DIR=$TOP_DIR/scripts |
|
148 |
+ |
|
149 |
+# Version of ubuntu with which we are working |
|
150 |
+UBUNTU_VERSION=`cat $STAGING_DIR/etc/lsb-release | grep "DISTRIB_CODENAME=" | sed "s/DISTRIB_CODENAME=//"` |
|
151 |
+KERNEL_VERSION=`ls $STAGING_DIR/boot/vmlinuz* | head -1 | sed "s/.*vmlinuz-//"` |
|
152 |
+ |
|
153 |
+# Setup fake grub |
|
154 |
+rm -rf $STAGING_DIR/boot/grub/ |
|
155 |
+mkdir -p $STAGING_DIR/boot/grub/ |
|
156 |
+cp $FILES_DIR/menu.lst.in $STAGING_DIR/boot/grub/menu.lst |
|
157 |
+sed -e "s,@KERNEL_VERSION@,$KERNEL_VERSION,g" -i $STAGING_DIR/boot/grub/menu.lst |
|
158 |
+ |
|
159 |
+# Setup fstab, tty, and other system stuff |
|
160 |
+cp $FILES_DIR/fstab $STAGING_DIR/etc/fstab |
|
161 |
+cp $FILES_DIR/hvc0.conf $STAGING_DIR/etc/init/ |
|
162 |
+ |
|
163 |
+# Put the VPX into UTC. |
|
164 |
+rm -f $STAGING_DIR/etc/localtime |
|
165 |
+ |
|
166 |
+# Helper to set hostname |
|
167 |
+function set_hostname() { |
|
168 |
+ echo $1 > $STAGING_DIR/etc/hostname |
|
169 |
+} |
|
170 |
+ |
|
171 |
+# We need a resolvable host name for rabbit to launch |
|
172 |
+if ! grep -q $GUEST_NAME $STAGING_DIR/etc/hosts; then |
|
173 |
+ echo "$MGT_IP $GUEST_NAME" >> $STAGING_DIR/etc/hosts |
|
174 |
+fi |
|
175 |
+ |
|
176 |
+# Configre hosts file |
|
177 |
+cat <<EOF >$STAGING_DIR/etc/hosts |
|
178 |
+$MGT_IP $GUEST_NAME |
|
179 |
+127.0.0.1 localhost localhost.localdomain |
|
180 |
+EOF |
|
181 |
+ |
|
182 |
+# Configure dns (use same dns as dom0) |
|
183 |
+cp /etc/resolv.conf $STAGING_DIR/etc/resolv.conf |
|
184 |
+ |
|
185 |
+# Copy over devstack |
|
186 |
+rm -f /tmp/devstack.tar |
|
187 |
+tar --exclude='stage' --exclude='xen/xvas' --exclude='xen/nova' -cvf /tmp/devstack.tar $TOP_DIR/../../../devstack |
|
188 |
+cd $STAGING_DIR/opt/stack/ |
|
189 |
+tar xf /tmp/devstack.tar |
|
190 |
+cd $TOP_DIR |
|
191 |
+ |
|
192 |
+# Configure OVA |
|
193 |
+VDI_SIZE=$(($VDI_MB*1024*1024)) |
|
194 |
+PRODUCT_BRAND=${PRODUCT_BRAND:-openstack} |
|
195 |
+PRODUCT_VERSION=${PRODUCT_VERSION:-001} |
|
196 |
+BUILD_NUMBER=${BUILD_NUMBER:-001} |
|
197 |
+LABEL="$PRODUCT_BRAND $PRODUCT_VERSION-$BUILD_NUMBER" |
|
198 |
+OVA=$STAGING_DIR/tmp/ova.xml |
|
199 |
+cp templates/ova.xml.in $OVA |
|
200 |
+sed -e "s,@VDI_SIZE@,$VDI_SIZE,g" -i $OVA |
|
201 |
+sed -e "s,@PRODUCT_BRAND@,$PRODUCT_BRAND,g" -i $OVA |
|
202 |
+sed -e "s,@PRODUCT_VERSION@,$PRODUCT_VERSION,g" -i $OVA |
|
203 |
+sed -e "s,@BUILD_NUMBER@,$BUILD_NUMBER,g" -i $OVA |
|
204 |
+ |
|
205 |
+# Directory for xvas |
|
206 |
+XVA_DIR=$TOP_DIR/xvas |
|
207 |
+ |
|
208 |
+# Create xva dir |
|
209 |
+mkdir -p $XVA_DIR |
|
210 |
+ |
|
211 |
+# Clean nova if desired |
|
212 |
+if [ "$CLEAN" = "1" ]; then |
|
213 |
+ rm -rf $TOP_DIR/nova |
|
214 |
+fi |
|
215 |
+ |
|
216 |
+# Checkout nova |
|
217 |
+if [ ! -d $TOP_DIR/nova ]; then |
|
218 |
+ git clone git://github.com/cloudbuilders/nova.git |
|
219 |
+ git checkout diablo |
|
220 |
+fi |
|
221 |
+ |
|
222 |
+# Run devstack on launch |
|
223 |
+cat <<EOF >$STAGING_DIR/etc/rc.local |
|
224 |
+STAGING_DIR=/ DO_TGZ=0 bash /opt/stack/devstack/tools/xen/prepare_guest.sh |
|
225 |
+STAGING_DIR=/ DO_TGZ=0 bash /opt/stack/devstack/tools/xen/prepare_guest.sh |
|
226 |
+su -c "/opt/stack/run.sh > /opt/stack/run.sh.log" stack |
|
227 |
+exit 0 |
|
228 |
+EOF |
|
229 |
+ |
|
230 |
+# Install plugins |
|
231 |
+cp -pr $TOP_DIR/nova/plugins/xenserver/xenapi/etc/xapi.d /etc/ |
|
232 |
+chmod a+x /etc/xapi.d/plugins/* |
|
233 |
+yum --enablerepo=base install -y parted |
|
234 |
+mkdir -p /boot/guest |
|
235 |
+ |
|
236 |
+# Set local storage il8n |
|
237 |
+SR_UUID=`xe sr-list --minimal name-label="Local storage"` |
|
238 |
+xe sr-param-set uuid=$SR_UUID other-config:i18n-key=local-storage |
|
239 |
+ |
|
240 |
+# Uninstall previous runs |
|
241 |
+xe vm-list --minimal name-label="$LABEL" | xargs ./scripts/uninstall-os-vpx.sh |
|
242 |
+ |
|
243 |
+# Destroy any instances that were launched |
|
244 |
+for uuid in `xe vm-list | grep -1 instance | grep uuid | sed "s/.*\: //g"`; do |
|
245 |
+ echo "Shutting down nova instance $uuid" |
|
246 |
+ xe vm-shutdown uuid=$uuid |
|
247 |
+ xe vm-destroy uuid=$uuid |
|
248 |
+done |
|
249 |
+ |
|
250 |
+# Path to head xva. By default keep overwriting the same one to save space |
|
251 |
+USE_SEPARATE_XVAS=${USE_SEPARATE_XVAS:-0} |
|
252 |
+if [ "$USE_SEPARATE_XVAS" = "0" ]; then |
|
253 |
+ XVA=$XVA_DIR/$UBUNTU_VERSION.xva |
|
254 |
+else |
|
255 |
+ XVA=$XVA_DIR/$UBUNTU_VERSION.$GUEST_NAME.xva |
|
256 |
+fi |
|
257 |
+ |
|
258 |
+# Clean old xva. In the future may not do this every time. |
|
259 |
+rm -f $XVA |
|
260 |
+ |
|
261 |
+# Configure the network |
|
262 |
+set_hostname $GUEST_NAME |
|
263 |
+INTERFACES=$STAGING_DIR/etc/network/interfaces |
|
264 |
+cp templates/interfaces.in $INTERFACES |
|
265 |
+sed -e "s,@ETH1_NETMASK@,$VM_NETMASK,g" -i $INTERFACES |
|
266 |
+sed -e "s,@ETH2_IP@,$MGT_IP,g" -i $INTERFACES |
|
267 |
+sed -e "s,@ETH2_NETMASK@,$MGT_NETMASK,g" -i $INTERFACES |
|
268 |
+sed -e "s,@ETH3_IP@,$PUB_IP,g" -i $INTERFACES |
|
269 |
+sed -e "s,@ETH3_NETMASK@,$PUB_NETMASK,g" -i $INTERFACES |
|
270 |
+ |
|
271 |
+# Configure run.sh |
|
272 |
+cat <<EOF >$STAGING_DIR/opt/stack/run.sh |
|
273 |
+#!/bin/bash |
|
274 |
+cd /opt/stack/devstack |
|
275 |
+killall screen |
|
276 |
+UPLOAD_LEGACY_TTY=yes HOST_IP=$PUB_IP VIRT_DRIVER=xenserver FORCE=yes MULTI_HOST=1 $STACKSH_PARAMS ./stack.sh |
|
277 |
+EOF |
|
278 |
+chmod 755 $STAGING_DIR/opt/stack/run.sh |
|
279 |
+ |
|
280 |
+# Create xva |
|
281 |
+if [ ! -e $XVA ]; then |
|
282 |
+ rm -rf /tmp/mkxva* |
|
283 |
+ UID=0 $SCRIPT_DIR/mkxva -o $XVA -t xva -x $OVA $STAGING_DIR $VDI_MB /tmp/ |
|
284 |
+fi |
|
285 |
+ |
|
286 |
+# Start guest |
|
287 |
+$TOP_DIR/scripts/install-os-vpx.sh -f $XVA -v $VM_BR -m $MGT_BR -p $PUB_BR |
0 | 5 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,10 @@ |
0 |
+# hvc0 - getty |
|
1 |
+# |
|
2 |
+# This service maintains a getty on hvc0 from the point the system is |
|
3 |
+# started until it is shut down again. |
|
4 |
+ |
|
5 |
+start on stopped rc RUNLEVEL=[2345] |
|
6 |
+stop on runlevel [!2345] |
|
7 |
+ |
|
8 |
+respawn |
|
9 |
+exec /sbin/getty -8 9600 hvc0 |
0 | 10 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,41 @@ |
0 |
+#!/bin/sh |
|
1 |
+set -o xtrace |
|
2 |
+set -o errexit |
|
3 |
+ |
|
4 |
+# Install basics for vi and git |
|
5 |
+yum -y --enablerepo=base install gcc make vim-enhanced zlib-devel openssl-devel |
|
6 |
+ |
|
7 |
+# Simple but usable vimrc |
|
8 |
+if [ ! -e /root/.vimrc ]; then |
|
9 |
+ cat > /root/.vimrc <<EOF |
|
10 |
+syntax on |
|
11 |
+se ts=4 |
|
12 |
+se expandtab |
|
13 |
+se shiftwidth=4 |
|
14 |
+EOF |
|
15 |
+fi |
|
16 |
+ |
|
17 |
+# Use the pretty vim |
|
18 |
+if [ -e /usr/bin/vim ]; then |
|
19 |
+ rm /bin/vi |
|
20 |
+ ln -s /usr/bin/vim /bin/vi |
|
21 |
+fi |
|
22 |
+ |
|
23 |
+# Install git |
|
24 |
+if ! which git; then |
|
25 |
+ DEST=/tmp/ |
|
26 |
+ GITDIR=$DEST/git-1.7.7 |
|
27 |
+ cd $DEST |
|
28 |
+ rm -rf $GITDIR* |
|
29 |
+ wget http://git-core.googlecode.com/files/git-1.7.7.tar.gz |
|
30 |
+ tar xfv git-1.7.7.tar.gz |
|
31 |
+ cd $GITDIR |
|
32 |
+ ./configure |
|
33 |
+ make install |
|
34 |
+fi |
|
35 |
+ |
|
36 |
+# Clone devstack |
|
37 |
+DEVSTACK=/root/devstack |
|
38 |
+if [ ! -d $DEVSTACK ]; then |
|
39 |
+ git clone git://github.com/cloudbuilders/devstack.git $DEVSTACK |
|
40 |
+fi |
0 | 41 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,88 @@ |
0 |
+#!/bin/bash |
|
1 |
+ |
|
2 |
+# Configurable nuggets |
|
3 |
+PASSWORD=${PASSWORD:-secrete} |
|
4 |
+STAGING_DIR=${STAGING_DIR:-stage} |
|
5 |
+DO_TGZ=${DO_TGZ:-1} |
|
6 |
+KERNEL_VERSION=3.0.0-12-virtual |
|
7 |
+ |
|
8 |
+# Debootstrap base system |
|
9 |
+if [ ! -d $STAGING_DIR ]; then |
|
10 |
+ apt-get install debootstrap |
|
11 |
+ debootstrap --arch amd64 oneiric $STAGING_DIR http://us.archive.ubuntu.com/ubuntu/ |
|
12 |
+fi |
|
13 |
+ |
|
14 |
+# Sources.list |
|
15 |
+cat <<EOF >$STAGING_DIR/etc/apt/sources.list |
|
16 |
+deb http://us.archive.ubuntu.com/ubuntu/ oneiric main restricted |
|
17 |
+deb-src http://us.archive.ubuntu.com/ubuntu/ oneiric main restricted |
|
18 |
+deb http://us.archive.ubuntu.com/ubuntu/ oneiric-updates main restricted |
|
19 |
+deb-src http://us.archive.ubuntu.com/ubuntu/ oneiric-updates main restricted |
|
20 |
+deb http://us.archive.ubuntu.com/ubuntu/ oneiric universe |
|
21 |
+deb http://us.archive.ubuntu.com/ubuntu/ oneiric-updates universe |
|
22 |
+deb http://us.archive.ubuntu.com/ubuntu/ oneiric multiverse |
|
23 |
+deb http://us.archive.ubuntu.com/ubuntu/ oneiric-updates multiverse |
|
24 |
+EOF |
|
25 |
+ |
|
26 |
+# Install basics |
|
27 |
+chroot $STAGING_DIR apt-get update |
|
28 |
+chroot $STAGING_DIR apt-get install -y linux-image-$KERNEL_VERSION |
|
29 |
+chroot $STAGING_DIR apt-get install -y cracklib-runtime curl wget ssh openssh-server tcpdump ethtool |
|
30 |
+chroot $STAGING_DIR apt-get install -y curl wget ssh openssh-server python-pip git vim-nox sudo |
|
31 |
+chroot $STAGING_DIR pip install xenapi |
|
32 |
+ |
|
33 |
+# Install guest utilities |
|
34 |
+XEGUEST=xe-guest-utilities_5.6.100-651_amd64.deb |
|
35 |
+wget http://images.ansolabs.com/xen/$XEGUEST -O $XEGUEST |
|
36 |
+cp $XEGUEST $STAGING_DIR/root |
|
37 |
+chroot $STAGING_DIR dpkg -i /root/$XEGUEST |
|
38 |
+chroot $STAGING_DIR update-rc.d -f xe-linux-distribution remove |
|
39 |
+chroot $STAGING_DIR update-rc.d xe-linux-distribution defaults |
|
40 |
+ |
|
41 |
+# Make a small cracklib dictionary, so that passwd still works, but we don't |
|
42 |
+# have the big dictionary. |
|
43 |
+mkdir -p $STAGING_DIR/usr/share/cracklib |
|
44 |
+echo a | chroot $STAGING_DIR cracklib-packer |
|
45 |
+ |
|
46 |
+# Make /etc/shadow, and set the root password |
|
47 |
+chroot $STAGING_DIR "pwconv" |
|
48 |
+echo "root:$PASSWORD" | chroot $STAGING_DIR chpasswd |
|
49 |
+ |
|
50 |
+# Put the VPX into UTC. |
|
51 |
+rm -f $STAGING_DIR/etc/localtime |
|
52 |
+ |
|
53 |
+# Add stack user |
|
54 |
+chroot $STAGING_DIR groupadd libvirtd |
|
55 |
+chroot $STAGING_DIR useradd stack -s /bin/bash -d /opt/stack -G libvirtd |
|
56 |
+echo stack:$PASSWORD | chroot $STAGING_DIR chpasswd |
|
57 |
+echo "stack ALL=(ALL) NOPASSWD: ALL" >> $STAGING_DIR/etc/sudoers |
|
58 |
+ |
|
59 |
+# Give ownership of /opt/stack to stack user |
|
60 |
+chroot $STAGING_DIR chown -R stack /opt/stack |
|
61 |
+ |
|
62 |
+# Make our ip address hostnames look nice at the command prompt |
|
63 |
+echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $STAGING_DIR/opt/stack/.bashrc |
|
64 |
+echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $STAGING_DIR/root/.bashrc |
|
65 |
+echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> $STAGING_DIR/etc/profile |
|
66 |
+ |
|
67 |
+function setup_vimrc { |
|
68 |
+ if [ ! -e $1 ]; then |
|
69 |
+ # Simple but usable vimrc |
|
70 |
+ cat > $1 <<EOF |
|
71 |
+syntax on |
|
72 |
+se ts=4 |
|
73 |
+se expandtab |
|
74 |
+se shiftwidth=4 |
|
75 |
+EOF |
|
76 |
+ fi |
|
77 |
+} |
|
78 |
+ |
|
79 |
+# Setup simple .vimrcs |
|
80 |
+setup_vimrc $STAGING_DIR/root/.vimrc |
|
81 |
+setup_vimrc $STAGING_DIR/opt/stack/.vimrc |
|
82 |
+ |
|
83 |
+if [ "$DO_TGZ" = "1" ]; then |
|
84 |
+ # Compress |
|
85 |
+ rm -f stage.tgz |
|
86 |
+ tar cfz stage.tgz stage |
|
87 |
+fi |
0 | 88 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,508 @@ |
0 |
+#!/bin/bash |
|
1 |
+# |
|
2 |
+# Copyright (c) 2011 Citrix Systems, Inc. |
|
3 |
+# Copyright 2011 OpenStack LLC. |
|
4 |
+# Copyright (C) 2011 Nicira, Inc |
|
5 |
+# All Rights Reserved. |
|
6 |
+# |
|
7 |
+# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
8 |
+# not use this file except in compliance with the License. You may obtain |
|
9 |
+# a copy of the License at |
|
10 |
+# |
|
11 |
+# http://www.apache.org/licenses/LICENSE-2.0 |
|
12 |
+# |
|
13 |
+# Unless required by applicable law or agreed to in writing, software |
|
14 |
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
15 |
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
16 |
+# License for the specific language governing permissions and limitations |
|
17 |
+# under the License. |
|
18 |
+# |
|
19 |
+ |
|
20 |
+set -eux |
|
21 |
+ |
|
22 |
+. /etc/xensource-inventory |
|
23 |
+ |
|
24 |
+NAME="XenServer OpenStack VPX" |
|
25 |
+DATA_VDI_SIZE="500MiB" |
|
26 |
+BRIDGE_M= |
|
27 |
+BRIDGE_P= |
|
28 |
+KERNEL_PARAMS= |
|
29 |
+VPX_FILE=os-vpx.xva |
|
30 |
+AS_TEMPLATE= |
|
31 |
+FROM_TEMPLATE= |
|
32 |
+RAM= |
|
33 |
+WAIT_FOR_NETWORK= |
|
34 |
+BALLOONING= |
|
35 |
+ |
|
36 |
+usage() |
|
37 |
+{ |
|
38 |
+cat << EOF |
|
39 |
+ |
|
40 |
+ Usage: $0 [-f FILE_PATH] [-d DISK_SIZE] [-v BRIDGE_NAME] [-m BRIDGE_NAME] [-p BRIDGE_NAME] |
|
41 |
+ [-k PARAMS] [-r RAM] [-i|-c] [-w] [-b] |
|
42 |
+ |
|
43 |
+ Installs XenServer OpenStack VPX. |
|
44 |
+ |
|
45 |
+ OPTIONS: |
|
46 |
+ |
|
47 |
+ -h Shows this message. |
|
48 |
+ -i Install OpenStack VPX as template. |
|
49 |
+ -c Clone from existing template. |
|
50 |
+ -w Wait for the network settings to show up before exiting. |
|
51 |
+ -b Enable memory ballooning. When set min_RAM=RAM/2 max_RAM=RAM. |
|
52 |
+ -f path Specifies the path to the XVA. |
|
53 |
+ Default to ./os-vpx.xva. |
|
54 |
+ -d disk-size Specifies the size in MiB for the data disk. |
|
55 |
+ Defaults to 500 MiB. |
|
56 |
+ -m bridge Specifies the bridge for the isolated management network. |
|
57 |
+ Defaults to xenbr0. |
|
58 |
+ -v bridge Specifies the bridge for the vm network |
|
59 |
+ -p bridge Specifies the bridge for the externally facing network. |
|
60 |
+ -k params Specifies kernel parameters. |
|
61 |
+ -r MiB Specifies RAM used by the VPX, in MiB. |
|
62 |
+ By default it will take the value from the XVA. |
|
63 |
+ |
|
64 |
+ EXAMPLES: |
|
65 |
+ |
|
66 |
+ Create a VPX that connects to the isolated management network using the |
|
67 |
+ default bridge with a data disk of 1GiB: |
|
68 |
+ install-os-vpx.sh -f /root/os-vpx-devel.xva -d 1024 |
|
69 |
+ |
|
70 |
+ Create a VPX that connects to the isolated management network using xenbr1 |
|
71 |
+ as bridge: |
|
72 |
+ install-os-vpx.sh -m xenbr1 |
|
73 |
+ |
|
74 |
+ Create a VPX that connects to both the management and public networks |
|
75 |
+ using xenbr1 and xapi4 as bridges: |
|
76 |
+ install-os-vpx.sh -m xenbr1 -p xapi4 |
|
77 |
+ |
|
78 |
+ Create a VPX that connects to both the management and public networks |
|
79 |
+ using the default for management traffic: |
|
80 |
+ install-os-vpx.sh -m xapi4 |
|
81 |
+ |
|
82 |
+ Create a VPX that automatically becomes the master: |
|
83 |
+ install-os-vpx.sh -k geppetto_master=true |
|
84 |
+ |
|
85 |
+EOF |
|
86 |
+} |
|
87 |
+ |
|
88 |
+get_params() |
|
89 |
+{ |
|
90 |
+ while getopts "hicwbf:d:v:m:p:k:r:" OPTION; |
|
91 |
+ do |
|
92 |
+ case $OPTION in |
|
93 |
+ h) usage |
|
94 |
+ exit 1 |
|
95 |
+ ;; |
|
96 |
+ i) |
|
97 |
+ AS_TEMPLATE=1 |
|
98 |
+ ;; |
|
99 |
+ c) |
|
100 |
+ FROM_TEMPLATE=1 |
|
101 |
+ ;; |
|
102 |
+ w) |
|
103 |
+ WAIT_FOR_NETWORK=1 |
|
104 |
+ ;; |
|
105 |
+ b) |
|
106 |
+ BALLOONING=1 |
|
107 |
+ ;; |
|
108 |
+ f) |
|
109 |
+ VPX_FILE=$OPTARG |
|
110 |
+ ;; |
|
111 |
+ d) |
|
112 |
+ DATA_VDI_SIZE="${OPTARG}MiB" |
|
113 |
+ ;; |
|
114 |
+ m) |
|
115 |
+ BRIDGE_M=$OPTARG |
|
116 |
+ ;; |
|
117 |
+ p) |
|
118 |
+ BRIDGE_P=$OPTARG |
|
119 |
+ ;; |
|
120 |
+ k) |
|
121 |
+ KERNEL_PARAMS=$OPTARG |
|
122 |
+ ;; |
|
123 |
+ r) |
|
124 |
+ RAM=$OPTARG |
|
125 |
+ ;; |
|
126 |
+ v) |
|
127 |
+ BRIDGE_V=$OPTARG |
|
128 |
+ ;; |
|
129 |
+ ?) |
|
130 |
+ usage |
|
131 |
+ exit |
|
132 |
+ ;; |
|
133 |
+ esac |
|
134 |
+ done |
|
135 |
+ if [[ -z $BRIDGE_M ]] |
|
136 |
+ then |
|
137 |
+ BRIDGE_M=xenbr0 |
|
138 |
+ fi |
|
139 |
+} |
|
140 |
+ |
|
141 |
+ |
|
142 |
+xe_min() |
|
143 |
+{ |
|
144 |
+ local cmd="$1" |
|
145 |
+ shift |
|
146 |
+ xe "$cmd" --minimal "$@" |
|
147 |
+} |
|
148 |
+ |
|
149 |
+ |
|
150 |
+get_dest_sr() |
|
151 |
+{ |
|
152 |
+ IFS=, |
|
153 |
+ sr_uuids=$(xe sr-list --minimal other-config:i18n-key=local-storage) |
|
154 |
+ dest_sr="" |
|
155 |
+ for sr_uuid in $sr_uuids |
|
156 |
+ do |
|
157 |
+ pbd=$(xe pbd-list --minimal sr-uuid=$sr_uuid host-uuid=$INSTALLATION_UUID) |
|
158 |
+ if [ "$pbd" ] |
|
159 |
+ then |
|
160 |
+ echo "$sr_uuid" |
|
161 |
+ unset IFS |
|
162 |
+ return |
|
163 |
+ fi |
|
164 |
+ done |
|
165 |
+ unset IFS |
|
166 |
+ |
|
167 |
+ dest_sr=$(xe_min sr-list uuid=$(xe_min pool-list params=default-SR)) |
|
168 |
+ if [ "$dest_sr" = "" ] |
|
169 |
+ then |
|
170 |
+ echo "No local storage and no default storage; cannot import VPX." >&2 |
|
171 |
+ exit 1 |
|
172 |
+ else |
|
173 |
+ echo "$dest_sr" |
|
174 |
+ fi |
|
175 |
+} |
|
176 |
+ |
|
177 |
+ |
|
178 |
+find_network() |
|
179 |
+{ |
|
180 |
+ result=$(xe_min network-list bridge="$1") |
|
181 |
+ if [ "$result" = "" ] |
|
182 |
+ then |
|
183 |
+ result=$(xe_min network-list name-label="$1") |
|
184 |
+ fi |
|
185 |
+ echo "$result" |
|
186 |
+} |
|
187 |
+ |
|
188 |
+ |
|
189 |
+find_template() |
|
190 |
+{ |
|
191 |
+ xe_min template-list other-config:os-vpx=true |
|
192 |
+} |
|
193 |
+ |
|
194 |
+ |
|
195 |
+renumber_system_disk() |
|
196 |
+{ |
|
197 |
+ local v="$1" |
|
198 |
+ local vdi_uuid=$(xe_min vbd-list vm-uuid="$v" type=Disk userdevice=xvda \ |
|
199 |
+ params=vdi-uuid) |
|
200 |
+ if [ "$vdi_uuid" ] |
|
201 |
+ then |
|
202 |
+ local vbd_uuid=$(xe_min vbd-list vm-uuid="$v" vdi-uuid="$vdi_uuid") |
|
203 |
+ xe vbd-destroy uuid="$vbd_uuid" |
|
204 |
+ local new_vbd_uuid=$(xe vbd-create vm-uuid="$v" vdi-uuid="$vdi_uuid" \ |
|
205 |
+ device=0 bootable=true type=Disk) |
|
206 |
+ xe vbd-param-set other-config:owner uuid="$new_vbd_uuid" |
|
207 |
+ fi |
|
208 |
+} |
|
209 |
+ |
|
210 |
+ |
|
211 |
+create_vif() |
|
212 |
+{ |
|
213 |
+ xe vif-create vm-uuid="$1" network-uuid="$2" device="$3" |
|
214 |
+} |
|
215 |
+ |
|
216 |
+create_gi_vif() |
|
217 |
+{ |
|
218 |
+ local v="$1" |
|
219 |
+ # Note that we've made the outbound device eth1, so that it comes up after |
|
220 |
+ # the guest installer VIF, which means that the outbound one wins in terms |
|
221 |
+ # of gateway. |
|
222 |
+ local gi_network_uuid=$(xe_min network-list \ |
|
223 |
+ other-config:is_guest_installer_network=true) |
|
224 |
+ create_vif "$v" "$gi_network_uuid" "0" >/dev/null |
|
225 |
+} |
|
226 |
+ |
|
227 |
+create_vm_vif() |
|
228 |
+{ |
|
229 |
+ local v="$1" |
|
230 |
+ echo "Installing management interface on $BRIDGE_V." |
|
231 |
+ local out_network_uuid=$(find_network "$BRIDGE_V") |
|
232 |
+ create_vif "$v" "$out_network_uuid" "1" >/dev/null |
|
233 |
+} |
|
234 |
+ |
|
235 |
+create_management_vif() |
|
236 |
+{ |
|
237 |
+ local v="$1" |
|
238 |
+ echo "Installing management interface on $BRIDGE_M." |
|
239 |
+ local out_network_uuid=$(find_network "$BRIDGE_M") |
|
240 |
+ create_vif "$v" "$out_network_uuid" "2" >/dev/null |
|
241 |
+} |
|
242 |
+ |
|
243 |
+ |
|
244 |
+# This installs the interface for public traffic, only if a bridge is specified |
|
245 |
+# The interface is not configured at this stage, but it will be, once the admin |
|
246 |
+# tasks are complete for the services of this VPX |
|
247 |
+create_public_vif() |
|
248 |
+{ |
|
249 |
+ local v="$1" |
|
250 |
+ if [[ -z $BRIDGE_P ]] |
|
251 |
+ then |
|
252 |
+ echo "Skipping installation of interface for public traffic." |
|
253 |
+ else |
|
254 |
+ echo "Installing public interface on $BRIDGE_P." |
|
255 |
+ pub_network_uuid=$(find_network "$BRIDGE_P") |
|
256 |
+ create_vif "$v" "$pub_network_uuid" "3" >/dev/null |
|
257 |
+ fi |
|
258 |
+} |
|
259 |
+ |
|
260 |
+ |
|
261 |
+label_system_disk() |
|
262 |
+{ |
|
263 |
+ local v="$1" |
|
264 |
+ local vdi_uuid=$(xe_min vbd-list vm-uuid="$v" type=Disk userdevice=0 \ |
|
265 |
+ params=vdi-uuid) |
|
266 |
+ xe vdi-param-set \ |
|
267 |
+ name-label="$NAME system disk" \ |
|
268 |
+ other-config:os-vpx=true \ |
|
269 |
+ uuid=$vdi_uuid |
|
270 |
+} |
|
271 |
+ |
|
272 |
+ |
|
273 |
+create_data_disk() |
|
274 |
+{ |
|
275 |
+ local v="$1" |
|
276 |
+ |
|
277 |
+ local sys_vdi_uuid=$(xe_min vbd-list vm-uuid="$v" type=Disk params=vdi-uuid) |
|
278 |
+ local data_vdi_uuid=$(xe_min vdi-list other-config:os-vpx-data=true) |
|
279 |
+ |
|
280 |
+ if echo "$data_vdi_uuid" | grep -q , |
|
281 |
+ then |
|
282 |
+ echo "Multiple data disks found -- assuming that you want a new one." |
|
283 |
+ data_vdi_uuid="" |
|
284 |
+ else |
|
285 |
+ data_in_use=$(xe_min vbd-list vdi-uuid="$data_vdi_uuid") |
|
286 |
+ if [ "$data_in_use" != "" ] |
|
287 |
+ then |
|
288 |
+ echo "Data disk already in use -- will create another one." |
|
289 |
+ data_vdi_uuid="" |
|
290 |
+ fi |
|
291 |
+ fi |
|
292 |
+ |
|
293 |
+ if [ "$data_vdi_uuid" = "" ] |
|
294 |
+ then |
|
295 |
+ echo -n "Creating new data disk ($DATA_VDI_SIZE)... " |
|
296 |
+ sr_uuid=$(xe_min vdi-list params=sr-uuid uuid="$sys_vdi_uuid") |
|
297 |
+ data_vdi_uuid=$(xe vdi-create name-label="$NAME data disk" \ |
|
298 |
+ sr-uuid="$sr_uuid" \ |
|
299 |
+ type=user \ |
|
300 |
+ virtual-size="$DATA_VDI_SIZE") |
|
301 |
+ xe vdi-param-set \ |
|
302 |
+ other-config:os-vpx-data=true \ |
|
303 |
+ uuid="$data_vdi_uuid" |
|
304 |
+ dom0_uuid=$(xe_min vm-list is-control-domain=true) |
|
305 |
+ vbd_uuid=$(xe vbd-create device=autodetect type=Disk \ |
|
306 |
+ vdi-uuid="$data_vdi_uuid" vm-uuid="$dom0_uuid") |
|
307 |
+ xe vbd-plug uuid=$vbd_uuid |
|
308 |
+ dev=$(xe_min vbd-list params=device uuid=$vbd_uuid) |
|
309 |
+ mke2fs -q -j -m0 /dev/$dev |
|
310 |
+ e2label /dev/$dev vpxstate |
|
311 |
+ xe vbd-unplug uuid=$vbd_uuid |
|
312 |
+ xe vbd-destroy uuid=$vbd_uuid |
|
313 |
+ else |
|
314 |
+ echo -n "Attaching old data disk... " |
|
315 |
+ fi |
|
316 |
+ vbd_uuid=$(xe vbd-create device=2 type=Disk \ |
|
317 |
+ vdi-uuid="$data_vdi_uuid" vm-uuid="$v") |
|
318 |
+ xe vbd-param-set other-config:os-vpx-data=true uuid=$vbd_uuid |
|
319 |
+ echo "done." |
|
320 |
+} |
|
321 |
+ |
|
322 |
+ |
|
323 |
+set_kernel_params() |
|
324 |
+{ |
|
325 |
+ local v="$1" |
|
326 |
+ local args=$KERNEL_PARAMS |
|
327 |
+ local cmdline=$(cat /proc/cmdline) |
|
328 |
+ for word in $cmdline |
|
329 |
+ do |
|
330 |
+ if echo "$word" | grep -q "geppetto" |
|
331 |
+ then |
|
332 |
+ args="$word $args" |
|
333 |
+ fi |
|
334 |
+ done |
|
335 |
+ if [ "$args" != "" ] |
|
336 |
+ then |
|
337 |
+ echo "Passing Geppetto args to VPX: $args." |
|
338 |
+ xe vm-param-set PV-args="$args" uuid="$v" |
|
339 |
+ fi |
|
340 |
+} |
|
341 |
+ |
|
342 |
+ |
|
343 |
+set_memory() |
|
344 |
+{ |
|
345 |
+ local v="$1" |
|
346 |
+ if [ "$RAM" != "" ] |
|
347 |
+ then |
|
348 |
+ echo "Setting RAM to $RAM MiB." |
|
349 |
+ [ "$BALLOONING" == 1 ] && RAM_MIN=$(($RAM / 2)) || RAM_MIN=$RAM |
|
350 |
+ xe vm-memory-limits-set static-min=16MiB static-max=${RAM}MiB \ |
|
351 |
+ dynamic-min=${RAM_MIN}MiB dynamic-max=${RAM}MiB \ |
|
352 |
+ uuid="$v" |
|
353 |
+ fi |
|
354 |
+} |
|
355 |
+ |
|
356 |
+ |
|
357 |
+# Make the VM auto-start on server boot. |
|
358 |
+set_auto_start() |
|
359 |
+{ |
|
360 |
+ local v="$1" |
|
361 |
+ xe vm-param-set uuid="$v" other-config:auto_poweron=true |
|
362 |
+} |
|
363 |
+ |
|
364 |
+ |
|
365 |
+set_all() |
|
366 |
+{ |
|
367 |
+ local v="$1" |
|
368 |
+ set_kernel_params "$v" |
|
369 |
+ set_memory "$v" |
|
370 |
+ set_auto_start "$v" |
|
371 |
+ label_system_disk "$v" |
|
372 |
+ create_gi_vif "$v" |
|
373 |
+ create_vm_vif "$v" |
|
374 |
+ create_management_vif "$v" |
|
375 |
+ create_public_vif "$v" |
|
376 |
+} |
|
377 |
+ |
|
378 |
+ |
|
379 |
+log_vifs() |
|
380 |
+{ |
|
381 |
+ local v="$1" |
|
382 |
+ |
|
383 |
+ (IFS=, |
|
384 |
+ for vif in $(xe_min vif-list vm-uuid="$v") |
|
385 |
+ do |
|
386 |
+ dev=$(xe_min vif-list uuid="$vif" params=device) |
|
387 |
+ mac=$(xe_min vif-list uuid="$vif" params=MAC | sed -e 's/:/-/g') |
|
388 |
+ echo "eth$dev has MAC $mac." |
|
389 |
+ done |
|
390 |
+ unset IFS) | sort |
|
391 |
+} |
|
392 |
+ |
|
393 |
+ |
|
394 |
+destroy_vifs() |
|
395 |
+{ |
|
396 |
+ local v="$1" |
|
397 |
+ IFS=, |
|
398 |
+ for vif in $(xe_min vif-list vm-uuid="$v") |
|
399 |
+ do |
|
400 |
+ xe vif-destroy uuid="$vif" |
|
401 |
+ done |
|
402 |
+ unset IFS |
|
403 |
+} |
|
404 |
+ |
|
405 |
+ |
|
406 |
+get_params "$@" |
|
407 |
+ |
|
408 |
+thisdir=$(dirname "$0") |
|
409 |
+ |
|
410 |
+if [ "$FROM_TEMPLATE" ] |
|
411 |
+then |
|
412 |
+ template_uuid=$(find_template) |
|
413 |
+ name=$(xe_min template-list params=name-label uuid="$template_uuid") |
|
414 |
+ echo -n "Cloning $name... " |
|
415 |
+ vm_uuid=$(xe vm-clone vm="$template_uuid" new-name-label="$name") |
|
416 |
+ xe vm-param-set is-a-template=false uuid="$vm_uuid" |
|
417 |
+ echo $vm_uuid. |
|
418 |
+ |
|
419 |
+ destroy_vifs "$vm_uuid" |
|
420 |
+ set_all "$vm_uuid" |
|
421 |
+else |
|
422 |
+ if [ ! -f "$VPX_FILE" ] |
|
423 |
+ then |
|
424 |
+ # Search $thisdir/$VPX_FILE too. In particular, this is used when |
|
425 |
+ # installing the VPX from the supp-pack, because we want to be able to |
|
426 |
+ # invoke this script from the RPM and the firstboot script. |
|
427 |
+ if [ -f "$thisdir/$VPX_FILE" ] |
|
428 |
+ then |
|
429 |
+ VPX_FILE="$thisdir/$VPX_FILE" |
|
430 |
+ else |
|
431 |
+ echo "$VPX_FILE does not exist." >&2 |
|
432 |
+ exit 1 |
|
433 |
+ fi |
|
434 |
+ fi |
|
435 |
+ |
|
436 |
+ echo "Found OS-VPX File: $VPX_FILE. " |
|
437 |
+ |
|
438 |
+ dest_sr=$(get_dest_sr) |
|
439 |
+ |
|
440 |
+ echo -n "Installing $NAME... " |
|
441 |
+ vm_uuid=$(xe vm-import filename=$VPX_FILE sr-uuid="$dest_sr") |
|
442 |
+ echo $vm_uuid. |
|
443 |
+ |
|
444 |
+ renumber_system_disk "$vm_uuid" |
|
445 |
+ |
|
446 |
+ nl=$(xe_min vm-list params=name-label uuid=$vm_uuid) |
|
447 |
+ xe vm-param-set \ |
|
448 |
+ "name-label=${nl/ import/}" \ |
|
449 |
+ other-config:os-vpx=true \ |
|
450 |
+ uuid=$vm_uuid |
|
451 |
+ |
|
452 |
+ set_all "$vm_uuid" |
|
453 |
+ create_data_disk "$vm_uuid" |
|
454 |
+ |
|
455 |
+ if [ "$AS_TEMPLATE" ] |
|
456 |
+ then |
|
457 |
+ xe vm-param-set uuid="$vm_uuid" is-a-template=true \ |
|
458 |
+ other-config:instant=true |
|
459 |
+ echo -n "Installing VPX from template... " |
|
460 |
+ vm_uuid=$(xe vm-clone vm="$vm_uuid" new-name-label="${nl/ import/}") |
|
461 |
+ xe vm-param-set is-a-template=false uuid="$vm_uuid" |
|
462 |
+ echo "$vm_uuid." |
|
463 |
+ fi |
|
464 |
+fi |
|
465 |
+ |
|
466 |
+ |
|
467 |
+log_vifs "$vm_uuid" |
|
468 |
+ |
|
469 |
+echo -n "Starting VM... " |
|
470 |
+xe vm-start uuid=$vm_uuid |
|
471 |
+echo "done." |
|
472 |
+ |
|
473 |
+ |
|
474 |
+show_ip() |
|
475 |
+{ |
|
476 |
+ ip_addr=$(echo "$1" | sed -n "s,^.*"$2"/ip: \([^;]*\).*$,\1,p") |
|
477 |
+ echo -n "IP address for $3: " |
|
478 |
+ if [ "$ip_addr" = "" ] |
|
479 |
+ then |
|
480 |
+ echo "did not appear." |
|
481 |
+ else |
|
482 |
+ echo "$ip_addr." |
|
483 |
+ fi |
|
484 |
+} |
|
485 |
+ |
|
486 |
+ |
|
487 |
+if [ "$WAIT_FOR_NETWORK" ] |
|
488 |
+then |
|
489 |
+ echo "Waiting for network configuration... " |
|
490 |
+ i=0 |
|
491 |
+ while [ $i -lt 600 ] |
|
492 |
+ do |
|
493 |
+ ip=$(xe_min vm-list params=networks uuid=$vm_uuid) |
|
494 |
+ if [ "$ip" != "<not in database>" ] |
|
495 |
+ then |
|
496 |
+ show_ip "$ip" "1" "$BRIDGE_M" |
|
497 |
+ if [[ $BRIDGE_P ]] |
|
498 |
+ then |
|
499 |
+ show_ip "$ip" "2" "$BRIDGE_P" |
|
500 |
+ fi |
|
501 |
+ echo "Installation complete." |
|
502 |
+ exit 0 |
|
503 |
+ fi |
|
504 |
+ sleep 10 |
|
505 |
+ let i=i+1 |
|
506 |
+ done |
|
507 |
+fi |
0 | 508 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,366 @@ |
0 |
+#!/bin/bash |
|
1 |
+# |
|
2 |
+# Copyright (c) 2011 Citrix Systems, Inc. |
|
3 |
+# Copyright 2011 OpenStack LLC. |
|
4 |
+# Copyright (C) 2011 Nicira, Inc |
|
5 |
+# All Rights Reserved. |
|
6 |
+# |
|
7 |
+# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
8 |
+# not use this file except in compliance with the License. You may obtain |
|
9 |
+# a copy of the License at |
|
10 |
+# |
|
11 |
+# http://www.apache.org/licenses/LICENSE-2.0 |
|
12 |
+# |
|
13 |
+# Unless required by applicable law or agreed to in writing, software |
|
14 |
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
15 |
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
16 |
+# License for the specific language governing permissions and limitations |
|
17 |
+# under the License. |
|
18 |
+# |
|
19 |
+ |
|
20 |
+set -eu |
|
21 |
+ |
|
22 |
+set -o xtrace |
|
23 |
+ |
|
24 |
+VBOX_IMG=/output/packages/vbox-img |
|
25 |
+ |
|
26 |
+usage() { |
|
27 |
+ cat >&2 <<EOF |
|
28 |
+$0 -o <output filenames> -t <types> -x <xml files> <fs-staging-dir> <fs-size-MiB> <tmpdir> |
|
29 |
+ -o: Colon-separated list of output filenames (one for each type). |
|
30 |
+ -p: Create a disk label and partition within the output image |
|
31 |
+ -t: Colon-separated list of types of output file. xva and ovf supported. |
|
32 |
+ -x: XML filenames (one for each type) |
|
33 |
+ |
|
34 |
+EOF |
|
35 |
+ exit 1 |
|
36 |
+} |
|
37 |
+ |
|
38 |
+# parse cmdline |
|
39 |
+ |
|
40 |
+OPT_USE_PARTITION= |
|
41 |
+OPT_TYPES= |
|
42 |
+OPT_OUTPUT_FILES= |
|
43 |
+OPT_XML_FILES= |
|
44 |
+ |
|
45 |
+while getopts o:pt:x: o |
|
46 |
+do case "$o" in |
|
47 |
+ o) OPT_OUTPUT_FILES=$(echo "$OPTARG" | sed -e 's/\s*:\s*/ /g') |
|
48 |
+ ;; |
|
49 |
+ p) OPT_USE_PARTITION=1 |
|
50 |
+ ;; |
|
51 |
+ t) OPT_TYPES=$(echo "$OPTARG" | sed -e 's/\s*:\s*/ /g') |
|
52 |
+ ;; |
|
53 |
+ x) OPT_XML_FILES=$(echo "$OPTARG" | sed -e 's/\s*:\s*/ /g') |
|
54 |
+ ;; |
|
55 |
+ [?]) usage |
|
56 |
+ ;; |
|
57 |
+ esac |
|
58 |
+done |
|
59 |
+shift $((OPTIND-1)) |
|
60 |
+ |
|
61 |
+[ $# -ne 3 ] && usage |
|
62 |
+FS_STAGING="$1" |
|
63 |
+FS_SIZE_MIB="$2" |
|
64 |
+TMPDIR="$3" |
|
65 |
+ |
|
66 |
+if [ "$UID" = "0" ] |
|
67 |
+then |
|
68 |
+ SUDO= |
|
69 |
+else |
|
70 |
+ SUDO=sudo |
|
71 |
+fi |
|
72 |
+ |
|
73 |
+if [ "$FS_SIZE_MIB" = "0" ] |
|
74 |
+then |
|
75 |
+ # Just create a dummy file. This allows developers to bypass bits of |
|
76 |
+ # the build by setting the size to 0. |
|
77 |
+ touch $OPT_OUTPUT_FILES |
|
78 |
+ exit 0 |
|
79 |
+fi |
|
80 |
+ |
|
81 |
+# create temporary files and dirs |
|
82 |
+FS_TMPFILE=$(mktemp "$TMPDIR/mkxva-fsimg-XXXXX") |
|
83 |
+XVA_TARBALL_STAGING=$(mktemp -d "$TMPDIR/mkxva-tarball-staging-XXXXX") |
|
84 |
+OVF_STAGING=$(mktemp -d "$TMPDIR/mkxva-ovf-staging-XXXXX") |
|
85 |
+ |
|
86 |
+# Find udevsettle and udevtrigger on this installation |
|
87 |
+if [ -x "/sbin/udevsettle" ] ; then |
|
88 |
+ UDEVSETTLE="/sbin/udevsettle --timeout=30" |
|
89 |
+elif [ -x "/sbin/udevadm" ] ; then |
|
90 |
+ UDEVSETTLE='/sbin/udevadm settle' |
|
91 |
+else |
|
92 |
+ UDEVSETTLE='/bin/true' |
|
93 |
+fi |
|
94 |
+ |
|
95 |
+if [ -x "/sbin/udevtrigger" ] ; then |
|
96 |
+ UDEVTRIGGER=/sbin/udevtrigger |
|
97 |
+elif [ -x "/sbin/udevadm" ] ; then |
|
98 |
+ UDEVTRIGGER='/sbin/udevadm trigger' |
|
99 |
+else |
|
100 |
+ UDEVTRIGGER= |
|
101 |
+fi |
|
102 |
+ |
|
103 |
+# CLEAN_ variables track devices and mounts that must be taken down |
|
104 |
+# no matter how the script exits. Loop devices are vulnerable to |
|
105 |
+# exhaustion so we make every effort to remove them |
|
106 |
+ |
|
107 |
+CLEAN_KPARTX= |
|
108 |
+CLEAN_LOSETUP= |
|
109 |
+CLEAN_MOUNTPOINT= |
|
110 |
+ |
|
111 |
+cleanup_devices () { |
|
112 |
+ if [ -n "$CLEAN_MOUNTPOINT" ] ; then |
|
113 |
+ echo "Mountpoint $CLEAN_MOUNTPOINT removed on abnormal exit" |
|
114 |
+ $SUDO umount "$CLEAN_MOUNTPOINT" || echo "umount failed" |
|
115 |
+ rmdir "$CLEAN_MOUNTPOINT" || echo "rmdir failed" |
|
116 |
+ fi |
|
117 |
+ if [ -n "$CLEAN_KPARTX" ] ; then |
|
118 |
+ echo "kpartx devices for $CLEAN_KPARTX removed on abnormal exit" |
|
119 |
+ $SUDO kpartx -d "$CLEAN_KPARTX" || echo "kpartx -d failed" |
|
120 |
+ fi |
|
121 |
+ if [ -n "$CLEAN_LOSETUP" ] ; then |
|
122 |
+ echo "Loop device $CLEAN_LOSETUP removed on abnormal exit" |
|
123 |
+ $SUDO losetup -d "$CLEAN_LOSETUP" # Allow losetup errors to propagate |
|
124 |
+ fi |
|
125 |
+} |
|
126 |
+ |
|
127 |
+trap "cleanup_devices" EXIT |
|
128 |
+ |
|
129 |
+make_fs_inner () { |
|
130 |
+ local staging="$1" |
|
131 |
+ local output="$2" |
|
132 |
+ local options="$3" |
|
133 |
+ CLEAN_MOUNTPOINT=$(mktemp -d "$TMPDIR/mkfs-XXXXXX") |
|
134 |
+ |
|
135 |
+ # copy staging dir contents to fs image |
|
136 |
+ $SUDO mount $options "$output" "$CLEAN_MOUNTPOINT" |
|
137 |
+ $SUDO tar -C "$staging" -c . | tar -C "$CLEAN_MOUNTPOINT" -x |
|
138 |
+ $SUDO umount "$CLEAN_MOUNTPOINT" |
|
139 |
+ rmdir "$CLEAN_MOUNTPOINT" |
|
140 |
+ CLEAN_MOUNTPOINT= |
|
141 |
+} |
|
142 |
+ |
|
143 |
+# Turn a staging dir into an ext3 filesystem within a partition |
|
144 |
+make_fs_in_partition () { |
|
145 |
+ local staging="$1" |
|
146 |
+ local output="$2" |
|
147 |
+ |
|
148 |
+ # create new empty disk |
|
149 |
+ dd if=/dev/zero of="$output" bs=1M count=$FS_SIZE_MIB |
|
150 |
+ # Set up a loop device on the empty disk image |
|
151 |
+ local loopdevice=$($SUDO losetup -f) |
|
152 |
+ $SUDO losetup "$loopdevice" "$output" |
|
153 |
+ CLEAN_LOSETUP="$loopdevice" |
|
154 |
+ # Create a partition table and single partition. |
|
155 |
+ # Start partition at sector 63 to allow space for grub |
|
156 |
+ cat <<EOF |
|
157 |
+Errors from sfdisk below are expected because the new disk is uninitialised |
|
158 |
+ Expecting: sfdisk: ERROR: sector 0 does not have an msdos signature |
|
159 |
+ Expecting: /dev/loop0: unrecognized partition table type |
|
160 |
+EOF |
|
161 |
+ $SUDO sfdisk -uS "$CLEAN_LOSETUP" <<EOF |
|
162 |
+63 - - * |
|
163 |
+EOF |
|
164 |
+ |
|
165 |
+ # kpartx creates a device for the new partition |
|
166 |
+ # in the form /dev/mapper/loop1p1 |
|
167 |
+ $SUDO kpartx -av "$CLEAN_LOSETUP" |
|
168 |
+ CLEAN_KPARTX="$CLEAN_LOSETUP" |
|
169 |
+ # Wait for the device to appear |
|
170 |
+ $UDEVTRIGGER |
|
171 |
+ $UDEVSETTLE || echo "udev settle command return code non-zero" |
|
172 |
+ # Infer the name of the partition device |
|
173 |
+ local partition="${CLEAN_LOSETUP/dev/dev/mapper}p1" |
|
174 |
+ # Set permissive privileges on the device |
|
175 |
+ $SUDO chmod 0777 "$partition" |
|
176 |
+ # Make an ext3 filesystem on the partition |
|
177 |
+ /sbin/mkfs.ext3 -I 128 -m0 -F "$partition" |
|
178 |
+ /sbin/e2label "$partition" vpxroot |
|
179 |
+ make_fs_inner "$staging" "$partition" "" |
|
180 |
+ |
|
181 |
+ # Now run grub on the image we've created |
|
182 |
+ CLEAN_MOUNTPOINT=$(mktemp -d "$TMPDIR/mkfs-XXXXXX") |
|
183 |
+ |
|
184 |
+ # copy Set up[ grub files prior to installing grub within the image |
|
185 |
+ $SUDO mount "$partition" "$CLEAN_MOUNTPOINT" |
|
186 |
+ $SUDO cp $CLEAN_MOUNTPOINT/usr/share/grub/i386-redhat/* "$CLEAN_MOUNTPOINT/boot/grub" |
|
187 |
+ kernel_version=$($SUDO chroot "$CLEAN_MOUNTPOINT" rpm -qv kernel | sed -e 's/kernel-//') |
|
188 |
+ kernel_version_xen=$($SUDO chroot "$CLEAN_MOUNTPOINT" rpm -qv kernel-xen | sed -e 's/kernel-xen-//') |
|
189 |
+ $SUDO cat > "$CLEAN_MOUNTPOINT/boot/grub/grub.conf" <<EOF |
|
190 |
+default 0 |
|
191 |
+timeout 2 |
|
192 |
+ |
|
193 |
+title vmlinuz-$kernel_version (HVM) |
|
194 |
+ root (hd0,0) |
|
195 |
+ kernel /boot/vmlinuz-$kernel_version ro root=LABEL=vpxroot |
|
196 |
+ initrd /boot/initrd-$kernel_version.img |
|
197 |
+ |
|
198 |
+title vmlinuz-${kernel_version_xen}xen (PV) |
|
199 |
+ root (hd0,0) |
|
200 |
+ kernel /boot/vmlinuz-${kernel_version_xen}xen ro root=LABEL=vpxroot console=xvc0 |
|
201 |
+ initrd /boot/initrd-${kernel_version_xen}xen.img |
|
202 |
+EOF |
|
203 |
+ |
|
204 |
+ $SUDO umount "$CLEAN_MOUNTPOINT" |
|
205 |
+ CLEAN_MOUNTPOINT= |
|
206 |
+ |
|
207 |
+ # Grub expects a disk with name /dev/xxxx with a first partition |
|
208 |
+ # named /dev/xxxx1, so we give it what it wants using symlinks |
|
209 |
+ # Note: /dev is linked to the real /dev of the build machine, so |
|
210 |
+ # must be cleaned up |
|
211 |
+ local disk_name="/dev/osxva$$bld" |
|
212 |
+ local disk_part1_name="${disk_name}1" |
|
213 |
+ rm -f "$disk_name" |
|
214 |
+ rm -f "$disk_part1_name" |
|
215 |
+ ln -s "$CLEAN_LOSETUP" "$disk_name" |
|
216 |
+ ln -s "$partition" "$disk_part1_name" |
|
217 |
+ |
|
218 |
+ # Feed commands into the grub shell to setup the disk |
|
219 |
+ grub --no-curses --device-map=/dev/null <<EOF |
|
220 |
+device (hd0) $disk_name |
|
221 |
+setup (hd0) (hd0,0) |
|
222 |
+quit |
|
223 |
+EOF |
|
224 |
+ |
|
225 |
+ # Cleanup |
|
226 |
+ rm -f "$disk_name" |
|
227 |
+ rm -f "$disk_part1_name" |
|
228 |
+ $SUDO kpartx -dv "$CLEAN_KPARTX" |
|
229 |
+ CLEAN_KPARTX= |
|
230 |
+ $SUDO losetup -d "$CLEAN_LOSETUP" |
|
231 |
+ CLEAN_LOSETUP= |
|
232 |
+} |
|
233 |
+ |
|
234 |
+# turn a staging dir into an ext3 filesystem image |
|
235 |
+make_fs () { |
|
236 |
+ local staging="$1" |
|
237 |
+ local output="$2" |
|
238 |
+ |
|
239 |
+ # create new empty fs |
|
240 |
+ dd if=/dev/zero of="$output" bs=1M count=0 seek=$FS_SIZE_MIB |
|
241 |
+ /sbin/mkfs.ext3 -m0 -F "$output" |
|
242 |
+ /sbin/e2label "$output" vpxroot |
|
243 |
+ make_fs_inner "$staging" "$output" "-oloop" |
|
244 |
+} |
|
245 |
+ |
|
246 |
+ |
|
247 |
+# split a virtual disk image into the format expected inside an xva file |
|
248 |
+splitvdi () { |
|
249 |
+ local diskimg="$1" |
|
250 |
+ local outputdir="$2" |
|
251 |
+ local rio="$3" |
|
252 |
+ |
|
253 |
+ local n_bytes=$(stat --printf=%s "$diskimg") |
|
254 |
+ local n_meg=$((($n_bytes+$((1024*1024 -1)))/$((1024*1024)))) |
|
255 |
+ local i=0 |
|
256 |
+ while [ $i -lt $n_meg ] ; do |
|
257 |
+ if [ $rio -eq 0 ] ; then |
|
258 |
+ local file="$outputdir"/chunk-$(printf "%08d" $i) |
|
259 |
+ dd if="$diskimg" of="$file" skip=$i bs=1M count=1 2>/dev/null |
|
260 |
+ gzip "$file" |
|
261 |
+ else |
|
262 |
+ local file="$outputdir"/$(printf "%08d" $i) |
|
263 |
+ dd if="$diskimg" of="$file" skip=$i bs=1M count=1 2>/dev/null |
|
264 |
+ local chksum=$(sha1sum -b "$file") |
|
265 |
+ echo -n "${chksum/ */}" > "$file.checksum" |
|
266 |
+ fi |
|
267 |
+ i=$(($i + 1)) |
|
268 |
+ done |
|
269 |
+} |
|
270 |
+ |
|
271 |
+if [ -n "$OPT_USE_PARTITION" ] ; then |
|
272 |
+ make_fs_in_partition "$FS_STAGING" "$FS_TMPFILE" |
|
273 |
+else |
|
274 |
+ make_fs "$FS_STAGING" "$FS_TMPFILE" |
|
275 |
+fi |
|
276 |
+ |
|
277 |
+VDI_SIZE=$(stat --format=%s "$FS_TMPFILE") |
|
278 |
+ |
|
279 |
+make_xva () { |
|
280 |
+ local output_file="$1" |
|
281 |
+ local xml_file="$2" |
|
282 |
+ local subdir |
|
283 |
+ local rio |
|
284 |
+ |
|
285 |
+ if [[ `cat $xml_file` =~ "<member>\s*<name>class</name>\s*<value>VDI</value>\s*</member>\s*<member>\s*<name>id</name>\s*<value>(Ref:[0-9]+)</value>" ]] |
|
286 |
+ then |
|
287 |
+ # it's a rio style xva |
|
288 |
+ subdir="${BASH_REMATCH[1]}"; |
|
289 |
+ rio=1 |
|
290 |
+ else |
|
291 |
+ # it's a geneva style xva |
|
292 |
+ subdir="xvda" |
|
293 |
+ rio=0 |
|
294 |
+ fi |
|
295 |
+ |
|
296 |
+ cp "$xml_file" "$XVA_TARBALL_STAGING"/ova.xml |
|
297 |
+ sed -i -e "s/@VDI_SIZE@/$VDI_SIZE/" "$XVA_TARBALL_STAGING"/ova.xml |
|
298 |
+ mkdir "$XVA_TARBALL_STAGING/$subdir" |
|
299 |
+ splitvdi "$FS_TMPFILE" "$XVA_TARBALL_STAGING/$subdir" "$rio" |
|
300 |
+ TARFILE_MEMBERS=$(cd "$XVA_TARBALL_STAGING" && echo ova.xml $subdir/*) |
|
301 |
+ tar -C "$XVA_TARBALL_STAGING" --format=v7 -c $TARFILE_MEMBERS -f "$output_file.tmp" |
|
302 |
+ mv "$output_file.tmp" "$output_file" |
|
303 |
+} |
|
304 |
+ |
|
305 |
+make_ovf () { |
|
306 |
+ local output_dir="$1" |
|
307 |
+ local xml_file="$2" |
|
308 |
+ local output_base=$(basename "$output_dir") |
|
309 |
+ local disk="$output_dir/${output_base}.vmdk" |
|
310 |
+ local manifest="$output_dir/${output_base}.mf" |
|
311 |
+ local ovf="$output_dir/${output_base}.ovf" |
|
312 |
+ |
|
313 |
+ mkdir -p "$output_dir" |
|
314 |
+ rm -f "$disk" |
|
315 |
+ $VBOX_IMG convert --srcfilename="$FS_TMPFILE" --dstfilename="$disk" \ |
|
316 |
+ --srcformat RAW --dstformat VMDK --variant Stream |
|
317 |
+ chmod 0644 "$disk" |
|
318 |
+ |
|
319 |
+ local n_bytes=$(stat --printf=%s "$disk") |
|
320 |
+ cp "$xml_file" "$ovf" |
|
321 |
+ sed -i -e "s/@MKXVA_DISK_FULLSIZE@/$VDI_SIZE/" "$ovf" |
|
322 |
+ sed -i -e "s/@MKXVA_DISK_SIZE@/$n_bytes/" "$ovf" |
|
323 |
+ sed -i -e "s/@MKXVA_DISK_MIB_SIZE@/$FS_SIZE_MIB/" "$ovf" |
|
324 |
+ sed -i -e "s/@MKXVA_DISK_FILENAME@/${output_base}.vmdk/" "$ovf" |
|
325 |
+ |
|
326 |
+ for to_sign in "$ovf" "$disk" |
|
327 |
+ do |
|
328 |
+ local sha1_sum=$(sha1sum "$to_sign" | cut -d' ' -f1) |
|
329 |
+ echo "SHA1($(basename "$to_sign"))= $sha1_sum" >> $manifest |
|
330 |
+ done |
|
331 |
+} |
|
332 |
+ |
|
333 |
+output_files="$OPT_OUTPUT_FILES" |
|
334 |
+xml_files="$OPT_XML_FILES" |
|
335 |
+# Iterate through the type list creating the relevant VMs |
|
336 |
+for create_type in $OPT_TYPES |
|
337 |
+do |
|
338 |
+ # Shift one parameter from the front of the lists |
|
339 |
+ create_output_file="${output_files%% *}" |
|
340 |
+ output_files="${output_files#* }" |
|
341 |
+ create_xml_file="${xml_files%% *}" |
|
342 |
+ xml_files="${xml_files#* }" |
|
343 |
+ echo "Creating $create_type appliance $create_output_file using metadata file $create_xml_file" |
|
344 |
+ |
|
345 |
+ case "$create_type" in |
|
346 |
+ xva) |
|
347 |
+ make_xva "$create_output_file" "$create_xml_file" |
|
348 |
+ ;; |
|
349 |
+ ovf) |
|
350 |
+ make_ovf "$create_output_file" "$create_xml_file" |
|
351 |
+ ;; |
|
352 |
+ *) |
|
353 |
+ echo "Unknown VM type '$create_type'" |
|
354 |
+ exit 1 |
|
355 |
+ ;; |
|
356 |
+ esac |
|
357 |
+ |
|
358 |
+done |
|
359 |
+ |
|
360 |
+ |
|
361 |
+# cleanup |
|
362 |
+if [ -z "${DO_NOT_CLEANUP:-}" ] ; then |
|
363 |
+ rm -rf "$XVA_TARBALL_STAGING" |
|
364 |
+ rm -f "$FS_TMPFILE" |
|
365 |
+fi |
0 | 366 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,102 @@ |
0 |
+#!/bin/bash |
|
1 |
+# |
|
2 |
+# Copyright (c) 2011 Citrix Systems, Inc. |
|
3 |
+# Copyright 2011 OpenStack LLC. |
|
4 |
+# Copyright (C) 2011 Nicira, Inc |
|
5 |
+# All Rights Reserved. |
|
6 |
+# |
|
7 |
+# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
8 |
+# not use this file except in compliance with the License. You may obtain |
|
9 |
+# a copy of the License at |
|
10 |
+# |
|
11 |
+# http://www.apache.org/licenses/LICENSE-2.0 |
|
12 |
+# |
|
13 |
+# Unless required by applicable law or agreed to in writing, software |
|
14 |
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
15 |
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
16 |
+# License for the specific language governing permissions and limitations |
|
17 |
+# under the License. |
|
18 |
+# |
|
19 |
+ |
|
20 |
+remove_data= |
|
21 |
+if [ "$1" = "--remove-data" ] |
|
22 |
+then |
|
23 |
+ remove_data=1 |
|
24 |
+fi |
|
25 |
+ |
|
26 |
+set -eu |
|
27 |
+ |
|
28 |
+xe_min() |
|
29 |
+{ |
|
30 |
+ local cmd="$1" |
|
31 |
+ shift |
|
32 |
+ /opt/xensource/bin/xe "$cmd" --minimal "$@" |
|
33 |
+} |
|
34 |
+ |
|
35 |
+destroy_vdi() |
|
36 |
+{ |
|
37 |
+ local vbd_uuid="$1" |
|
38 |
+ local type=$(xe_min vbd-list uuid=$vbd_uuid params=type) |
|
39 |
+ local dev=$(xe_min vbd-list uuid=$vbd_uuid params=userdevice) |
|
40 |
+ local vdi_uuid=$(xe_min vbd-list uuid=$vbd_uuid params=vdi-uuid) |
|
41 |
+ |
|
42 |
+ if [ "$type" = 'Disk' ] && [ "$dev" != 'xvda' ] && [ "$dev" != '0' ] |
|
43 |
+ then |
|
44 |
+ echo -n "Destroying data disk... " |
|
45 |
+ xe vdi-destroy uuid=$vdi_uuid |
|
46 |
+ echo "done." |
|
47 |
+ fi |
|
48 |
+} |
|
49 |
+ |
|
50 |
+uninstall() |
|
51 |
+{ |
|
52 |
+ local vm_uuid="$1" |
|
53 |
+ local power_state=$(xe_min vm-list uuid=$vm_uuid params=power-state) |
|
54 |
+ |
|
55 |
+ if [ "$power_state" != "halted" ] |
|
56 |
+ then |
|
57 |
+ echo -n "Shutting down VM... " |
|
58 |
+ xe vm-shutdown vm=$vm_uuid force=true |
|
59 |
+ echo "done." |
|
60 |
+ fi |
|
61 |
+ |
|
62 |
+ if [ "$remove_data" = "1" ] |
|
63 |
+ then |
|
64 |
+ for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g') |
|
65 |
+ do |
|
66 |
+ destroy_vdi "$v" |
|
67 |
+ done |
|
68 |
+ fi |
|
69 |
+ |
|
70 |
+ echo -n "Deleting VM... " |
|
71 |
+ xe vm-uninstall vm=$vm_uuid force=true >/dev/null |
|
72 |
+ echo "done." |
|
73 |
+} |
|
74 |
+ |
|
75 |
+uninstall_template() |
|
76 |
+{ |
|
77 |
+ local vm_uuid="$1" |
|
78 |
+ |
|
79 |
+ if [ "$remove_data" = "1" ] |
|
80 |
+ then |
|
81 |
+ for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g') |
|
82 |
+ do |
|
83 |
+ destroy_vdi "$v" |
|
84 |
+ done |
|
85 |
+ fi |
|
86 |
+ |
|
87 |
+ echo -n "Deleting template... " |
|
88 |
+ xe template-uninstall template-uuid=$vm_uuid force=true >/dev/null |
|
89 |
+ echo "done." |
|
90 |
+} |
|
91 |
+ |
|
92 |
+ |
|
93 |
+for u in $(xe_min vm-list other-config:os-vpx=true | sed -e 's/,/ /g') |
|
94 |
+do |
|
95 |
+ uninstall "$u" |
|
96 |
+done |
|
97 |
+ |
|
98 |
+for u in $(xe_min template-list other-config:os-vpx=true | sed -e 's/,/ /g') |
|
99 |
+do |
|
100 |
+ uninstall_template "$u" |
|
101 |
+done |
0 | 8 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,21 @@ |
0 |
+auto lo |
|
1 |
+iface lo inet loopback |
|
2 |
+ |
|
3 |
+auto eth0 |
|
4 |
+iface eth0 inet dhcp |
|
5 |
+ |
|
6 |
+auto eth1 |
|
7 |
+iface eth1 inet static |
|
8 |
+ netmask @ETH1_NETMASK@ |
|
9 |
+post-up ethtool -K eth1 tx off |
|
10 |
+post-up ifconfig eth1 up |
|
11 |
+ |
|
12 |
+auto eth2 |
|
13 |
+iface eth2 inet static |
|
14 |
+ address @ETH2_IP@ |
|
15 |
+ netmask @ETH2_NETMASK@ |
|
16 |
+ |
|
17 |
+auto eth3 |
|
18 |
+iface eth3 inet static |
|
19 |
+ address @ETH3_IP@ |
|
20 |
+ netmask @ETH3_NETMASK@ |
0 | 6 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,14 @@ |
0 |
+<?xml version="1.0" ?> |
|
1 |
+<appliance version="0.1"> |
|
2 |
+ <vm name="vm"> |
|
3 |
+ <label> |
|
4 |
+ @PRODUCT_BRAND@ @PRODUCT_VERSION@-@BUILD_NUMBER@ |
|
5 |
+ </label> |
|
6 |
+ <shortdesc></shortdesc> |
|
7 |
+ <config mem_set="671088640" vcpus="1"/> |
|
8 |
+ <hacks is_hvm="false"/> |
|
9 |
+ <vbd device="xvda" function="root" mode="w" vdi="vdi_xvda"/> |
|
10 |
+ </vm> |
|
11 |
+ <vdi name="vdi_xvda" size="@VDI_SIZE@" source="file://xvda" type="dir-gzipped-chunks" variety="system"/> |
|
12 |
+</appliance> |
|
13 |
+ |