From b115341253b30fd51b5ac2fa763c701737eaae6c Mon Sep 17 00:00:00 2001 From: root Date: Thu, 19 Jan 2012 13:28:21 -0800 Subject: [PATCH] Generalize xen network config Allow dhcp for IP addresses. dhclient3 bug workaround. Refactor code to improve network creation logic. Change-Id: Ia3e2e65bbe8b68cf4832595cb7c283c3dc84db19 --- stack.sh | 9 ++- tools/xen/build_domU.sh | 97 ++++++++++++++++++++++--------- tools/xen/build_xva.sh | 42 ++++++++++--- tools/xen/templates/interfaces.in | 17 ++++-- tools/xen/xenrc | 15 +++-- 5 files changed, 130 insertions(+), 50 deletions(-) diff --git a/stack.sh b/stack.sh index 08fcafe425..e1f3083a1a 100755 --- a/stack.sh +++ b/stack.sh @@ -200,14 +200,13 @@ LIBVIRT_TYPE=${LIBVIRT_TYPE:-kvm} # cases unless you are working on multi-zone mode. SCHEDULER=${SCHEDULER:-nova.scheduler.simple.SimpleScheduler} +HOST_IP_IFACE=${HOST_IP_IFACE:-eth0} # Use the eth0 IP unless an explicit is set by ``HOST_IP`` environment variable -if [ ! -n "$HOST_IP" ]; then - HOST_IP=`LC_ALL=C /sbin/ifconfig eth0 | grep -m 1 'inet addr:'| cut -d: -f2 | awk '{print $1}'` +if [ -z "$HOST_IP" -o "$HOST_IP" == "dhcp" ]; then + HOST_IP=`LC_ALL=C /sbin/ifconfig ${HOST_IP_IFACE} | grep -m 1 'inet addr:'| cut -d: -f2 | awk '{print $1}'` if [ "$HOST_IP" = "" ]; then echo "Could not determine host ip address." - echo "If this is not your first run of stack.sh, it is " - echo "possible that nova moved your eth0 ip address to the FLAT_NETWORK_BRIDGE." - echo "Please specify your HOST_IP in your localrc." + echo "Either localrc specified dhcp on ${HOST_IP_IFACE} or defaulted to eth0" exit 1 fi fi diff --git a/tools/xen/build_domU.sh b/tools/xen/build_domU.sh index cd28f15574..5ea03dad2e 100755 --- a/tools/xen/build_domU.sh +++ b/tools/xen/build_domU.sh @@ -37,51 +37,85 @@ if ! which git; then fi # Helper to create networks +# Uses echo trickery to return network uuid function create_network() { - if ! xe network-list | grep bridge | grep -q $1; then - echo "Creating bridge $1" - xe network-create name-label=$1 + br=$1 + dev=$2 + vlan=$3 + netname=$4 + if [ -z $br ] + then + pif=$(xe pif-list --minimal device=$dev VLAN=$vlan) + if [ -z $pif ] + then + net=$(xe network-create name-label=$netname) + else + net=$(xe network-list --minimal PIF-uuids=$pif) + fi + echo $net + return 0 + fi + if [ ! $(xe network-list --minimal params=bridge | grep -w --only-matching $br) ] + then + echo "Specified bridge $br does not exist" + echo "If you wish to use defaults, please keep the bridge name empty" + exit 1 + else + net=$(xe network-list --minimal bridge=$br) + echo $net + fi +} + +function errorcheck() { + rc=$? + if [ $rc -ne 0 ] + then + exit $rc fi } # Create host, vm, mgmt, pub networks -create_network xapi0 -create_network $VM_BR -create_network $MGT_BR -create_network $PUB_BR - -# Get the uuid for our physical (public) interface -PIF=`xe pif-list --minimal device=eth0` - -# Create networks/bridges for vm and management -VM_NET=`xe network-list --minimal bridge=$VM_BR` -MGT_NET=`xe network-list --minimal bridge=$MGT_BR` +VM_NET=$(create_network "$VM_BR" "$VM_DEV" "$VM_VLAN" "vmbr") +errorcheck +MGT_NET=$(create_network "$MGT_BR" "$MGT_DEV" "$MGT_VLAN" "mgtbr") +errorcheck +PUB_NET=$(create_network "$PUB_BR" "$PUB_DEV" "$PUB_VLAN" "pubbr") +errorcheck # Helper to create vlans function create_vlan() { - pif=$1 + dev=$1 vlan=$2 net=$3 - if ! xe vlan-list | grep tag | grep -q $vlan; then - xe vlan-create pif-uuid=$pif vlan=$vlan network-uuid=$net + # VLAN -1 refers to no VLAN (physical network) + if [ $vlan -eq -1 ] + then + return + fi + if [ -z $(xe vlan-list --minimal tag=$vlan) ] + then + pif=$(xe pif-list --minimal network-uuid=$net) + # We created a brand new network this time + if [ -z $pif ] + then + pif=$(xe pif-list --minimal device=$dev VLAN=-1) + xe vlan-create pif-uuid=$pif vlan=$vlan network-uuid=$net + else + echo "VLAN does not exist but PIF attached to this network" + echo "How did we reach here?" + exit 1 + fi fi } # Create vlans for vm and management -create_vlan $PIF $VM_VLAN $VM_NET -create_vlan $PIF $MGT_VLAN $MGT_NET +create_vlan $PUB_DEV $PUB_VLAN $PUB_NET +create_vlan $VM_DEV $VM_VLAN $VM_NET +create_vlan $MGT_DEV $MGT_VLAN $MGT_NET # dom0 ip HOST_IP=${HOST_IP:-`ifconfig xenbr0 | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"`} -# Setup host-only nat rules -HOST_NET=169.254.0.0/16 -if ! iptables -L -v -t nat | grep -q $HOST_NET; then - iptables -t nat -A POSTROUTING -s $HOST_NET -j SNAT --to-source $HOST_IP - iptables -I FORWARD 1 -s $HOST_NET -j ACCEPT - /etc/init.d/iptables save -fi - # Set up ip forwarding if ! grep -q "FORWARD_IPV4=YES" /etc/sysconfig/network; then # FIXME: This doesn't work on reboot! @@ -139,6 +173,15 @@ if [ "$DO_SHUTDOWN" = "1" ]; then fi # Start guest +if [ -z $VM_BR ]; then + VM_BR=$(xe network-list --minimal uuid=$VM_NET params=bridge) +fi +if [ -z $MGT_BR ]; then + MGT_BR=$(xe network-list --minimal uuid=$MGT_NET params=bridge) +fi +if [ -z $PUB_BR ]; then + PUB_BR=$(xe network-list --minimal uuid=$PUB_NET params=bridge) +fi $TOP_DIR/scripts/install-os-vpx.sh -f $XVA -v $VM_BR -m $MGT_BR -p $PUB_BR # If we have copied our ssh credentials, use ssh to monitor while the installation runs diff --git a/tools/xen/build_xva.sh b/tools/xen/build_xva.sh index e4de2a1af6..c8721aa9d1 100755 --- a/tools/xen/build_xva.sh +++ b/tools/xen/build_xva.sh @@ -62,7 +62,7 @@ XVA_DIR=$TOP_DIR/xvas mkdir -p $XVA_DIR # Path to xva -XVA=$XVA_DIR/$GUEST_NAME.xva +XVA=$XVA_DIR/$GUEST_NAME.xva # Setup fake grub rm -rf $STAGING_DIR/boot/grub/ @@ -102,6 +102,8 @@ sed -e "s,@BUILD_NUMBER@,$BUILD_NUMBER,g" -i $OVA # Run devstack on launch cat <$STAGING_DIR/etc/rc.local +# network restart required for getting the right gateway +/etc/init.d/networking restart GUEST_PASSWORD=$GUEST_PASSWORD STAGING_DIR=/ DO_TGZ=0 bash /opt/stack/devstack/tools/xen/prepare_guest.sh su -c "/opt/stack/run.sh > /opt/stack/run.sh.log" stack exit 0 @@ -122,12 +124,36 @@ EOF # Configure the network INTERFACES=$STAGING_DIR/etc/network/interfaces cp $TEMPLATES_DIR/interfaces.in $INTERFACES -sed -e "s,@ETH1_IP@,$VM_IP,g" -i $INTERFACES -sed -e "s,@ETH1_NETMASK@,$VM_NETMASK,g" -i $INTERFACES -sed -e "s,@ETH2_IP@,$MGT_IP,g" -i $INTERFACES -sed -e "s,@ETH2_NETMASK@,$MGT_NETMASK,g" -i $INTERFACES -sed -e "s,@ETH3_IP@,$PUB_IP,g" -i $INTERFACES -sed -e "s,@ETH3_NETMASK@,$PUB_NETMASK,g" -i $INTERFACES +if [ $VM_IP == "dhcp" ]; then + echo 'eth1 on dhcp' + sed -e "s,iface eth1 inet static,iface eth1 inet dhcp,g" -i $INTERFACES + sed -e '/@ETH1_/d' -i $INTERFACES +else + sed -e "s,@ETH1_IP@,$VM_IP,g" -i $INTERFACES + sed -e "s,@ETH1_NETMASK@,$VM_NETMASK,g" -i $INTERFACES +fi + +if [ $MGT_IP == "dhcp" ]; then + echo 'eth2 on dhcp' + sed -e "s,iface eth2 inet static,iface eth2 inet dhcp,g" -i $INTERFACES + sed -e '/@ETH2_/d' -i $INTERFACES +else + sed -e "s,@ETH2_IP@,$MGT_IP,g" -i $INTERFACES + sed -e "s,@ETH2_NETMASK@,$MGT_NETMASK,g" -i $INTERFACES +fi + +if [ $PUB_IP == "dhcp" ]; then + echo 'eth3 on dhcp' + sed -e "s,iface eth3 inet static,iface eth3 inet dhcp,g" -i $INTERFACES + sed -e '/@ETH3_/d' -i $INTERFACES +else + sed -e "s,@ETH3_IP@,$PUB_IP,g" -i $INTERFACES + sed -e "s,@ETH3_NETMASK@,$PUB_NETMASK,g" -i $INTERFACES +fi + +if [ -h $STAGING_DIR/sbin/dhclient3 ]; then + rm -f $STAGING_DIR/sbin/dhclient3 +fi # Gracefully cp only if source file/dir exists function cp_it { @@ -151,7 +177,7 @@ cat <$STAGING_DIR/opt/stack/run.sh #!/bin/bash cd /opt/stack/devstack killall screen -UPLOAD_LEGACY_TTY=yes HOST_IP=$PUB_IP VIRT_DRIVER=xenserver FORCE=yes MULTI_HOST=1 $STACKSH_PARAMS ./stack.sh +UPLOAD_LEGACY_TTY=yes HOST_IP=$PUB_IP VIRT_DRIVER=xenserver FORCE=yes MULTI_HOST=1 HOST_IP_IFACE=$HOST_IP_IFACE $STACKSH_PARAMS ./stack.sh EOF chmod 755 $STAGING_DIR/opt/stack/run.sh diff --git a/tools/xen/templates/interfaces.in b/tools/xen/templates/interfaces.in index 49c3d681d9..e315a8c3c4 100644 --- a/tools/xen/templates/interfaces.in +++ b/tools/xen/templates/interfaces.in @@ -1,8 +1,15 @@ auto lo iface lo inet loopback -auto eth0 -iface eth0 inet dhcp +# If eth3 is static, the order should not matter +# and eth0 will have the default gateway. If not, +# we probably want the default gateway to be +# what is on the public interface. Hence changed +# the order here. +auto eth3 +iface eth3 inet static + address @ETH3_IP@ + netmask @ETH3_NETMASK@ auto eth1 iface eth1 inet static @@ -15,7 +22,5 @@ iface eth2 inet static address @ETH2_IP@ netmask @ETH2_NETMASK@ -auto eth3 -iface eth3 inet static - address @ETH3_IP@ - netmask @ETH3_NETMASK@ +auto eth0 +iface eth0 inet dhcp diff --git a/tools/xen/xenrc b/tools/xen/xenrc index 246ac16be3..73f9c025ec 100644 --- a/tools/xen/xenrc +++ b/tools/xen/xenrc @@ -9,24 +9,31 @@ VDI_MB=${VDI_MB:-2500} # VM Password GUEST_PASSWORD=${GUEST_PASSWORD:-secrete} -# Our nova host's network info +# Host Interface, i.e. the public facing interface on the nova vm +HOST_IP_IFACE=${HOST_IP_IFACE:-eth0} + +# 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 MGT_IP=${MGT_IP:-172.16.100.55} PUB_IP=${PUB_IP:-192.168.1.55} # Public network -PUB_BR=${PUB_BR:-xenbr0} +PUB_BR=${PUB_BR:-"xenbr0"} +PUB_DEV=${PUB_DEV:-eth0} +PUB_VLAN=${PUB_VLAN:--1} PUB_NETMASK=${PUB_NETMASK:-255.255.255.0} # VM network params VM_NETMASK=${VM_NETMASK:-255.255.255.0} -VM_BR=${VM_BR:-xapi1} +VM_BR=${VM_BR:-""} VM_VLAN=${VM_VLAN:-100} +VM_DEV=${VM_DEV:-eth0} # MGMT network params MGT_NETMASK=${MGT_NETMASK:-255.255.255.0} -MGT_BR=${MGT_BR:-xapi2} +MGT_BR=${MGT_BR:-""} MGT_VLAN=${MGT_VLAN:-101} +MGT_DEV=${MGT_DEV:-eth0} # XVA Directory XVA_DIR=${XVA_DIR:-xvas}