Warewulf debian tarball
From SOFTICE
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:
- su -
- mkdir ~/ww
- cd ~/ww
- wget http://warewulf.lbl.gov/downloads/snapshots/CURRENT/warewulf-2.5.0-svn98.tar.gz
- tar oxzf warewulf-2.5.0-svn98.tar.gz
- mv warewulf warewulf.deb
- cd warewulf.deb
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)
- 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

