| ... | ... |
@@ -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 |
+ |