Debian Clusters for Education and Research: The Missing Manual

Setting a Dynamic Hostname by DNS

From Debian Clusters

Jump to: navigation, search

Often, rather than having to set /etc/hostname for each worker node, it's more helpful to have it assign the hostname to itself automatically at boot based on the information handed to it by DNS (see Name Service: DNS and BIND). This is particularly true since it's most expedient to create one worker node image and then broadcast that image onto the other nodes, and it's pain to go through and change each one's hostname. Further, since all the information for which machine is which is located in DNS, why make it necessary to change that in two places?

Dotquad.c

There's a small script that set this for you, if DNS has been set up. It requires the binary from dotquad.c. First, save the following, dotquad.c, on the machine.

/* This file is in the public domain. */

#include <stdlib.h>
#include <stdio.h>

void range(int a){
        /* die if not valid octet */
        if (a<0) exit(1); if (a>255) exit(1);
}

int main(int argc, char* argv[]){
        int a, b, c, d;
        unsigned int ip = 0;

        if (argc != 2) exit(1);
        if (sscanf(argv[1], "%i.%i.%i.%i", &a, &b, &c, &d)<4) exit(1);
        range(a); range(b); range(c); range(d);
        ip = ip * 256 + a;
        ip = ip * 256 + b;
        ip = ip * 256 + c;
        ip = ip * 256 + d;
        printf("%u\n", ip);
        exit(0);
}

The binary of this file needs to be compiled and placed at /bin/dotquad, because the custom hostnames script will reference it there. If you haven't installed g++ yet, do that now (apt-get install g++). Then,

g++ dotquad.c -o /bin/dotquad

Custom Hostname Script

Below is the script that will automatically set the hostname based on DNS for the machine. I recommend setting /etc/hostname to some default value common to all of the machines, like amnesia. Then you can tell at a glance if DNS is working. Before this script will work, host must be installed on the machine. Do this with

apt-get install host

Then save the file below in /etc/init.d/, make it executable (chmod +x <filename>), and then symlink it into /etc/rc2.d, something like this:

ln -s /etc/init.d/hostnamecustom /etc/rc2.d/S21hostnamecustom

You can also start or stop it at the command line, after it's moved to /etc/init.d/. This won't take affect for any existing bash sessions; you'll have to log out and log back in to see the change.

/etc/init.d/hostnamecustom start

Hostnamecustom

#!/bin/sh
DOTQUAD=/bin/dotquad
case "$1" in
    start)
    echo -n 'Setting system hostname: '
        sleep 2
        for x in `ls /proc/sys/net/ipv4/conf/ | grep -v lo | grep -v all | grep -v default` ; do
        interface=$x
        echo Trying interface $x
        ip=`ifconfig $interface | grep "inet addr" | cut -d":" -f 2 | awk '{print $1}'`
        echo "IP resolved to $ip"
        if $DOTQUAD "$ip" >/dev/null ;
        then
                host=`host $ip 2>/dev/null | head -n 1 | awk '{print $2}' 2>/dev/null`
                echo "$host"
                if [ "x$host" != "x" ] ; then
                        hname=`echo $host | cut -d"." -f1`
                        echo "Host name is $hname"
                        sysctl -w kernel.hostname=$hname
                        dname=`echo $host | cut -d"." -f2-`
                        echo "Domain name is $dname"
                        sysctl -w kernel.domainname=$dname || true

                        # save the current /etc/hosts file
                        cp /etc/hosts /etc/hosts.orig || true

                        # strip out any existing entry for this host
                        cat /etc/hosts | grep -v $hname | cat > /etc/hosts.new

                        # add the new IP fqdn hname to the /etc/hosts.new file
                        echo $ip $hname $host >> /etc/hosts.new

                        # mv the new file into place
                        mv /etc/hosts.new /etc/hosts

                        # save the current /etc/hostname file
                        cp /etc/hostname /etc/hostname.orig || true

                        # add the new hostname to /etc/hostname.new
                        echo $hname >> /etc/hostname.new

                        # move hostname.new into place
                        mv /etc/hostname.new /etc/hostname

                        exit 0
                fi
        fi
        done
        if [ "x$interface" = "x" ] ; then
                echo "Assigning hostname failed."
        else
                echo `ifconfig eth0`
                echo done.
        fi
        ;;

    stop)
    echo -n 'Restoring original hostname '

        if [ -f /etc/hostname ] ; then
                hostname --file /etc/hostname
        fi
        if [ -f /etc/hosts.orig ] ; then
                mv /etc/hosts.orig /etc/hosts || true
        fi
        ;;

    restart|reload|force-reload)
            $0 stop
            sleep 2
            $0 start
            ;;
esac
Personal tools