TN extrbase
I've created this page in order to properly describe my custom extrbase hook inside this wiki. At this point it's mostly for myself. There's a link in http://wiki.fai-project.org/index.php/FAI_multi-distribution which points to a message I wrote to the mailing list. Since the posting is from May 2009 the posted code is somewhat outdated.
rationale
I disliked the default extrbase hook 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 the 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.
Special requirements
This script assumes there are 3 variables
OS_TYPE (Debian, Ubuntu, SLES) OS_VERS (etch/lenny/speedy/.. or gutsy/intrepid/jaunty or 10/10SP1/10SP2) OS_ARCH (X86_32 / X86_64)
which define the operating system to be installed.
The easiest way to supply these variables would be creating a couple of <classname>.var files inside class and announcing appropriate classes.
ETCH32.var may contain
OS_TYPE=Debian OS_VERS=etch OS_ARCH=x86_32
Warning: This hook fails if these variables are empty!
magic
There's another functionality which enables you to ignore the default base.tgz file and/or fetch base files from a http-server. The reason I implemented this was to move the huge basefiles out of my fai configspace. (Actually I wouldn't need to do this anymore, because my config-spaces are now kept in a subversion repository.)
If $BASELOCATION and $BASEFILENAME are empty, then the default location for basefiles is
$FAI/basefiles/BASE_${OS_TYPE}-${OS_VERS}-${OS_ARCH}.tar.gz
File: hooks/extrbase.DEFAULT
#! /bin/bash # Focus: # - find correct base archive and extract it # or # - call debootstrap (debian-style dists only) # Goal: # - chroot possible # - shell available # 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) ## Step 1 - check for debootstrap options or create new ones if [ -z ${FAI_DEBOOTSTRAP} ] ; then case ${OS_TYPE} in Debian) FAI_DEBOOTSTRAP="${OS_VERS} http://ftp.de.debian.org/debian/" BOOTSTRAP=1 ;; Ubuntu) FAI_DEBOOTSTRAP="${OS_VERS} http://de.archive.ubuntu.com/ubuntu/" BOOTSTRAP=1 ;; *) ;; esac fi if [[ ${BOOTSTRAP} == 1 && -z ${FAI_DEBOOTSTRAP_OPTS} ]] ; then # make sure debootstrap contains correct architecture case ${OS_ARCH} in X86_32) ARCH="--arch=i386" ;; X86_64) ARCH="--arch=amd64" ;; esac # make sure ubuntu is installed with aptitude # the intrepid-script on Debian/Lenny doesn't include it if [[ ${OS_TYPE} == "Ubuntu" ]] ; then INCLUDE="--include=aptitude" fi # don't install dhcp-client or dhcp3-client # it's only installed when requested EXCLUDE="--exclude=dhcp3-client,dhcp-client" FAI_DEBOOTSTRAP_OPTS="$ARCH $INCLUDE $EXCLUDE $FAI_DEBOOTSTRAP_OPTS" fi # 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." echo " custom basefile location: $BASELOCATION" echo " custom basefile filename: $BASEFILENAME" # default location DefaultBASEFILE=$FAI/basefiles/BASE_${OS_TYPE}-${OS_VERS}-${OS_ARCH}.tar.gz # keeps track whether an appropriate base image was found or not BASEFOUND=0 # use a software repository if it's available if [[ -n ${BASELOCATION} && -n $BASEFILENAME ]] ; then echo -e " downloading & extracting from\n ${BASELOCATION}" MyBASEFILE="${BASELOCATION}/${BASEFILENAME}" # is there a matching base image? if $(wget --spider -q $MyBASEFILE) ; then # okay, there is -> download and extract wget --progress=dot:mega -O - $MyBASEFILE | tar xz -C ${target} BASEFOUND=1 fi # fallback to "local" files elif [ -r ${DefaultBASEFILE} ] ; then echo " using ${DefaultBASEFILE}" tar xzf ${DefaultBASEFILE} -C ${target} BASEFOUND=1 fi if [[ $BASEFOUND == 0 ]] ; then # or use base.tgz (if allowed) / call debootstrap echo "Could not find BASE_${OS_TYPE}-${OS_VERS}-${OS_ARCH}.tar.gz in $FAI/DefaultBASEFILEs/" [ $do_init_tasks -eq 0 ] && DefaultBASEFILE=$NFSROOT/live/filesystem.dir/var/tmp/base.tgz if [ -f $DefaultBASEFILE ] && [[ $IGNOREBASETGZ = 0 ]] ; then # extract the tar file which was the result of debootstrap echo "Extracting $DefaultBASEFILE" gzip -dc $DefaultBASEFILE | tar -C $FAI_ROOT -xpf - else echo "Calling debootstrap." [ -z "$FAI_DEBOOTSTRAP" ] && die "$FAI_DEBOOTSTRAP undefined. Aborting" call_debootstrap $FAI_DEBOOTSTRAP $FAI_DEBOOTSTRAP_OPTS RETVAL=$? [[ $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 RETVAL=0 fi task_error 801 $RETVAL fi fi fs=$FAI_ROOT/etc/fstab # 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
---
TODO: Could somebody proofread this and test it out?
--ThomasNeumann 17:34, 3 February 2010 (UTC)