Example: Postboot Scripts for Creating Hostnames and Name Resolution

This post walks through an example slice that uses postboot scripts to assign hostnames to each VM and to add entries into /etc/hosts so that the VMs can address each other using the hostnames.   This example is useful in its own right but may also serve as an introduction to  postboot scripts.

Setting up the Request:

Start by creating the following topology in Flukes:

Configure the slice with some basic requirements by selecting your favorite node type, image, and domain for Node0 and NodeGroup0.  Select the number of VMs in the group for NodeGroup0.  These settings can be chosen by right-clicking the node or node group and choosing “Edit Properties”.

Assign IP addresses to all VMs using the “Auto IP” button.

At this point you should be able to submit your slice to ExoGENI and it will be instantiated.  However, you can only access the VMs on the dataplane (“Link0”) using IP addresses.  For many application this is sufficient, however some applications use hostnames and assume the existence of DNS to resolve the hostnames.   In addition, using “Auto IP” can make it difficult to find the IPs that ExoGENI chosen (especially for large slices).

Modifying the Postboot Script:

It is desirable to programmatically assign hostnames to VMs and configure the slice to resolve the names to the appropriate IPs.  We can accomplish this using postboot scripts.  Hostnames can be based on the node or group name and the index within the group.  Name resolution can be achieved by inserting the hostnames and IPs into /etc/hosts in each VM.   Since the entire slice is maintained by the user through ExoGENI it does not need a dynamic name resolution system like DNS.

Edit the Postboot Scripts for Node0 and NodeGroup0 (right-click the node or node group -> edit properties -> click “PostBoot Script”).  In the text box add the following script:

#!/bin/bash

echo $Node0.IP("Link0") Node0 >> /etc/hosts
#set ( $max = $NodeGroup0.size() - 1 )
#foreach ( $i in [0..$max] )
 echo $NodeGroup0.get($i).IP("Link0") `echo $NodeGroup0.get($i).Name() | sed 's/\//-/g'` >> /etc/hosts
#end

echo `echo $self.Name() | sed 's/\//-/g'` > /etc/hostname
/bin/hostname -F /etc/hostname

The script is a Velocity template that will be processed by ExoGENI for each VM and executed at startup.   Submit the request to ExoGENI.   The resulting slice should have assigned hostnames to each VM and have modified /etc/hosts on each VM.

For example, the script that was executed on Node0 looks like this:

root@Node0:~# neuca-user-script 
#!/bin/bash
echo 172.16.100.1 Node0 >> /etc/hosts
echo 172.16.100.2 `echo NodeGroup0/0 | sed 's/\//-/g'` >> /etc/hosts
echo 172.16.100.3 `echo NodeGroup0/1 | sed 's/\//-/g'` >> /etc/hosts
echo 172.16.100.4 `echo NodeGroup0/2 | sed 's/\//-/g'` >> /etc/hosts
echo 172.16.100.5 `echo NodeGroup0/3 | sed 's/\//-/g'` >> /etc/hosts
echo `echo Node0 | sed 's/\//-/g'` > /etc/hostname
/bin/hostname -F /etc/hostname

The resulting /etc/hosts file on Node0 looks like this:

root@Node0:~# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.16.100.1 Node0
172.16.100.2 NodeGroup0-0
172.16.100.3 NodeGroup0-1
172.16.100.4 NodeGroup0-2
172.16.100.5 NodeGroup0-3

This configuration allows for the addressing of other VMs by hostnames like:

root@Node0:~# ping -c 4 NodeGroup0-0
PING NodeGroup0-0 (172.16.100.2) 56(84) bytes of data.
64 bytes from NodeGroup0-0 (172.16.100.2): icmp_req=1 ttl=64 time=4.73 ms
64 bytes from NodeGroup0-0 (172.16.100.2): icmp_req=2 ttl=64 time=0.593 ms
64 bytes from NodeGroup0-0 (172.16.100.2): icmp_req=3 ttl=64 time=0.529 ms
64 bytes from NodeGroup0-0 (172.16.100.2): icmp_req=4 ttl=64 time=0.317 ms
--- NodeGroup0-0 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.317/1.543/4.736/1.846 ms

Postboot Script Explanation:

1.  Specify the interpreter

#!/bin/bash

2.  Add Node0’s IP and name to /etc/hosts.  The Velocity replacement refers to Node0 as “$Node0”.   The function IP(“Link0”) is called on Node0 to get the IP address of the interface connected to “Link0”.

echo $Node0.IP("Link0") Node0 >> /etc/hosts

After template expansion the line looks like:

echo 172.16.100.1 Node0 >> /etc/hosts

3.  Add NodeGroup0’s IPs to /etc/hosts.  This requires an entry for each VM in the group, but we do not know the number of VMs a priori.  A Velocity object for each VM in the group is accessed using an index.  We use the Velocity instructions to set a variable (“$max”) to the highest in index then loop through the group adding a line to the script for each VM.  Each VM in the group is accessed by the function get(<index>).  The IP is accessed in the same way as the stand-alone VM by using IP(“Link0”).  In this case we are also using the name of the VM by using the Name() function.

#set ( $max = $NodeGroup0.size() - 1 )
#foreach ( $i in [0..$max] )
 echo $NodeGroup0.get($i).IP("Link0") `echo $NodeGroup0.get($i).Name() | sed 's/\//-/g'` >> /etc/hosts
#end

After template expansion the line looks like:

echo 172.16.100.2 `echo NodeGroup0/0 | sed 's/\//-/g'` >> /etc/hosts
echo 172.16.100.3 `echo NodeGroup0/1 | sed 's/\//-/g'` >> /etc/hosts
echo 172.16.100.4 `echo NodeGroup0/2 | sed 's/\//-/g'` >> /etc/hosts
echo 172.16.100.5 `echo NodeGroup0/3 | sed 's/\//-/g'` >> /etc/hosts

Note that the ExoGENI names of the VMs in the group contain a “/” which is not allowed in a host name.  We pipe the name to sed in order to replace the “/” with a “-“.

4. Add the name of the VM to the /etc/hostname file and reset the hostname.   The variable “$self” refers to the current VM.

echo `echo $self.Name() | sed 's/\//-/g'` > /etc/hostname
/bin/hostname -F /etc/hostname

 

Have something to add?

Loading Facebook Comments ...