Dynamic hostname for VM’s generated from Virtualbox

I am currently working on dynamic environment provisioning for baremetal and hypervisors. Going through my notes, I found the following post, it was obviously copied from somewhere and i don’t have the URL for it. I am posting it here again for future reference as i think it is a very clever idea.

These scripts are used for simple management of hostnames for several VirtualBox VMs comprising a test or sandbox environment on your local machine.
Architecture:

  • Each VM is configured to use bridged network adapter, so all VMs and the host can see each other
  • A script is installed in each VM to run on post-ifup, which grabs VM’s IP, puts “$IP $desired-hostname $desired-fully-qualified-hostname” into /etc/hosts, changes hostname correspondingly, and puts VM’s hostname and fq-hostname into VM’s properties
  • A script is used on the host machine, which loops through running VMs, and updates /etc/hosts on the host machine and on the VMs

Setup:

1. On CentOS/RedHat VM:
1.1. put “ifup-local.sh” to /etc/sysconfig/network-scripts directory
1.2. change HN and FQHN variable values to desired hostname and fully qualified hostname for this VM
1.3. make soft link to the file from /sbin: ln -s /etc/sysconfig/network-scripts/ifup-local.sh /sbin/ifup-local
2. On the host use update-vms script to update VMs and host’s /etc/hosts files when VMs are started, stopped, or network configuration (IPs) is updated

#!/bin/bash
# CentOS/RedHat neworking scripts call /sbin/ifup-local in the end of ifup-post. This script should be either put at /sbin/ifup-local, ore soft-linked

# desired hostname
HN=myhostname

# desired fully qualified hostname
FQHN=$HN.mydomain

# additional fully qualified hostnames
ALTHN="s1.$FQHN s2.$FQHN"

# get current IP address (assuming there is only one non-127.0.* network interface
IP_ADDR=$(/sbin/ifconfig eth0 2>&1 | grep 'inet addr:' | grep -v '127.0.' | cut -d: -f2 | awk '{ print $1}')

if [ -n "$IP_ADDR" ]
then
  # remove potentially existing old line from hosts
  grep -Ev " $FQHN\$" /etc/hosts | grep -Ev "$IP_ADDR " > /tmp/hosts
  # add new line to hosts
  echo -n "$IP_ADDR $FQHN" >> /tmp/hosts
  for s in "$ALTHN"
  do
echo -n " $s" >> /tmp/hosts
  done
echo " $HN" >> /tmp/hosts
  cp /tmp/hosts /etc/hosts
  # set hostname
  hostname $HN
  # set VirtualBox VM properties
  VBoxControl guestproperty set /VirtualBox/GuestInfo/Net/0/V4/HN $HN 2>&1 > /dev/nul
  VBoxControl guestproperty set /VirtualBox/GuestInfo/Net/0/V4/FQHN $FQHN 2>&1 > /dev/nul
  VBoxControl guestproperty set /VirtualBox/GuestInfo/Net/0/V4/ALTHN "$ALTHN" 2>&1 > /dev/nul
else
  # in case IP address was not found do nothing
  hostname localhost
fi

 

#!/bin/bash
# this script should be run on the VMs' host to synchronize all VMs' and the host's /etc/hosts files
# list all running VMs
VMS=$(VBoxManage list runningvms)

# create a base for VMs' /etc/hosts file
echo "127.0.0.1 localhost.localdomain localhost" > /tmp/vmhosts
echo "::1 localhost6.localdomain6 localhost6" >> /tmp/vmhosts
# here we will collect fq-hostnames of all VMs that have corresponding properties set
VMHNS=""
for VM in $VMS
do
  # VirtualBox lists VM names and UUIDs in its output; we are only interested in UUIDs
  if [[ "${VM:0:1}" == '{' ]]
  then
    # remove curly braces around VM UUID
    VM="${VM#\{}"
    VM="${VM%\}}"
    # get VM IP from VM's properties
    IP=$(VBoxManage guestproperty get $VM /VirtualBox/GuestInfo/Net/0/V4/IP | grep "Value: ")
    IP=${IP#Value\: }
    # get VM hostname from VM's properties
    HN=$(VBoxManage guestproperty get $VM /VirtualBox/GuestInfo/Net/0/V4/HN | grep "Value: ")
    HN=${HN#Value\: }
    # get VM fq-hostname from VM's properties
    FQHN=$(VBoxManage guestproperty get $VM /VirtualBox/GuestInfo/Net/0/V4/FQHN | grep "Value: ")
    FQHN=${FQHN#Value\: }
    # get VM fq-hostname from VM's properties
    ALTHN=$(VBoxManage guestproperty get $VM /VirtualBox/GuestInfo/Net/0/V4/ALTHN | grep "Value: ")
    ALTHN=${ALTHN#Value\: }
    if [[ -n "$VM" && -n "$IP" && -n "$HN" && -n "$FQHN" ]]
    then
echo "Processing VM $VM - $IP - $FQHN - $HN - $ALTHN"
      # remove potentially existing old record for this VM in host's /etc/hosts file
      grep -v "\(^\|[^a-zA-Z0-9\-\.]\)${FQHN//./\\.}\([^a-zA-Z0-9\-\.]\|$\)" /etc/hosts | grep -v "\(^\|[^a-zA-Z0-9\-\.]\)${HN//./\\.}\([^a-zA-Z0-9\-\.]\|$\)" | grep -v "\(^\|[^a-zA-Z0-9\-\.]\)${IP//./\\.}\([^a-zA-Z0-9\-\.]\|$\)" > /tmp/hosts
      # add a line for this VM to the file
      echo -n "$IP $FQHN" >> /tmp/hosts
      for s in "$ALTHN"
      do
echo -n " $s" >> /tmp/hosts
      done
echo " $HN" >> /tmp/hosts
      # update /etc/hosts file on the host (assuming that current user's password is in ~/Private/pwd file)
      sudo -S -p "" /bin/bash -c "cp /tmp/hosts /etc/hosts" < ~/Private/pwd       # add line for this VM to the VMs' /etc/hosts file       echo -n "$IP $FQHN" >> /tmp/vmhosts
      for s in "$ALTHN"
      do
echo -n " $s" >> /tmp/vmhosts
      done
echo " $HN" >> /tmp/vmhosts
      VMHNS="$VMHNS $FQHN"
    fi
fi
done

# get current host IP address and name (assuming there is only one non-127.0.* network interface)
HIP=$(/sbin/ifconfig 2>&1 | grep 'inet addr:' | grep -v '127.0.' | cut -d: -f2 | awk '{ print $1}')
HHN=$(hostname)
HFQHN=$(hostname -f)

# add a line for the host into /etc/hosts of all VMs
echo "$HIP $HHN $HFQHN" >> /tmp/vmhosts

# copy prepared VMs' /etc/hosts file to all VMs
if [ -n "$VMHNS" ]
then
for VMHN in $VMHNS
  do
scp -o NumberOfPasswordPrompts=0 -o StrictHostKeyChecking=no /tmp/vmhosts root@$VMHN:/etc/hosts
  done
fi

About rp

Architect for large, highly scalable LAMP applications and Technical Manager with special focus on metrics based continuous improvement of teams and products. Rajat has close to a decade of experience of a very wide range of skills related to infrastructure, middleware, app servers all the way to front-end technologies and software development methodologies including agile, iterative waterfall, waterfall as well as ah-hoc startup using the right approach in the right context to reduce time to market.