#!/bin/bash
#============================================================================
# vnet-attach
#
# Version = 1.0.0 beta
# Date = 2007-07-25
#
# Maintainer(s) = Ron Terry - ron (at) pronetworkconsulting (dot) com
#
# The latest version can be found at:
#
#    http://pronetworkconsulting.com/linux/scripts/vnet-attach.html
#
# Description:
#
#   The vnet-attach script is a simplifed way to reattach or add virtual 
#    network interfaces in Xen VMs to virtual networks in Domain0. It uses 
#    the xm network-attach command to do the work but will parse xenstore 
#    to determine the MAC address of the interface you are reattaching so 
#    that it's network configuration (IP address, etc.) inside the VM are 
#    restored automatically.

#   This is an improvement because the xm network-attach command requires 
#    that you specify mac=12:34:56:aa:bb:cc when you attach the interface 
#    or the MAC address will be dynamically generated and therefor appear 
#    to be a new NIC inside the VM.
#
#============================================================================

####  Read config files and set variables  ##################################

#MAC_LIST=`xm list -l $VM | grep -w "mac" | cut -d "(" -f 2 | cut -d ")" -f 1 | cut -d " " -f 2`
#DOMID=`xm list -l $VM | grep -w "domid"|cut -d "(" -f 2 | cut -d ")" -f 1 | cut -d " " -f 2`
#VIF_NUM=`xm network-list -l $VM | grep -w "handle" | cut -d "(" -f 2 | cut -d ")" -f 1 | cut -d " " -f 2`

####  Script Functions  #####################################################

usage() {
# Gives usege information for the script
  echo
  echo "Usage:  vnet-attach -d <vm name|id> [-i <Dev ID>] -b <bridge>"
  echo 
  echo "  options:  -d      domain ID or name"
  echo "            -i      network interface (0=eth0, 1=eth1, etc)"
  echo "            -b      bridge name"
  echo "            -D      detach from bridge instead of attach to bridge"
  echo "            -h      usage help (this screen)"
  echo
  echo "  Example:  vnet-attach -d sles10 -i 0 -b xenbr2"
  echo "            vnet-attach -D -d sles10 -i 0"
  echo
}

check_for_xen() {
# Checks to see if you are booted int a Xen environment and if it s Dom0
  if ! uname -r | grep -iq xen || ! /etc/init.d/xend status
  then
    echo
    echo "Error:  This utility can only be run from within Xen Domain 0"
    echo
    exit 1
  fi
}
check_cli_args(){
# Check for arguments passed on the command line and sets variable accordingly
  while getopts "d:i:b:hD" OPTIONS
  do
    case $OPTIONS in
      d)
        VM=$OPTARG
        echo "VM = $VM"
      ;;
      i)
        INTERFACE=$OPTARG
        echo "INTERFACE = $INTERFACE"
      ;;
      b)
        BRIDGE=$OPTARG
        echo "BRIDGE = $BRIDGE"
      ;;
      h)
        usage
        exit 1
      ;;
      D)
        MODE="detach"
      ;;
    esac
  done

  if [ -z $MODE ]
  then
    MODE="attach"
  fi

  if [ -z $VM ]
  then
    echo
    echo "Error:  You must provide the virtual machine name or ID"
    usage
    exit 1
  fi
}

set_vars() {
  MAC_LIST=`xm list -l $VM | grep -w "mac" | cut -d "(" -f 2 | cut -d ")" -f 1 | cut -d " " -f 2`
  VIF_NUM=`xm network-list -l $VM | grep -w "handle" | cut -d "(" -f 2 | cut -d ")" -f 1 | cut -d " " -f 2`
  DOMID=`xm list -l $VM | grep -w "domid"|cut -d "(" -f 2 | cut -d ")" -f 1 | cut -d " " -f 2`
}

get_attached_bridge() {
  ATTCHED_BRIDGE=`brctl show |grep -w vif$DOMID.$VIF_NUM`
}

attach_vif() {
# Attaches a virtual NIC to a bridge
  if [ -z $INTERFACE ]
  then
    INTERFACE="0"
  fi
  if [ -z $BRIDGE ]
  then
    BRIDGE="xenbr0"
  fi
  count=0
  for MAC in $MAC_LIST
  do
    if [ "$count" = "$INTERFACE" ]
    then
      echo "attaching eth$INTERFACE ($MAC) in $VM to bridge $BRIDGE"
      #read
      xm network-attach $VM mac=$MAC bridge=$BRIDGE
    fi
    (( count++ ))
  done
}

detach_vif() {
# Detaches a virtual NIC from a bridge
  echo "detaching eth$INTERFACE in $VM"
  #from bridge $ATTACHED_BRIDGE
  xm network-detach $VM $INTERFACE
}

####  Main Code Body  #######################################################

check_for_xen
set_vars
check_cli_args $*

echo $VM
echo $DOMID
read

if [ -z $VM ]
then
  usage
else
  case $MODE in
    attach)
      attach_vif 
    ;;
    detach)
      detach_vif
    ;;
  esac
fi