TN extrbase

From FAIWiki
Jump to navigation Jump to search

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)