Improvements to DevStack's XenServer scripts

I have ensured:
- template gets re-used on second run
- template includes XenServer tools, and custom user accounts
- take snapshot before first boot, for easy re-run
- make host_ip_iface work with either eth2 or eth3
- make ssh into domU checks looser
- above is all ground work for improved jenkins tests
- added some more comments to make it scripts clearer

Change-Id: I5c45370bf8a1393d669480e196b13f592d29154f
This commit is contained in:
John Garbutt 2012-04-27 18:28:28 +01:00
parent d0e55c859a
commit daadf744ed
12 changed files with 453 additions and 208 deletions

View File

@ -81,3 +81,9 @@ Step 5: Do cloudy stuff!
* Play with horizon * Play with horizon
* Play with the CLI * Play with the CLI
* Log bugs to devstack and core projects, and submit fixes! * Log bugs to devstack and core projects, and submit fixes!
Step 6: Run from snapshot
-------------------------
If you want to quicky re-run devstack from a clean state,
using the same settings you used in your previous run,
you can revert the DomU to the snapshot called "before_first_boot"

View File

@ -1,46 +1,40 @@
#!/bin/bash #!/bin/bash
set -e # This script is run by install_os_domU.sh
#
# It modifies the ubuntu image created by install_os_domU.sh
# and previously moodified by prepare_guest_template.sh
#
# This script is responsible for:
# - pushing in the DevStack code
# - creating run.sh, to run the code on boot
# It does this by mounting the disk image of the VM.
#
# The resultant image is then templated and started
# by install_os_domU.sh
declare -a on_exit_hooks # Exit on errors
set -o errexit
on_exit() # Echo commands
{ set -o xtrace
for i in $(seq $((${#on_exit_hooks[*]} - 1)) -1 0)
do
eval "${on_exit_hooks[$i]}"
done
}
add_on_exit()
{
local n=${#on_exit_hooks[*]}
on_exit_hooks[$n]="$*"
if [[ $n -eq 0 ]]
then
trap on_exit EXIT
fi
}
# Abort if localrc is not set
if [ ! -e ../../localrc ]; then
echo "You must have a localrc with ALL necessary passwords defined before proceeding."
echo "See the xen README for required passwords."
exit 1
fi
# This directory # This directory
TOP_DIR=$(cd $(dirname "$0") && pwd) TOP_DIR=$(cd $(dirname "$0") && pwd)
# Include onexit commands
. $TOP_DIR/scripts/on_exit.sh
# Source params - override xenrc params in your localrc to suite your taste # Source params - override xenrc params in your localrc to suite your taste
source xenrc source xenrc
# Echo commands #
set -o xtrace # Parameters
#
GUEST_NAME="$1" GUEST_NAME="$1"
# Directory where we stage the build #
# Mount the VDI
#
STAGING_DIR=$($TOP_DIR/scripts/manage-vdi open $GUEST_NAME 0 1 | grep -o "/tmp/tmp.[[:alnum:]]*") STAGING_DIR=$($TOP_DIR/scripts/manage-vdi open $GUEST_NAME 0 1 | grep -o "/tmp/tmp.[[:alnum:]]*")
add_on_exit "$TOP_DIR/scripts/manage-vdi close $GUEST_NAME 0 1" add_on_exit "$TOP_DIR/scripts/manage-vdi close $GUEST_NAME 0 1"
@ -76,7 +70,7 @@ cd $TOP_DIR
cat <<EOF >$STAGING_DIR/etc/rc.local cat <<EOF >$STAGING_DIR/etc/rc.local
# network restart required for getting the right gateway # network restart required for getting the right gateway
/etc/init.d/networking restart /etc/init.d/networking restart
GUEST_PASSWORD=$GUEST_PASSWORD STAGING_DIR=/ DO_TGZ=0 bash /opt/stack/devstack/tools/xen/prepare_guest.sh > /opt/stack/prepare_guest.log 2>&1 chown -R stack /opt/stack
su -c "/opt/stack/run.sh > /opt/stack/run.sh.log 2>&1" stack su -c "/opt/stack/run.sh > /opt/stack/run.sh.log 2>&1" stack
exit 0 exit 0
EOF EOF
@ -85,8 +79,12 @@ EOF
echo $GUEST_NAME > $STAGING_DIR/etc/hostname echo $GUEST_NAME > $STAGING_DIR/etc/hostname
# Hostname must resolve for rabbit # Hostname must resolve for rabbit
HOSTS_FILE_IP=$PUB_IP
if [ $MGT_IP != "dhcp" ]; then
HOSTS_FILE_IP=$MGT_IP
fi
cat <<EOF >$STAGING_DIR/etc/hosts cat <<EOF >$STAGING_DIR/etc/hosts
$MGT_IP $GUEST_NAME $HOSTS_FILE_IP $GUEST_NAME
127.0.0.1 localhost localhost.localdomain 127.0.0.1 localhost localhost.localdomain
EOF EOF
@ -142,8 +140,6 @@ cat <<EOF >$STAGING_DIR/opt/stack/run.sh
#!/bin/bash #!/bin/bash
cd /opt/stack/devstack cd /opt/stack/devstack
killall screen killall screen
UPLOAD_LEGACY_TTY=yes HOST_IP=$PUB_IP VIRT_DRIVER=xenserver FORCE=yes MULTI_HOST=$MULTI_HOST HOST_IP_IFACE=$HOST_IP_IFACE $STACKSH_PARAMS ./stack.sh VIRT_DRIVER=xenserver FORCE=yes MULTI_HOST=$MULTI_HOST HOST_IP_IFACE=$HOST_IP_IFACE $STACKSH_PARAMS ./stack.sh
EOF EOF
chmod 755 $STAGING_DIR/opt/stack/run.sh chmod 755 $STAGING_DIR/opt/stack/run.sh
echo "Done"

View File

@ -1,40 +0,0 @@
#!/usr/bin/env bash
# Echo commands
set -o xtrace
# Head node host, which runs glance, api, keystone
HEAD_PUB_IP=${HEAD_PUB_IP:-192.168.1.57}
HEAD_MGT_IP=${HEAD_MGT_IP:-172.16.100.57}
COMPUTE_PUB_IP=${COMPUTE_PUB_IP:-192.168.1.58}
COMPUTE_MGT_IP=${COMPUTE_MGT_IP:-172.16.100.58}
# Networking params
FLOATING_RANGE=${FLOATING_RANGE:-192.168.1.196/30}
# Variables common amongst all hosts in the cluster
COMMON_VARS="$STACKSH_PARAMS MYSQL_HOST=$HEAD_MGT_IP RABBIT_HOST=$HEAD_MGT_IP GLANCE_HOSTPORT=$HEAD_MGT_IP:9292 FLOATING_RANGE=$FLOATING_RANGE"
# Helper to launch containers
function install_domU {
GUEST_NAME=$1 PUB_IP=$2 MGT_IP=$3 DO_SHUTDOWN=$4 TERMINATE=$TERMINATE STACKSH_PARAMS="$COMMON_VARS $5" ./build_domU.sh
}
# Launch the head node - headnode uses a non-ip domain name,
# because rabbit won't launch with an ip addr hostname :(
install_domU HEADNODE $HEAD_PUB_IP $HEAD_MGT_IP 1 "ENABLED_SERVICES=g-api,g-reg,key,n-api,n-sch,n-vnc,horizon,mysql,rabbit"
if [ $HEAD_PUB_IP == "dhcp" ]
then
guestnet=$(xe vm-list --minimal name-label=HEADNODE params=networks)
HEAD_PUB_IP=$(echo $guestnet | grep -w -o --only-matching "3/ip: [0-9,.]*;" | cut -d ':' -f2 | cut -d ';' -f 1)
fi
# Wait till the head node is up
while ! curl -L http://$HEAD_PUB_IP | grep -q username; do
echo "Waiting for head node ($HEAD_PUB_IP) to start..."
sleep 5
done
# Build the HA compute host
install_domU COMPUTENODE $COMPUTE_PUB_IP $COMPUTE_MGT_IP 0 "ENABLED_SERVICES=n-cpu,n-net,n-api"

View File

@ -1,7 +1,16 @@
#!/bin/bash #!/bin/bash
# This script is a level script
# It must be run on a XenServer or XCP machine
#
# It creates a DomU VM that runs OpenStack services
#
# For more details see: README.md
# Exit on errors # Exit on errors
set -o errexit set -o errexit
# Echo commands
set -o xtrace
# Abort if localrc is not set # Abort if localrc is not set
if [ ! -e ../../localrc ]; then if [ ! -e ../../localrc ]; then
@ -16,12 +25,17 @@ TOP_DIR=$(cd $(dirname "$0") && pwd)
# Source lower level functions # Source lower level functions
. $TOP_DIR/../../functions . $TOP_DIR/../../functions
# Include onexit commands
. $TOP_DIR/scripts/on_exit.sh
#
# Get Settings
#
# Source params - override xenrc params in your localrc to suit your taste # Source params - override xenrc params in your localrc to suit your taste
source xenrc source xenrc
# Echo commands
set -o xtrace
xe_min() xe_min()
{ {
local cmd="$1" local cmd="$1"
@ -29,22 +43,38 @@ xe_min()
xe "$cmd" --minimal "$@" xe "$cmd" --minimal "$@"
} }
#
# Prepare Dom0
# including installing XenAPI plugins
#
cd $TOP_DIR cd $TOP_DIR
if [ -f ./master ] if [ -f ./master ]
then then
rm -rf ./master rm -rf ./master
rm -rf ./nova rm -rf ./nova
fi fi
# get nova
wget https://github.com/openstack/nova/zipball/master --no-check-certificate wget https://github.com/openstack/nova/zipball/master --no-check-certificate
unzip -o master -d ./nova unzip -o master -d ./nova
cp -pr ./nova/*/plugins/xenserver/xenapi/etc/xapi.d /etc/
chmod a+x /etc/xapi.d/plugins/* # install xapi plugins
XAPI_PLUGIN_DIR=/etc/xapi.d/plugins/
if [ ! -d $XAPI_PLUGIN_DIR ]; then
# the following is needed when using xcp-xapi
XAPI_PLUGIN_DIR=/usr/lib/xcp/plugins/
fi
cp -pr ./nova/*/plugins/xenserver/xenapi/etc/xapi.d/plugins/* $XAPI_PLUGIN_DIR
chmod a+x ${XAPI_PLUGIN_DIR}*
mkdir -p /boot/guest mkdir -p /boot/guest
GUEST_NAME=${GUEST_NAME:-"DevStackOSDomU"}
SNAME="ubuntusnapshot" #
TNAME="ubuntuready" # Configure Networking
#
# Helper to create networks # Helper to create networks
# Uses echo trickery to return network uuid # Uses echo trickery to return network uuid
@ -84,7 +114,7 @@ function errorcheck() {
fi fi
} }
# Create host, vm, mgmt, pub networks # Create host, vm, mgmt, pub networks on XenServer
VM_NET=$(create_network "$VM_BR" "$VM_DEV" "$VM_VLAN" "vmbr") VM_NET=$(create_network "$VM_BR" "$VM_DEV" "$VM_VLAN" "vmbr")
errorcheck errorcheck
MGT_NET=$(create_network "$MGT_BR" "$MGT_DEV" "$MGT_VLAN" "mgtbr") MGT_NET=$(create_network "$MGT_BR" "$MGT_DEV" "$MGT_VLAN" "mgtbr")
@ -123,28 +153,48 @@ create_vlan $PUB_DEV $PUB_VLAN $PUB_NET
create_vlan $VM_DEV $VM_VLAN $VM_NET create_vlan $VM_DEV $VM_VLAN $VM_NET
create_vlan $MGT_DEV $MGT_VLAN $MGT_NET create_vlan $MGT_DEV $MGT_VLAN $MGT_NET
# dom0 ip # Get final bridge names
HOST_IP=${HOST_IP:-`ifconfig xenbr0 | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"`} if [ -z $VM_BR ]; then
VM_BR=$(xe_min network-list uuid=$VM_NET params=bridge)
# Set up ip forwarding fi
if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then if [ -z $MGT_BR ]; then
# FIXME: This doesn't work on reboot! MGT_BR=$(xe_min network-list uuid=$MGT_NET params=bridge)
echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network fi
if [ -z $PUB_BR ]; then
PUB_BR=$(xe_min network-list uuid=$PUB_NET params=bridge)
fi fi
# dom0 ip, XenAPI is assumed to be listening
HOST_IP=${HOST_IP:-`ifconfig xenbr0 | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"`}
# Set up ip forwarding, but skip on xcp-xapi
if [ -a /etc/sysconfig/network]; then
if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then
# FIXME: This doesn't work on reboot!
echo "FORWARD_IPV4=YES" >> /etc/sysconfig/network
fi
fi
# Also, enable ip forwarding in rc.local, since the above trick isn't working # Also, enable ip forwarding in rc.local, since the above trick isn't working
if ! grep -q "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then if ! grep -q "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then
echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local
fi fi
# Enable ip forwarding at runtime as well # Enable ip forwarding at runtime as well
echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/ip_forward
#
# Shutdown previous runs # Shutdown previous runs
#
DO_SHUTDOWN=${DO_SHUTDOWN:-1} DO_SHUTDOWN=${DO_SHUTDOWN:-1}
CLEAN_TEMPLATES=${CLEAN_TEMPLATES:-false}
if [ "$DO_SHUTDOWN" = "1" ]; then if [ "$DO_SHUTDOWN" = "1" ]; then
# Shutdown all domU's that created previously # Shutdown all domU's that created previously
xe_min vm-list name-label="$GUEST_NAME" | xargs ./scripts/uninstall-os-vpx.sh clean_templates_arg=""
if $CLEAN_TEMPLATES; then
clean_templates_arg="--remove-templates"
fi
./scripts/uninstall-os-vpx.sh $clean_templates_arg
# Destroy any instances that were launched # Destroy any instances that were launched
for uuid in `xe vm-list | grep -1 instance | grep uuid | sed "s/.*\: //g"`; do for uuid in `xe vm-list | grep -1 instance | grep uuid | sed "s/.*\: //g"`; do
@ -160,34 +210,18 @@ if [ "$DO_SHUTDOWN" = "1" ]; then
done done
fi fi
# Start guest
if [ -z $VM_BR ]; then
VM_BR=$(xe_min network-list uuid=$VM_NET params=bridge)
fi
if [ -z $MGT_BR ]; then
MGT_BR=$(xe_min network-list uuid=$MGT_NET params=bridge)
fi
if [ -z $PUB_BR ]; then
PUB_BR=$(xe_min network-list uuid=$PUB_NET params=bridge)
fi
templateuuid=$(xe template-list name-label="$TNAME") #
if [ -n "$templateuuid" ] # Create Ubuntu VM template
then # and/or create VM from template
vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$GUEST_NAME") #
else
template=$(xe_min template-list name-label="Ubuntu 11.10 (64-bit)")
if [ -z "$template" ]
then
cp $TOP_DIR/devstackubuntupreseed.cfg /opt/xensource/www/
$TOP_DIR/scripts/xenoneirictemplate.sh "${HOST_IP}/devstackubuntupreseed.cfg"
MIRROR=${MIRROR:-archive.ubuntu.com}
sed -e "s,d-i mirror/http/hostname string .*,d-i mirror/http/hostname string $MIRROR," \
-i /opt/xensource/www/devstackubuntupreseed.cfg
fi
$TOP_DIR/scripts/install-os-vpx.sh -t "Ubuntu 11.10 (64-bit)" -v $VM_BR -m $MGT_BR -p $PUB_BR -l $GUEST_NAME -r $OSDOMU_MEM_MB -k "flat_network_bridge=${VM_BR}"
# Wait for install to finish GUEST_NAME=${GUEST_NAME:-"DevStackOSDomU"}
TNAME="devstack_template_folsom_11.10"
SNAME_PREPARED="template_prepared"
SNAME_FIRST_BOOT="before_first_boot"
function wait_for_VM_to_halt() {
while true while true
do do
state=$(xe_min vm-list name-label="$GUEST_NAME" power-state=halted) state=$(xe_min vm-list name-label="$GUEST_NAME" power-state=halted)
@ -196,72 +230,199 @@ else
break break
else else
echo "Waiting for "$GUEST_NAME" to finish installation..." echo "Waiting for "$GUEST_NAME" to finish installation..."
sleep 30 sleep 20
fi fi
done done
}
templateuuid=$(xe template-list name-label="$TNAME")
if [ -z "$templateuuid" ]; then
#
# Install Ubuntu over network
#
# try to find ubuntu template
ubuntu_template_name="Ubuntu 11.10 for DevStack (64-bit)"
ubuntu_template=$(xe_min template-list name-label="$ubuntu_template_name")
# remove template, if we are in CLEAN_TEMPLATE mode
if [ -n "$ubuntu_template" ]; then
if $CLEAN_TEMPLATES; then
xe template-param-clear param-name=other-config uuid=$ubuntu_template
xe template-uninstall template-uuid=$ubuntu_template force=true
ubuntu_template=""
fi
fi
# always update the preseed file, incase we have a newer one
PRESEED_URL=${PRESEED_URL:-""}
if [ -z "$PRESEED_URL" ]; then
PRESEED_URL="${HOST_IP}/devstackubuntupreseed.cfg"
HTTP_SERVER_LOCATION="/opt/xensource/www"
if [ ! -e $HTTP_SERVER_LOCATION ]; then
HTTP_SERVER_LOCATION="/var/www/html"
mkdir -p $HTTP_SERVER_LOCATION
fi
cp -f $TOP_DIR/devstackubuntupreseed.cfg $HTTP_SERVER_LOCATION
MIRROR=${MIRROR:-""}
if [ -n "$MIRROR" ]; then
sed -e "s,d-i mirror/http/hostname string .*,d-i mirror/http/hostname string $MIRROR," \
-i "${HTTP_SERVER_LOCATION}/devstackubuntupreseed.cfg"
fi
fi
if [ -z "$ubuntu_template" ]; then
$TOP_DIR/scripts/xenoneirictemplate.sh $PRESEED_URL
fi
# create a new VM with the given template
# creating the correct VIFs and metadata
$TOP_DIR/scripts/install-os-vpx.sh -t "$ubuntu_template_name" -v $VM_BR -m $MGT_BR -p $PUB_BR -l $GUEST_NAME -r $OSDOMU_MEM_MB -k "flat_network_bridge=${VM_BR}"
# wait for install to finish
wait_for_VM_to_halt
# set VM to restart after a reboot
vm_uuid=$(xe_min vm-list name-label="$GUEST_NAME") vm_uuid=$(xe_min vm-list name-label="$GUEST_NAME")
xe vm-param-set actions-after-reboot=Restart uuid="$vm_uuid" xe vm-param-set actions-after-reboot=Restart uuid="$vm_uuid"
#
# Prepare VM for DevStack
#
# Install XenServer tools, and other such things
$TOP_DIR/prepare_guest_template.sh "$GUEST_NAME"
# start the VM to run the prepare steps
xe vm-start vm="$GUEST_NAME"
# Wait for prep script to finish and shutdown system
wait_for_VM_to_halt
# Make template from VM # Make template from VM
snuuid=$(xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME") snuuid=$(xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_PREPARED")
template_uuid=$(xe snapshot-clone uuid=$snuuid new-name-label="$TNAME") xe snapshot-clone uuid=$snuuid new-name-label="$TNAME"
else
#
# Template already installed, create VM from template
#
vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$GUEST_NAME")
fi fi
#
# Inject DevStack inside VM disk
#
$TOP_DIR/build_xva.sh "$GUEST_NAME" $TOP_DIR/build_xva.sh "$GUEST_NAME"
# create a snapshot before the first boot
# to allow a quick re-run with the same settings
xe vm-snapshot vm="$GUEST_NAME" new-name-label="$SNAME_FIRST_BOOT"
#
# Run DevStack VM
#
xe vm-start vm="$GUEST_NAME" xe vm-start vm="$GUEST_NAME"
if [ $PUB_IP == "dhcp" ]; then
PUB_IP=$(xe_min vm-list name-label=$GUEST_NAME params=networks | sed -ne 's,^.*3/ip: \([0-9.]*\).*$,\1,p') #
# Find IP and optionally wait for stack.sh to complete
#
function find_ip_by_name() {
local guest_name="$1"
local interface="$2"
local period=10
max_tries=10
i=0
while true
do
if [ $i -ge $max_tries ]; then
echo "Timed out waiting for devstack ip address"
exit 11
fi
devstackip=$(xe vm-list --minimal \
name-label=$guest_name \
params=networks | sed -ne "s,^.*${interface}/ip: \([0-9.]*\).*\$,\1,p")
if [ -z "$devstackip" ]
then
sleep $period
((i++))
else
echo $devstackip
break
fi
done
}
function ssh_no_check() {
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$@"
}
# Note the XenServer needs to be on the chosen
# network, so XenServer can access Glance API
if [ $HOST_IP_IFACE == "eth2" ]; then
DOMU_IP=$MGT_IP
if [ $MGT_IP == "dhcp" ]; then
DOMU_IP=$(find_ip_by_name $GUEST_NAME 2)
fi
else
DOMU_IP=$PUB_IP
if [ $PUB_IP == "dhcp" ]; then
DOMU_IP=$(find_ip_by_name $GUEST_NAME 3)
fi
fi fi
# If we have copied our ssh credentials, use ssh to monitor while the installation runs # If we have copied our ssh credentials, use ssh to monitor while the installation runs
WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1} WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
COPYENV=${COPYENV:-1}
if [ "$WAIT_TILL_LAUNCH" = "1" ] && [ -e ~/.ssh/id_rsa.pub ] && [ "$COPYENV" = "1" ]; then if [ "$WAIT_TILL_LAUNCH" = "1" ] && [ -e ~/.ssh/id_rsa.pub ] && [ "$COPYENV" = "1" ]; then
# Done creating the container, let's tail the log
echo
echo "============================================================="
echo " -- YAY! --"
echo "============================================================="
echo
echo "We're done launching the vm, about to start tailing the" echo "We're done launching the vm, about to start tailing the"
echo "stack.sh log. It will take a second or two to start." echo "stack.sh log. It will take a second or two to start."
echo echo
echo "Just CTRL-C at any time to stop tailing." echo "Just CTRL-C at any time to stop tailing."
set +o xtrace # wait for log to appear
while ! ssh_no_check -q stack@$DOMU_IP "[ -e run.sh.log ]"; do
while ! ssh -q stack@$PUB_IP "[ -e run.sh.log ]"; do sleep 10
sleep 1
done done
ssh stack@$PUB_IP 'tail -f run.sh.log' & # output the run.sh.log
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no stack@$DOMU_IP 'tail -f run.sh.log' &
TAIL_PID=$! TAIL_PID=$!
function kill_tail() { function kill_tail() {
kill $TAIL_PID kill -9 $TAIL_PID
exit 1 exit 1
} }
# Let Ctrl-c kill tail and exit # Let Ctrl-c kill tail and exit
trap kill_tail SIGINT trap kill_tail SIGINT
echo "Waiting stack.sh to finish..." # ensure we kill off the tail if we exit the script early
while ! ssh -q stack@$PUB_IP "grep -q 'stack.sh completed in' run.sh.log"; do # for other reasons
sleep 1 add_on_exit "kill -9 $TAIL_PID || true"
# wait silently until stack.sh has finished
set +o xtrace
while ! ssh_no_check -q stack@$DOMU_IP "tail run.sh.log | grep -q 'stack.sh completed in'"; do
sleep 10
done done
set -o xtrace
kill $TAIL_PID # kill the tail process now stack.sh has finished
kill -9 $TAIL_PID
if ssh -q stack@$PUB_IP "grep -q 'stack.sh failed' run.sh.log"; then # check for a failure
if ssh_no_check -q stack@$DOMU_IP "grep -q 'stack.sh failed' run.sh.log"; then
exit 1 exit 1
fi fi
echo "################################################################################"
echo "" echo ""
echo "Finished - Zip-a-dee Doo-dah!" echo "All Finished!"
echo "You can then visit the OpenStack Dashboard" echo "You can visit the OpenStack Dashboard"
echo "at http://$PUB_IP, and contact other services at the usual ports." echo "at http://$DOMU_IP, and contact other services at the usual ports."
else else
echo "################################################################################" echo "################################################################################"
echo "" echo ""
@ -269,10 +430,9 @@ else
echo "Now, you can monitor the progress of the stack.sh installation by " echo "Now, you can monitor the progress of the stack.sh installation by "
echo "tailing /opt/stack/run.sh.log from within your domU." echo "tailing /opt/stack/run.sh.log from within your domU."
echo "" echo ""
echo "ssh into your domU now: 'ssh stack@$PUB_IP' using your password" echo "ssh into your domU now: 'ssh stack@$DOMU_IP' using your password"
echo "and then do: 'tail -f /opt/stack/run.sh.log'" echo "and then do: 'tail -f /opt/stack/run.sh.log'"
echo "" echo ""
echo "When the script completes, you can then visit the OpenStack Dashboard" echo "When the script completes, you can then visit the OpenStack Dashboard"
echo "at http://$PUB_IP, and contact other services at the usual ports." echo "at http://$DOMU_IP, and contact other services at the usual ports."
fi fi

View File

@ -1,6 +1,18 @@
#!/bin/bash #!/bin/bash
# This script is run on an Ubuntu VM.
# This script is inserted into the VM by prepare_guest_template.sh
# and is run when that VM boots.
# It customizes a fresh Ubuntu install, so it is ready
# to run stack.sh
#
# This includes installing the XenServer tools,
# creating the user called "stack",
# and shuts down the VM to signal the script has completed
set -x set -x
# Echo commands
set -o xtrace
# Configurable nuggets # Configurable nuggets
GUEST_PASSWORD=${GUEST_PASSWORD:-secrete} GUEST_PASSWORD=${GUEST_PASSWORD:-secrete}
@ -13,7 +25,7 @@ chroot $STAGING_DIR apt-get install -y cracklib-runtime curl wget ssh openssh-se
chroot $STAGING_DIR apt-get install -y curl wget ssh openssh-server python-pip git vim-nox sudo chroot $STAGING_DIR apt-get install -y curl wget ssh openssh-server python-pip git vim-nox sudo
chroot $STAGING_DIR pip install xenapi chroot $STAGING_DIR pip install xenapi
# Install guest utilities # Install XenServer guest utilities
XEGUEST=xe-guest-utilities_5.6.100-651_amd64.deb XEGUEST=xe-guest-utilities_5.6.100-651_amd64.deb
wget http://images.ansolabs.com/xen/$XEGUEST -O $XEGUEST wget http://images.ansolabs.com/xen/$XEGUEST -O $XEGUEST
cp $XEGUEST $STAGING_DIR/root cp $XEGUEST $STAGING_DIR/root
@ -68,3 +80,12 @@ if [ "$DO_TGZ" = "1" ]; then
rm -f stage.tgz rm -f stage.tgz
tar cfz stage.tgz stage tar cfz stage.tgz stage
fi fi
# remove self from local.rc
# so this script is not run again
rm -rf /etc/rc.local
mv /etc/rc.local.preparebackup /etc/rc.local
cp $STAGING_DIR/etc/rc.local $STAGING_DIR/etc/rc.local.backup
# shutdown to notify we are done
shutdown -h now

View File

@ -0,0 +1,57 @@
#!/bin/bash
# This script is run by install_os_domU.sh
#
# Parameters:
# - $GUEST_NAME - hostname for the DomU VM
#
# It modifies the ubuntu image created by install_os_domU.sh
#
# This script is responsible for cusomtizing the fresh ubuntu
# image so on boot it runs the prepare_guest.sh script
# that modifies the VM so it is ready to run stack.sh.
# It does this by mounting the disk image of the VM.
#
# The resultant image is started by install_os_domU.sh,
# and once the VM has shutdown, build_xva.sh is run
# Exit on errors
set -o errexit
# Echo commands
set -o xtrace
# This directory
TOP_DIR=$(cd $(dirname "$0") && pwd)
# Include onexit commands
. $TOP_DIR/scripts/on_exit.sh
# Source params - override xenrc params in your localrc to suite your taste
source xenrc
#
# Parameters
#
GUEST_NAME="$1"
# Mount the VDI
STAGING_DIR=$($TOP_DIR/scripts/manage-vdi open $GUEST_NAME 0 1 | grep -o "/tmp/tmp.[[:alnum:]]*")
add_on_exit "$TOP_DIR/scripts/manage-vdi close $GUEST_NAME 0 1"
# Make sure we have a stage
if [ ! -d $STAGING_DIR/etc ]; then
echo "Stage is not properly set up!"
exit 1
fi
# Copy prepare_guest.sh to VM
mkdir -p $STAGING_DIR/opt/stack/
cp $TOP_DIR/prepare_guest.sh $STAGING_DIR/opt/stack/prepare_guest.sh
# backup rc.local
cp $STAGING_DIR/etc/rc.local $STAGING_DIR/etc/rc.local.preparebackup
# run prepare_guest.sh on boot
cat <<EOF >$STAGING_DIR/etc/rc.local
GUEST_PASSWORD=$GUEST_PASSWORD STAGING_DIR=/ DO_TGZ=0 bash /opt/stack/prepare_guest.sh > /opt/stack/prepare_guest.log 2>&1
EOF

View File

@ -19,7 +19,12 @@
set -eux set -eux
. /etc/xensource-inventory if [ -a /etc/xensource-inventory]
then
. /etc/xensource-inventory
else
. /etc/xcp/inventory
fi
NAME="XenServer OpenStack VPX" NAME="XenServer OpenStack VPX"
DATA_VDI_SIZE="500MiB" DATA_VDI_SIZE="500MiB"

View File

@ -20,6 +20,26 @@ vdi_uuid=$(xe_min vbd-list params=vdi-uuid vm-uuid="$vm_uuid" \
dom0_uuid=$(xe_min vm-list is-control-domain=true) dom0_uuid=$(xe_min vm-list is-control-domain=true)
get_mount_device()
{
vbd_uuid=$1
dev=$(xe_min vbd-list params=device uuid="$vbd_uuid")
if [[ "$dev" =~ "sm/" ]]; then
DEBIAN_FRONTEND=noninteractive \
apt-get --option "Dpkg::Options::=--force-confold" --assume-yes \
install kpartx || true &> /dev/null
mapping=$(kpartx -av "/dev/$dev" | sed -ne 's,^add map \([a-f0-9\-]*\).*$,\1,p' | sed -ne "s,^\(.*${part}\)\$,\1,p")
if [ -z "$mapping" ]; then
echo "Failed to find mapping"
exit -1
fi
echo "mapper/${mapping}"
else
echo "/dev/$dev$part"
fi
}
open_vdi() open_vdi()
{ {
vbd_uuid=$(xe vbd-create vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid" \ vbd_uuid=$(xe vbd-create vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid" \
@ -27,26 +47,30 @@ open_vdi()
mp=$(mktemp -d) mp=$(mktemp -d)
xe vbd-plug uuid="$vbd_uuid" xe vbd-plug uuid="$vbd_uuid"
which_udev=$(which udevsettle) || true
if [ -n "$which_udev" ]; then
udevsettle udevsettle
dev=$(xe_min vbd-list params=device uuid="$vbd_uuid") else
mount "/dev/$dev$part" "$mp" udevadm settle
fi
mount_device=$(get_mount_device "$vbd_uuid")
mount "$mount_device" "$mp"
echo "Your vdi is mounted at $mp" echo "Your vdi is mounted at $mp"
} }
close_vdi() close_vdi()
{ {
vbd_uuid=$(xe_min vbd-list vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid") vbd_uuid=$(xe_min vbd-list vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid")
dev=$(xe_min vbd-list params=device uuid="$vbd_uuid") mount_device=$(get_mount_device "$vbd_uuid")
umount "/dev/$dev$part" umount "$mount_device"
xe vbd-unplug uuid=$vbd_uuid xe vbd-unplug uuid=$vbd_uuid
xe vbd-destroy uuid=$vbd_uuid xe vbd-destroy uuid=$vbd_uuid
} }
if [ "$action" == "open" ] if [ "$action" == "open" ]; then
then
open_vdi open_vdi
elif [ "$action" == "close" ] elif [ "$action" == "close" ]; then
then
close_vdi close_vdi
fi fi

24
tools/xen/scripts/on_exit.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e
set -o xtrace
declare -a on_exit_hooks
on_exit()
{
for i in $(seq $((${#on_exit_hooks[*]} - 1)) -1 0)
do
eval "${on_exit_hooks[$i]}"
done
}
add_on_exit()
{
local n=${#on_exit_hooks[*]}
on_exit_hooks[$n]="$*"
if [[ $n -eq 0 ]]
then
trap on_exit EXIT
fi
}

View File

@ -17,19 +17,19 @@
# under the License. # under the License.
# #
remove_data= set -ex
if [ "$1" = "--remove-data" ]
then
remove_data=1
fi
set -eu # By default, don't remove the templates
REMOVE_TEMPLATES=${REMOVE_TEMPLATES:-"false"}
if [ "$1" = "--remove-templates" ]; then
REMOVE_TEMPLATES=true
fi
xe_min() xe_min()
{ {
local cmd="$1" local cmd="$1"
shift shift
/opt/xensource/bin/xe "$cmd" --minimal "$@" xe "$cmd" --minimal "$@"
} }
destroy_vdi() destroy_vdi()
@ -39,11 +39,8 @@ destroy_vdi()
local dev=$(xe_min vbd-list uuid=$vbd_uuid params=userdevice) local dev=$(xe_min vbd-list uuid=$vbd_uuid params=userdevice)
local vdi_uuid=$(xe_min vbd-list uuid=$vbd_uuid params=vdi-uuid) local vdi_uuid=$(xe_min vbd-list uuid=$vbd_uuid params=vdi-uuid)
if [ "$type" = 'Disk' ] && [ "$dev" != 'xvda' ] && [ "$dev" != '0' ] if [ "$type" == 'Disk' ] && [ "$dev" != 'xvda' ] && [ "$dev" != '0' ]; then
then
echo -n "Destroying data disk... "
xe vdi-destroy uuid=$vdi_uuid xe vdi-destroy uuid=$vdi_uuid
echo "done."
fi fi
} }
@ -52,50 +49,36 @@ uninstall()
local vm_uuid="$1" local vm_uuid="$1"
local power_state=$(xe_min vm-list uuid=$vm_uuid params=power-state) local power_state=$(xe_min vm-list uuid=$vm_uuid params=power-state)
if [ "$power_state" != "halted" ] if [ "$power_state" != "halted" ]; then
then
echo -n "Shutting down VM... "
xe vm-shutdown vm=$vm_uuid force=true xe vm-shutdown vm=$vm_uuid force=true
echo "done."
fi fi
if [ "$remove_data" = "1" ] for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g'); do
then
for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g')
do
destroy_vdi "$v" destroy_vdi "$v"
done done
fi
echo -n "Deleting VM... "
xe vm-uninstall vm=$vm_uuid force=true >/dev/null xe vm-uninstall vm=$vm_uuid force=true >/dev/null
echo "done."
} }
uninstall_template() uninstall_template()
{ {
local vm_uuid="$1" local vm_uuid="$1"
if [ "$remove_data" = "1" ] for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g'); do
then
for v in $(xe_min vbd-list vm-uuid=$vm_uuid | sed -e 's/,/ /g')
do
destroy_vdi "$v" destroy_vdi "$v"
done done
fi
echo -n "Deleting template... "
xe template-uninstall template-uuid=$vm_uuid force=true >/dev/null xe template-uninstall template-uuid=$vm_uuid force=true >/dev/null
echo "done."
} }
# remove the VMs and their disks
for u in $(xe_min vm-list other-config:os-vpx=true | sed -e 's/,/ /g') for u in $(xe_min vm-list other-config:os-vpx=true | sed -e 's/,/ /g'); do
do
uninstall "$u" uninstall "$u"
done done
for u in $(xe_min template-list other-config:os-vpx=true | sed -e 's/,/ /g') # remove the templates
do if [ "$REMOVE_TEMPLATES" == "true" ]; then
for u in $(xe_min template-list other-config:os-vpx=true | sed -e 's/,/ /g'); do
uninstall_template "$u" uninstall_template "$u"
done done
fi

View File

@ -3,7 +3,7 @@
## on Xenserver 6.0.2 Net install only ## on Xenserver 6.0.2 Net install only
## Original Author: David Markey <david.markey@citrix.com> ## Original Author: David Markey <david.markey@citrix.com>
## Author: Renuka Apte <renuka.apte@citrix.com> ## Author: Renuka Apte <renuka.apte@citrix.com>
## This is not an officially supported guest OS on XenServer 6.02 ## This is not an officially supported guest OS on XenServer 6.0.2
BASE_DIR=$(cd $(dirname "$0") && pwd) BASE_DIR=$(cd $(dirname "$0") && pwd)
source $BASE_DIR/../../../localrc source $BASE_DIR/../../../localrc
@ -15,11 +15,15 @@ if [[ -z $LENNY ]] ; then
exit 1 exit 1
fi fi
distro="Ubuntu 11.10" distro="Ubuntu 11.10 for DevStack"
arches=("32-bit" "64-bit") arches=("32-bit" "64-bit")
preseedurl=${1:-"http://images.ansolabs.com/devstackubuntupreseed.cfg"} preseedurl=${1:-"http://images.ansolabs.com/devstackubuntupreseed.cfg"}
NETINSTALL_LOCALE=${NETINSTALL_LOCALE:-en_US}
NETINSTALL_KEYBOARD=${NETINSTALL_KEYBOARD:-us}
NETINSTALL_IFACE=${NETINSTALL_IFACE:-eth3}
for arch in ${arches[@]} ; do for arch in ${arches[@]} ; do
echo "Attempting $distro ($arch)" echo "Attempting $distro ($arch)"
if [[ -n $(xe template-list name-label="$distro ($arch)" params=uuid --minimal) ]] ; then if [[ -n $(xe template-list name-label="$distro ($arch)" params=uuid --minimal) ]] ; then
@ -30,7 +34,11 @@ for arch in ${arches[@]} ; do
echo "NETINSTALLIP not set in localrc" echo "NETINSTALLIP not set in localrc"
exit 1 exit 1
fi fi
pvargs="-- quiet console=hvc0 partman/default_filesystem=ext3 locale=en_US console-setup/ask_detect=false keyboard-configuration/layoutcode=us netcfg/choose_interface=eth3 netcfg/get_hostname=os netcfg/get_domain=os auto url=${preseedurl}" # Some of these settings can be found in example preseed files
# however these need to be answered before the netinstall
# is ready to fetch the preseed file, and as such must be here
# to get a fully automated install
pvargs="-- quiet console=hvc0 partman/default_filesystem=ext3 locale=${NETINSTALL_LOCALE} console-setup/ask_detect=false keyboard-configuration/layoutcode=${NETINSTALL_KEYBOARD} netcfg/choose_interface=${NETINSTALL_IFACE} netcfg/get_hostname=os netcfg/get_domain=os auto url=${preseedurl}"
if [ "$NETINSTALLIP" != "dhcp" ] if [ "$NETINSTALLIP" != "dhcp" ]
then then
netcfgargs="netcfg/disable_autoconfig=true netcfg/get_nameservers=${NAMESERVERS} netcfg/get_ipaddress=${NETINSTALLIP} netcfg/get_netmask=${NETMASK} netcfg/get_gateway=${GATEWAY} netcfg/confirm_static=true" netcfgargs="netcfg/disable_autoconfig=true netcfg/get_nameservers=${NAMESERVERS} netcfg/get_ipaddress=${NETINSTALLIP} netcfg/get_netmask=${NETMASK} netcfg/get_gateway=${GATEWAY} netcfg/confirm_static=true"

View File

@ -5,12 +5,15 @@ GUEST_NAME=${GUEST_NAME:-DevStackOSDomU}
# Size of image # Size of image
VDI_MB=${VDI_MB:-5000} VDI_MB=${VDI_MB:-5000}
OSDOMU_MEM_MB=1024
# VM Password # VM Password
GUEST_PASSWORD=${GUEST_PASSWORD:-secrete} GUEST_PASSWORD=${GUEST_PASSWORD:-secrete}
# Host Interface, i.e. the public facing interface on the nova vm # Host Interface, i.e. the interface on the nova vm you want to expose the services on
HOST_IP_IFACE=${HOST_IP_IFACE:-eth0} # Usually either eth2 (management network) or eth3 (public network)
# not eth0 (private network with XenServer host) or eth1 (VM traffic network)
HOST_IP_IFACE=${HOST_IP_IFACE:-eth3}
# Our nova host's network info # Our nova host's network info
VM_IP=${VM_IP:-10.255.255.255} # A host-only ip that let's the interface come up, otherwise unused VM_IP=${VM_IP:-10.255.255.255} # A host-only ip that let's the interface come up, otherwise unused
@ -35,7 +38,5 @@ MGT_BR=${MGT_BR:-""}
MGT_VLAN=${MGT_VLAN:-101} MGT_VLAN=${MGT_VLAN:-101}
MGT_DEV=${MGT_DEV:-eth0} MGT_DEV=${MGT_DEV:-eth0}
OSDOMU_MEM_MB=1024
# Source params # Source params
cd ../.. && source ./stackrc && cd $TOP_DIR cd ../.. && source ./stackrc && cd $TOP_DIR