User:BrianShowalter/Using FAI to install Linux-vservers

From FAIWiki
Jump to: navigation, search

This document explains how to set up and use FAI to install Linux vservers. It assumes that the vserver patches have already been compiled into the kernel that will be installed by FAI.


In the $FAI_CONFIGDIR or /usr/lib/fai directory, there is a file called subroutines which contains functions that handle certain FAI tasks. Load this file into a text editor. Around line 112 there is a line that executes "unset task_$taskname". Comment out this line so that the task functions will remain available for use when installing vserver children.


In $FAI_CONFIGDIR/class/50-host-classes, set up the vserver host and child classes similar to the following:

#!/bin/sh

class $HOSTNAME in
   vshost)
      echo "FAIBASE VSHOST VSCOMMON";;
   vschild1)
      echo "VSCHILD VSCOMMON APACHE" && exit 0;;
   vschild2)
      echo "VSCHILD VSCOMMON MYSQL" && exit 0;;
   vschild3)
      echo "VSCHILD VSCOMMON POSTFIX" && exit 0;;
   *)
      echo "FAIBASE DHCPC";;
esac

ifclass I386 && echo "GRUB"
exit 0


In $FAI_CONFIGDIR/class/vshost.var, set up the names of the child vservers that are associated with a host:

vschildren="vschild1 vschild2 vschild3"


Set up the vserver child classes (one class file per child) as follows in $FAI_CONFIGDIR/class/<childname>.var:

vsname="vs1"
childdev="eth0"
childip="192.168.0.10"
childprefix="24"


Copy $FAI_CONFIGDIR/debconf/FAIBASE to $FAI_CONFIGDIR/debconf/VSCHILD.


In $FAI_CONFIGDIR/hooks/finish.VSHOST, create a file with the following contents:

#!/bin/sh
#
# $FAI_CONFIGDIR/hooks/finish.VSHOST
#
# Save hostname and root directory of vserver base
VSHOST=$HOSTNAME
VSHOST_IPADDR=$IPADDR
VSHOST_FAI_ROOT=$FAI_ROOT

# Create vserver base directories
[ -e $FAI_ROOT/vservers ] || mkdir $FAI_ROOT/vservers
rm -f $FAI_ROOT/etc/vservers/.defaults/vdirbase
chroot $FAI_ROOT ln -s /vservers /etc/vservers/.defaults/vdirbase
chroot $FAI_ROOT setattr --barrier /vservers

mkdir -p $FAI_ROOT/etc/vservers/.defaults/apps/debootstrap
echo "http://$mirrorhost/debian" >$FAI_ROOT/etc/vservers/.defaults/apps/debootstrap/mirror

# Check whether any vserver children need to be installed
if [ -n "$vschildren" ]; then
        for childhost in $vschildren; do
                HOSTNAME=$childhost
                hostname $childhost
                echo "vserver child hostname set to $childhost"
                sleep 3
            export HOSTNAME

                task vschild_defclass
                task defvar

                # Set up FAI_ROOT to point to vserver child root
                export FAI_ROOT="$VSHOST_FAI_ROOT/vservers/$vsname"
                export ROOTCMD="chroot $FAI_ROOT"
                export IPADDR=$childip

                # Variables for cfengine
                target=$FAI_ROOT

                # Create child vserver
                task vschild_create

                # Install & configure vserver packages
                task vschild_install
        done
fi

# Restore hostname, IP address and root directory of vserver base
export HOSTNAME=$VSHOST
hostname $VSHOST
export IPADDR=$VSHOST_IPADDR
export FAI_ROOT=$VSHOST_FAI_ROOT
export ROOTCMD="chroot $FAI_ROOT"


In $FAI_CONFIGDIR/hooks/subroutines, create a file with the following contents:

#! /bin/bash
#
# $FAI_CONFIGDIR/hooks/subroutines

# Custom FAI subroutines to install vserver children
#
# Written by Brian Showalter
# 11 Feb 2006

task_vschild_defclass() {
        # Reevaluate classes
        fai-class -T $FAI/class $LOGDIR/FAI_CLASSES
        classes=$(< $LOGDIR/FAI_CLASSES)

    # define classes as: a.b.c.d for cfengine -D
    # this doesn't work without echo
    cfclasses=$(echo $classes)
    cfclasses=${cfclasses// /.}
    [ "$debug" ] && echo "cfclasses: $cfclasses"
}

task_vschild_create() {
        echo "Creating vserver $vsname"
        local removepkgs="sparc-utils,dhcp-client,lilo,makedev,pcmcia-cs,ppp,pppconfig,pppoe"
        removepkgs="${removepkgs},pppoeconf,setserial,syslinux,fdutils,libpcap0"
        removepkgs="${removepkgs},pciutils,ipchains,iptables,jove,nano"

        chroot $VSHOST_FAI_ROOT /usr/sbin/vserver $vsname build -m debootstrap \
                --hostname $childhost --interface $childdev:$childip/$childprefix -- \
                -d sarge -m http://$mirrorhost/debian -- --exclude="$removepkgs"
}

task_vschild_updatebase() {
        if [ "$FAI_ACTION" = "install" ]; then
                # Some packages must access /proc even in chroot environment
                mount -t proc proc $FAI_ROOT/proc

            # if libc is upgraded init u is called in chroot environment and
            # then init will eat up much cpu time
            fai-divert -a /sbin/init /usr/sbin/liloconfig /usr/sbin/invoke-rc.d
            # fake some more programs
#           fai-divert -a /etc/init.d/nis /sbin/start-stop-daemon
#           cp /sbin/start-stop-daemon $FAI_ROOT/sbin/start-stop-daemon
        fi

        # update the apt-get information inside the nfsroot
        export aptopt='-y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold"'
        $ROOTCMD apt-get $aptopt update
        $ROOTCMD apt-get $aptopt check
        [ $? -ne 0 ] && $ROOTCMD apt-get $aptopt -f install </dev/null
        $ROOTCMD dpkg -C
        [ $? -ne 0 ] && yes '' | $ROOTCMD dpkg --configure -a
        # using the above value, causes an error: "dpkg need action"
        export aptopt=
        $ROOTCMD apt-get $aptopt -f -y dist-upgrade </dev/null
        # update dpkg info which packages are available
        tmp=$($ROOTCMD mktemp)
        $ROOTCMD apt-cache dumpavail > $FAI_ROOT/$tmp
        $ROOTCMD dpkg --update-avail $tmp
        rm -f $FAI_ROOT/$tmp
}

task_vschild_install() {
        task debconf
        task prepareapt
        task vschild_updatebase
        task instsoft
        task configure
}

The two commented-out lines above cause problems when starting vserver children.


In $FAI_CONFIGDIR/package_config/VSCOMMON, insert the following package names to install common software. This is similar to those installed with the FAIBASE class, except that it doesn't include packages that should not go in a vserver child, such as hdparm or nfs-common:

PACKAGES aptitude
bzip2
cfengine
cron
debconf-utils
file
less
linuxlogo
rsync
ssh
sysutils
time


In $FAI_CONFIGDIR/package_config/VSHOST, insert the following package names to install the vserver utility software:

PACKAGES aptitude
util-vserver
vserver-debiantools


In $FAI_CONFIGDIR/scripts/VSCHILD/10-misc, insert the following:

#! /bin/sh

# (c) Thomas Lange, 2001-2005, lange@debian.org

error=0 ; trap "error=$((error|1))" ERR

# assuming that make-fai-nfsroot.conf sets
# FAI_LOCAL_REPOSITORY="deb file:/fai/files packages/"
# install additional packags that are located in /fai/files/packages/
if [ -d /fai/files/packages ] && [ ! -f /fai/files/packages/Packages.gz ]; then
    # Mm. It seems not to be a simple repository. I assume it's configured in sources.list
    echo "WARNING! Index file Packages.gz is missing in /fai/files/packages."
fi

fcopy /etc/hostname || echo $HOSTNAME     > $target/etc/hostname
echo $time_zone    > $target/etc/timezone
ln -fs /usr/share/zoneinfo/${time_zone} $target/etc/localtime

fcopy -iM /etc/hosts /etc/motd

# set root password
echo "root:$rootpw" | $ROOTCMD chpasswd --encrypted
# make /root accessable only by root
chmod 0700 $target/root
chown root:root $target/root
# copy default dotfiles for root account
fcopy -ir /root

# create keyboard layput table
$ROOTCMD bash -c "echo 'console-data console-data/keymap/full select $FAI_KEYMAP' | debconf-set-selections"
$ROOTCMD install-keymap $FAI_KEYMAP || true
# dumpkeys | gzip -9f >$target/etc/console/boottime.kmap.gz

exit $error


In $FAI_CONFIGDIR/scripts/VSCHILD/20-misc, insert the following:

#! /usr/bin/cfengine

control:
      OutputPrefix = ("cfengine")
      actionsequence = ( tidy )
      EditFileSize = ( 30000 )

tidy:
      any::
            ${target}/etc/rc?.d pattern=S??exim4 R=0 age=0
            ${target}/etc/rc?.d pattern=S??klogd R=0 age=0
            ${target}/etc/rc?.d pattern=S??makedev R=0 age=0
            ${target}/etc/rc?.d pattern=S??nfs-common R=0 age=0
            ${target}/etc/rc?.d pattern=S??portmap R=0 age=0
            ${target}/etc/rc?.d pattern=S??postfix R=0 age=0
            ${target}/etc/rc?.d pattern=S??rsync R=0 age=0


In $FAI_CONFIGDIR/scripts/VSHOST/10-misc, insert the following:

#! /usr/bin/cfengine

control:
      OutputPrefix = ("cfengine")
      actionsequence = ( directories editfiles )
      EditFileSize = ( 30000 )

directories:
      any::
            ${target}/vservers mode=1000 owner=0 group=0

editfiles:
      any::
            { ${target}/etc/ssh/sshd_config
                LocateLineMatching "#ListenAddress 0.0.0.0"
                ReplaceLineWith "ListenAddress ${IPADDR}"
            }