Warewulf debian tarball

From SOFTICE

Jump to: navigation, search


Contents

Status

Page is deprecated now, these modifications have been updated and included directly in a (beta) debian package for warewulf. This beta is available at http://softice.lakeland.usf.edu/downloads/warewulf/ and the general procedures to build that debian packages are documented at How-to:building_debian_packages

Synopsis

This how-to describes how to install the warewulf 2.5 tarball on a debian sarge (3.1) system. It sums up all the modifications that were necessary to the original tarball intended for Red Hat based systems.

Remark: the real test has so far been done with a warewulf 2.4 tarball, this page is the result of replicating modifications to a warewulf 2.5 tarball. I'll test it as soon as I have a secondary system to spare and keep updating the information below.

See Also: how-to:building_debian_packages

This how-to has been contributed to the warewulf wiki http://warewulf.lbl.gov/pmwiki/index.php?n=Debian-ingThe2.5Tarball

Tools of the trade: warewulf tarball

Let's start off by downloading warewulf 2.5 tarball:

Since we are going to modify files and directory, we'll first clean up the subversion information in our working-version source code tree:

  • find ./ -name '.svn' -type d -exec rm -r '{}' \;

As a reminder if your find skills are somewhat rusty:

-type d we're working on directories

-name '.svn'

-exec rm -r {} ; deletes each found .svn directory

At this point we have the archive ~/ww/warewulf-2.5.0-svn98.tar.gz to serve us as repository for the reference source code later on and a warewulf.deb directory in which we're going to do our Debian-ing.



Debian-ing the daemons init scripts location

Our first target will be the ~/warewulf/warewulf.deb/etc subdirectory which contains the perl scripts for the following warewulf daemons:

  • warewulf (for the master node to monitor cluster nodes)
  • wulfd (to run on each node)
  • vnfsd (to run on the master node to serve with the thttpd mini-web server the VNFS root images to the nodes)

Being meant for RedHat systems, the archive has the daemons' init scripts in etc/rc.d/init.d while a Debian system would expect them in etc/init.d/. Let's fix this:

  • mv etc/rc.d/init.d etc/
  • rm -r etc/rc.d

The ~/warewulf/warewulf.deb/Makefile needs also to be modified so that it now installs the init scripts from ./etc/init.d to /etc/init.d

The target 'install is the only one concerned, we need to replace the lines mentionning etc/rc.d/init.d as source for install with etc/init.d/

Original:

mkdir -p $(DESTDIR)/etc/sysconfig
mkdir -p $(DESTDIR)/etc/rc.d/init.d/
mkdir -p $(DESTDIR)/srv/vnfsd/
install -m 755 src/thttpd/thttpd                   $(DESTDIR)/usr/sbin/vnfsd
install -m 755 src/wulfd/wulfd                     $(DESTDIR)/usr/sbin/
cp -rap wwinitrd/*                                 $(DESTDIR)/var/warewulf/wwinitrd/
cp -rap etc/warewulf/*                             $(DESTDIR)/etc/warewulf/
install -m 755 etc/rc.d/init.d/warewulf      $(DESTDIR)/etc/rc.d/init.d/
install -m 755 etc/rc.d/init.d/wwnewd        $(DESTDIR)/etc/rc.d/init.d/
install -m 755 etc/rc.d/init.d/wulfd         $(DESTDIR)/etc/rc.d/init.d/
install -m 755 etc/rc.d/init.d/vnfsd         $(DESTDIR)/etc/rc.d/init.d/
install -m 644 etc/sysconfig/wulfd                 $(DESTDIR)/etc/sysconfig/

Replaced by:

mkdir -p $(DESTDIR)/etc/sysconfig
mkdir -p $(DESTDIR)/etc/init.d/
mkdir -p $(DESTDIR)/srv/vnfsd/
install -m 755 src/thttpd/thttpd                   $(DESTDIR)/usr/sbin/vnfsd
install -m 755 src/wulfd/wulfd                     $(DESTDIR)/usr/sbin/
cp -rap wwinitrd/*                                 $(DESTDIR)/var/warewulf/wwinitrd/
cp -rap etc/warewulf/*                             $(DESTDIR)/etc/warewulf/
install -m 755 etc/init.d/warewulf           $(DESTDIR)/etc/rc.d/init.d/
install -m 755 etc/init.d/wwnewd             $(DESTDIR)/etc/init.d/
install -m 755 etc/init.d/wulfd              $(DESTDIR)/etc/init.d/
install -m 755 etc/init.d/vnfsd              $(DESTDIR)/etc/init.d/
install -m 644 etc/sysconfig/wulfd                 $(DESTDIR)/etc/sysconfig/

Debian-ing: daemons init scripts code: generalities

The previous step ensures that the daemons' init scripts will be installed at the correct location. We also need to inspect their code to debian-ize what needs to be.

Fortunately, very few things need to be fixed:

  • Red Hat systems use the daemon daemon-name arguments command to start and stop programs that need to be executed as daemons. In Debian, start-stop-daemon --start --exec daemon-name -- argument does the same job.
  • Red Hat systems also use the status daemon-name command which can be replaced on Debian systems by invoke-rc.d daemon-name status.
  • The scripts refer to /etc/init.d/functions which doesn't exist in a Debian tree. We can simply comment out the line in /etc/init.d/wulfd and /etc/init.d/warewulfd.
  • The scripts refer to /etc/sysconfig/wulfd which is a file containing only ADMIN_MASTER='localhost'. The contents have been pasted to /etc/init.d/wulfd which was testing its existence (test removed as well) then including it. Reason is that I don't know where such files go into a debian system (TODO).

Now let's go over the changes in each of the warewulf scripts in /etc/init.d/. To make things a little shorter, we will display below only the parts of the scripts' code relevant to the changes.

Debian-ing: daemons init scripts code: /etc/init.d/wulfd

Reminder: wulfd is meant to be run on each of the nodes

#!/bin/bash 
# 
# chkconfig: 345 95 05 
# description: WULFD watches the status of the slave nodes on the cluster 
#              and keeps them configured properly and available to cluster 
#              users. 
# processname: wulfd 
# pidfile: /var/run/wulfd.pid 
 
#alessio: removing stuff below for debian 
#if [ ! -f "/etc/sysconfig/wulfd" ]; then 
#   exit 
#fi 
   
#alessio: same thing here  
# source function library 
#. /etc/init.d/functions 
#. /etc/sysconfig/wulfd 
 
# Define the master node that wulfd should be sending the node status to 
 
ADMIN_MASTER='192.168.0.1' 
#alessio: hard coded, bad bad bad! [TODO] 
 
 
RETVAL=0 
 
start() { 
   if [ -x /usr/sbin/wulfd ]; then 
      echo -n $"Starting wulfd: " 
      if [ -f /var/run/wulfd.pid ]; then 
         invoke-rc.d wulfd status 
         exit 1 
      else 
         start-stop-daemon --start --exec /usr/sbin/wulfd -- -h $ADMIN_MASTER $WULFD_OPTIONS </dev/null 
         RETVAL=$? 
         echo 
      fi 
   fi 
} 


stop() { 
   if [ -f /var/lock/subsys/wulfd ]; then 
      echo -n $"Shutting down wulfd: " 
      start-stop-daemon --stop -name wulfd 
      RETVAL=$? 
      echo 
   fi 
   test -f /var/run/wwnodestatus        && rm -f /var/run/wwnodestatus 
   test -f /var/lock/subsys/wulfd       && rm -f /var/lock/subsys/wulfd 
} 
 
stats() { 
   if [ -x /usr/sbin/wulfd ]; then 
      invoke-rc.d wulfd status 
      RETVAL=0 
   fi 
} 
 

Debian-ing: daemons init scripts code: /etc/init.d/warewulfd

reminder: warewulfd is meant to be run only on the master node

#!/bin/bash 
# 
# chkconfig: 345 95 05 
# description: WAREWULFD watches the status of the slave nodes on the cluster 
#              and keeps them configured properly and available to cluster 
#              users. 
# processname: warewulfd 
# pidfile: /var/run/warewulfd.pid 
 
# source function library 
#. /etc/init.d/functions 
 
RETVAL=0 
 
start() { 
   if [ -x /usr/sbin/warewulfd ]; then 
      echo -n $"Starting warewulfd: " 
      if [ -f /var/run/warewulfd.pid ]; then 
         invoke-rc.d warewulfd status  
      else 
         start-stop-daemon --start --exec /usr/sbin/warewulfd --  </dev/null 
         RETVAL=$? 
         echo 
         if [ $RETVAL -eq 0 ]; then 
            touch /var/lock/subsys/warewulfd 
            echo READY > /tmp/nodestatus 
         fi 
      fi 
   fi 
} 
 
stop() { 
   if [ -f /var/run/warewulfd.pid ]; then 
      echo -n $"Shutting down warewulfd: " 
      #alessio: the following would cause infinite recursion at shutdown
      #invoke-rc.d warewulfd stop 
      start-stop-daemon --stop --pidfile /var/run/warewulfd.pid
      RETVAL=$? 
      echo 
   fi 
   test -f /var/lock/subsys/warewulfd &&        rm -f /var/lock/subsys/warewulfd 
} 
stats() { 
   if [ -x /usr/sbin/warewulfd ]; then 
      invoke-rc.d warewulfd status 
      RETVAL=0 
   fi 
} 
 
reload() { 
   if [ -x /usr/sbin/warewulfd ]; then 
      echo -n $"Reloading warewulfd: " 
      killall -HUP warewulfd  
      retval=$? 
      echo 
   fi 
} 
 

Debian-ing: daemons init scripts code: /etc/init.d/vnfsd

#!/bin/bash 
# 
# chkconfig: 345 95 05 
# description: Warewulf Virtual Node File System Daemon (VNFSD) 
# processname: vnfsd 
# pidfile: /var/run/vnfsd.pid 
 
# source function library 
#. /etc/init.d/functions 
 
RETVAL=0 
 
start() { 
   if [ -x /usr/sbin/vnfsd ]; then 
      echo -n $"Starting vnfsd: " 
      if [ -f /var/run/vnfsd.pid ]; then 
         status vnfsd 
      else 
         start-stop-daemon --start --exec /usr/sbin/vnfsd -- -p 9874 -u nobody -i /var/run/vnfsd.pid -d /srv/vnfs </dev/null 
         RETVAL=$? 
         echo 
         if [ $RETVAL -eq 0 ]; then 
            touch /var/lock/subsys/vnfsd 
         fi 
      fi 
   fi 
} 
 
stop() { 
   if [ -f /var/run/vnfsd.pid ]; then 
      echo -n $"Shutting down vnfsd: " 
      killproc vnfsd 
      RETVAL=$? 
      echo 
   fi 
   test -f /var/lock/subsys/vnfsd &&    rm -f /var/lock/subsys/vnfsd 
} 
 
stats() { 
   if [ -x /usr/sbin/vnfsd ]; then 
      status vnfsd 
      RETVAL=0 
   fi 
} 
 
reload() { 
   if [ -x /usr/sbin/vnfsd ]; then 
      echo -n $"Reloading vnfsd: " 
      killproc vnfsd -HUP 
      retval=$? 
      echo 
   fi 
} 


TODO -- Debian-ing: /usr/lib/warewulf/Warewulf.pm

The file /usr/lib/warewulf/Warewulf.pm is the warewulf perl library used by other scripts of the distribution. The get_net_conf function is responsible for parsing the /etc/sysconfig/nework-scripts/ifcfg-eth0 or -eth1 file as indicated in /etc/warewulf/master.conf.

In order to adapt this to a Debian distrib, we first make sure that /etc/warewulf/master.conf refers to the proper network configuration file; Original:

ifcfg            = /etc/sysconfig/network-scritpts/ifcfg-

Replaced by:

ifcfg            = /etc/network/interfaces

Of course, while ifcfg- will be appended by the interface name for the cluster NIC (eth0, eth1, ...) and therefore contain only information about that particular interface, the Debian file contains the configuration of all interfaces. What's more, the syntax is, of course, different and thus calls for a different perl code to parse it.

This is where we need to dwelve into the get_net_conf function of the perl warewulf library and more specifically its main while loop;

Original code:

 
 while (<IFCFG>) { 
    chomp; 
    next unless $_; 
    ($entry,$value) = split (/=/, $_); 
    if ($entry eq 'IPADDR' ) { 
       $ipaddr = $value; 
    } elseif ( $entry eq 'NETWORK' ) { 
       $network = $value; 
    } elseif ( $entry eq 'NETMASK' ) { 
       $netmask = $value; 
    } 
  } 

If you look further, you'll notice that if the network information is missing, it is computed from the IP address and the netmask by calling $network = &ipcalc_network($ipaddre, $netmask). So let's modify the code to parse the Debian /etc/network/interfaces

TODO I'm not a perl programmer so I'll need to test that on my next install to make sure it works...

 
   open (IFCFG, "/etc/network/interfaces") 
     or die "Could not open: /etc/network/interfaces\n");  
 
   while (<IFCFG>) {  
     chomp;  
 
     #http://perl.org.il/pipermail/perl/2003-June/002238.html 
     my $currentline = $_; 
     foreach my $s ($currentline) { 
       $s =~ s/^\s+//; 
       $s =~ s/\s+$//; 
       $s =~ s/\s+/ /g; 
     } 
 
     ($entry,$value) = split (/\ /, $currentline); 
 
     if ( (${entry} eq 'iface') and (${value} eq $device')) {  
 
        while(<IFCFG>) {  
                chomp;  
 
                my $currentline = $_; 
                foreach my $s ($currentline) { 
                        $s =~ s/^\s+//; 
                        $s =~ s/\s+$//; 
                        $s =~ s/\s+/ /g; 
                } 
                 
                ($entry,$value) = split (/\ /, $currentline); 
                 
                if ($entry eq 'address' ) {  
                        $ipaddr = $value;  
                } elsif ( $entry eq 'network' ) {  
                        $network = $value;  
                } elsif ( $entry eq 'netmask' ) {  
                        $netmask = $value;  
                } 
        next unless $_;  
        } 
     }  
            next unless $_;  
}        

If the above code works, please send me peanuts in a nice package...

FIXME -- Debian-ing: the rest of /etc/warewulf/master.conf

While we are at it let's finish debian-ing master.conf by changing the command lines for starting the various services warewulf relies on.

Original:

[servers]
syslog     = `hostname`-admin
home nfs   = `hostname`-sfs
vnfs nfs   = `hostname`-sfs
... later down the file ...
[commands]
restart warewulfd = /sbin/service/ warewulfd restart > /dev/null 2>&1
restart dhcpd     = /sbin/service/ dhcpd restart > /dev/null 2>&1
restart nfs       = /sbin/service/ nfs restart > /dev/null 2>&1
restart inetd     = /sbin/service/ xinetd restart > /dev/null 2>&1
restart syslog    = /sbin/service/ syslog restart > /dev/null 2>&1


Replaced by:

[servers]
syslog     = 192.168.0.1
home nfs   = 192.168.0.1
vnfs nfs   = 192.168.0.1
... later down the file ...
[commands]
restart warewulfd = /usr/sbin/invoke-rc.d warewulfd restart > /dev/null 2>&1
restart dhcpd     = /usr/sbin/invoke-rc.d dhcpd restart > /dev/null 2>&1
restart nfs       = /usr/sbin/invoke-rc.d nfs-user-server restart > /dev/null 2>&1
restart inetd     = /usr/sbin/invoke-rc.d inetd restart > /dev/null 2>&1
restart syslog    = /usr/sbin/invoke-rc.d sysklogd restart > /dev/null 2>&1

Couple of remarks:

  • Hardcoding the IP is dirty... didn't have time to deal with potential DNS glitches so just wrapped it up like this, please test, edit, update and improve as you see fit :) TODO



Debian-ing: /usr/sbin/wwinit

2 modifications here; the 1st one, which is not tied to Debian or Red Hat, is the master node IP. Old habits preventing, I changed the following hardcoded statement at the beginning of the file:

$boot_ip = "10.128.0.1"; 

by:

$boot_ip = "192.168.0.1";


The second concern the generation of the network device in /etc/network/interfaces. We change this:

   if ( ! $master{'network'}{'boot device'} or $master{'network'}{'boot device'} eq "auto" ) { 
      print "Warewulf requires a specific network for booting the nodes.\n\n"; 
      print "   $master{'network'}{'admin device'}:1"; 
      print "   $boot_ip/$master{'network'}{'admin netmask'}\n"; 
      print "\n"; 
      while (1) { 
         print "Should I create this boot device alias and configure for you? [Y/n]: "; 
         chomp ($cont = <STDIN>); 
         if ( $cont =~ /^y[es]?$/i or ! $cont ) { 
            open(IFCFG, "> $master{'paths'}{'ifcfg'}$master{'network'}{'admin device'}:1"); 
            print IFCFG "DEVICE=$master{'network'}{'admin device'}:1\n"; 
            print IFCFG "IPADDR=$boot_ip\n"; 
            print IFCFG "NETMASK=$master{'network'}{'admin netmask'}\n"; 
            print IFCFG "BOOTPROTO=static\n"; 
            print IFCFG "ONBOOT=yes\n"; 
            close IFCFG; 
            system("/sbin/ifdown $master{'network'}{'admin device'}:1 >/dev/null 2>&1"); 
            system("/sbin/ifup $master{'network'}{'admin device'}:1 >/dev/null 2>&1"); 
            last 
         } elsif ( $cont =~ /^n[o]?$/i ) { 
            last; 
         } 
      } 

Into this:

   if ( ! $master{'network'}{'boot device'} or $master{'network'}{'boot device'} eq "auto" ) { 
      print "Warewulf requires a specific network for booting the nodes.\n\n"; 
      print "   $master{'network'}{'admin device'}:1"; 
      print "   $boot_ip/$master{'network'}{'admin netmask'}\n"; 
      print "\n"; 
      while (1) { 
         print "Should I create this boot device alias and configure for you? [Y/n]: "; 
         chomp ($cont = <STDIN>); 
         if ( $cont =~ /^y[es]?$/i or ! $cont ) { 
           open(IFCFG, "> $master{'paths'}{'ifcfg'}$master{'network'}{'admin device'}:1"); 
           print IFCFG "auto $master{'network'}{'admin device'}\n"; 
           print IFCFG "iface $master{'network'}{'admin device'} static\n"; 
           print IFCFG "address $boot_ip\n"; 
           print IFCFG "netmask $master{'network'}{'admin netmask'}\n"; 
           close IFCFG; 
           system("/sbin/ifdown $master{'network'}{'admin device'} >/dev/null 2>&1"); 
           system("/sbin/ifup $master{'network'}{'admin device'} >/dev/null 2>&1"); 
           last 
         } elsif ( $cont =~ /^n[o]?$/i ) { 
            last; 
         } 

Building a Debian VNFS

You can use any pre-made vnfs at this point, but why not making our own debian vnfs? how-to:warewulf_debian_vnfs


References

  • Warewulf website

http://warewulf.lbl.gov/pmwiki/index.php?n=Main.HomePage

  • Caosity website (warewulf email lists)

http://www.caosity.org/

  • Debian New Maintainers' Guide

http://www.debian.org/doc/maint-guide/

  • Debian Binary Package Building HOWTO

http://www.tldp.org/HOWTO/Debian-Binary-Package-Building-HOWTO/index.html

  • Link page from the above document

http://www.tldp.org/HOWTO/Debian-Binary-Package-Building-HOWTO/x267.html

  • debian-mentors email list

http://lists.debian.org/debian-mentors/

  • Debian Policy Manual

http://www.debian.org/doc/debian-policy/

  • Shadow Passwords How-To

http://www.ibiblio.org/pub/Linux/docs/HOWTO/Shadow-Password-HOWTO