[I had to push participation in this mailing list aside for quite some time, trying to catch up]

Henning Sprang wrote:
Russ Allbery wrote:
Hm, that's interesting -- I didn't think about trying that route.  How
do I specify a different base.tgz to unpack in the newly created file
system?  It looks like the path to base.tgz is hard-coded into
subroutines-linux, at least in the version I'm currently looking at
(which isn't the latest).

The task extrbase looks in the directory "basefiles" inside the fai
configspace for a file

CLASS.tar.gz - for any of the clases defined for the host currentlyx
being installed.

I disliked this kind of behaviour, that's why I rewrote the hook in my configspace. I don't recommend it for the faint of heart, just to show
a different possibility.

I was faced with having to install

 - Debian Etch/Lenny/Speedy/Sid
 - Ubuntu 8.04 8.10 9.04
 - SuSE Linux Enterprise Server 10 / 10SP1 / 10SP2

in 32 and 64 bit which would mean I had to find names for 20 classes, (which are never used elsewhere) just to be able pull in the correct base image. (And _never_ have a base.tgz in your nfs root, or fai would always use this one. At least if i recall correctly.)

The most significant change to default behaviour is, that integration
of Debian Speedy (current "testing") was just a question of allowing
the variable OS_VERS to assume the value "speedy". (I set these during execution of a different script in class/...) Because no valid base image can be found, debootstrap is used automatically. Ubuntu 9.04 would have been equally easy, but the appropriate debootstrap script was missing from my nfsroot. (I blame Debian Lenny.)

Doing it the canonical way would have meant to create 2 new classes e.g. BASE-DEBIAN-SPEEDY-X86_32 and -X86_64 and either provide base images or also create 2 new files BASE-DEBIAN-SPEEDY-X86_32.var and -X86_64.var
in $FAI/classes which contain the correct FAI_DEBOOTSTRAP variable.

This script assumes there are 3 variables

  OS_TYPE     (Debian, Ubuntu, SLES)
  OS_VERS     (etch/lenny/speedy/.. or
               gutsy/intrepid/jaunty or
  OS_ARCH     (X86_32 / X86_64)

which define the operating system to be installed.

hint: You can provide these variables at the boot-prompt.

There's also an unconditional "cat" in line 27 - it's a recent addition and I didn't found the time to properly secure this command.

the scary stuff

(Please keep in mind that I controll 4 very different FAI-environments
 with exactly the same config-space.)

There a other variables, most importantly:

  SWREPO      the location of the base-files, it doesn't hurt if it's
              not defined-> the default behaviour kicks: $FAI/basefiles
              (I didn't like to have to carry these multi-megabyte files
               in my config-space all the time.)


In my environment a so called IDENTITYFILE is written during execution of the scripts in $FAI/class/. It holds a lot of different options and is used mostly to limit the number of classes. (I'm using classes mostly to define which "major building blocks" this installation should contain and define small environment- or host-dependent settings in the identity file.)

I'm also patching fai on the fly, so I don't have to remember to patch the nfs roots after an upgrade. This behaviour is customizable
via a script in $FAI/class/.

 install_packages -> "and"-patch
 fai-do-scripts   -> "perl"-patch, if necessary

#! /bin/bash

# I found it necessary to modify the default behaviour, because
# fai has some quirks I don't like.
#   - if base.tgz exists then always use it instead of bootstrapping
#   - find a valid base image via a class
#     this class is used nowhere else and doesn't have
#     other uses.
#  (- always state a Debian base archive is being extracted)
#   - fai barfs on debootstraps exit code 141
#     (this still needs a proper analysis)

# read additional information from the environment or from the
# identityfile, values given in identityfile have preference!
# this file must contain:
#   FAI_OSTYPE - which OS to install (Debian, Ubuntu, SuSE?)
#   FAI_OSVERS - which version to install? (etch, lenny, sid, hardy, 10SP2)
#   FAI_OSARCH - x86_32 or x86_64?
if [ -r ${IDENTITYFILE} ] ; then
        source ${IDENTITYFILE}

## Preparation - lenny's grub has a small cosmetic flaw
##   it always tries to read the device map from the root
##   device - but an nfsroot doesn't have / need a device map
# PATCHLOCATION is defined in class/DEFAULT
# may have been overwritten by a later definition
cat $PATCHLOCATION/grub-install.patch | patch -p 1 

## Step 1 - check for debootstrap options or create new ones
if [ -z ${FAI_DEBOOTSTRAP} ] ; then
        case ${OS_TYPE} in
if [ -z ${FAI_DEBOOTSTRAP_OPTS} ] ; then
        # make sure debootstrap contains correct architecture
        case ${OS_ARCH} in

        # make sure ubuntu is installed with aptitude
        # the intrepid-script on Debian/Lenny doesn't include it
        if [[ ${OS_TYPE} = "Ubuntu" ]] ; then

        # don't install dhcp-client or dhcp3-client
        # it's only installed when requested


# this code is copied from task_extrbase() found in
# <NFSROOT>/usr/lib/fai/subroutines-linux
# changes:
#   - don't lie about installing debian
#   - if IGNOREBASETGZ is set, the base.tgz is ignored
#   - regard debootstraps exit code 141 as valid

echo "Installing ${OS_TYPE} base archive."

if [[ $SWREPO != "" ]] ; then
        wget -q -P /tmp/ 

# find & extract the base file
if [ -r ${basefile} ] ; then
        echo "Unpacking ${basefile}"
        tar xzf ${basefile} -C ${target}
        # or use base.tgz (if allowed) / call debootstrap 
        echo "Could not find BASE_${OS_TYPE}-${OS_VERS}-${OS_ARCH}.tar.gz in 
        [ $do_init_tasks -eq 0 ] && 
        if [ -f $basefile ] && [[ $IGNOREBASETGZ = 0 ]] ; then
                # extract the tar file which was the result of debootstrap
                echo "Extracting $basefile"
                gzip -dc $basefile | tar -C $FAI_ROOT -xpf -
                echo "Calling debootstrap."
                [ -z "$FAI_DEBOOTSTRAP" ] && die "$FAI_DEBOOTSTRAP undefined. 
                call_debootstrap $FAI_DEBOOTSTRAP $FAI_DEBOOTSTRAP_OPTS
                [[ $verbose = 1 ]] && echo "debootstrap return value: $RETVAL"
                # debootstrap completes with the following message:
                # "I: Base system installed successfully." but the return code 
is 141
                if [ $RETVAL = 141 ] ; then
                task_error 801 $RETVAL

# now we can copy fstab
[ -f $fs ] && mv $fs $fs.old
[ -f $LOGDIR/fstab ] && cp -p $LOGDIR/fstab $fs

# no need for task_extrbase() anymore, everything's set up
skiptask extrbase

Antwort per Email an