FAI update scripts?

Joerg Lehmann joerg at luga.de
Wed Jul 25 15:57:27 CEST 2001


Hi! 

On 25.07.01, Thomas Lange wrote:
> >>>>> On Tue, 24 Jul 2001 13:57:23 +1000 (EST), Matthew Palmer
> >>>>> <mjp16 at ieee.uow.edu.au> said:
>     >> From a quick thought-experiment, it seems the easiest way to
>     >> do
>     >> it is to
>     > mount /usr/share/fai from the server, then run the
>     > class-defining scripts and parse the package lists for the
>     > classes.
>     > Do you have any plans for such a script, or already have one
>     > written?  I'm not familiar enough with the system to just hack
>     > one up quickly, and I'd rather not duplicate effort.
>
> Very good idea, laos if it's not FAI's main aim to do daily
> administration. I'm working on this right now. I think the script
> should use the classes defined when the installation was performed.
> If
> you like to redefine the list of classes for a host, you should do a
> new installation. A first hack will be posted to the mailling list.
 
We use a modified version of /sbin/rcS_fai for regular updates of our
machines (see attachement). First the classes and variables are
defined, then install_packges and the usual install scripts are run. 
It's not perfect, but it works.
  
There are however some problems:
   
 - the removal of packages that are not installed leads to errors
    
 - as already mentioned by Thomas, removing a package out of the
   package lists, doesn't result in a deletion on the machines.
       
The first one is trivial, while the second one would need more
work (and thought). For instance, consider the typical case, hat apt has
installed additional packages due to a dependency of the orginal
package. In this case, only removing the original package may not help
alot. Think for example of the task-* packages...
        
Nevertheless, I think it would be great, if fai comes with an update
script for regular use, even if the deinstallation of packages doesn't
work properly.
	 
Greetings,
	  
          Joerg

-- 
 Joerg Lehmann                  |
 Institut fuer Physik           | email: Joerg.Lehmann at Physik.Uni-Augsburg.DE
 Universitaet Augsburg          | Phone: +49-821-598-3229
 D-86135 Augsburg               | Fax  : +49-821-598-3222                  
-------------- next part --------------
#!/bin/bash
# $Id: rcS_fai,v 1.28 2000/12/12 15:25:35 lange Exp $
#*********************************************************************
#
# rcS_fai -- main FAI installation script executed after booting
#
# This script is part of FAI (Fully Automatic Installation)
# (c) 1999, 2000 by Thomas Lange, lange at informatik.uni-koeln.de
# Universitaet zu Koeln
#
#*********************************************************************
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# A copy of the GNU General Public License is available as
# `/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
# or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html.  You
# can also obtain it by writing to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#*********************************************************************

# set -xv # for full debugging

# local variables
FAI_VERSION="FAI 1.4.2, december 12, 2000"

logdir=/var/log/fai
export fairuntmp=$logdir/$HOSTNAME/fairuntmp

rcslog=$fairuntmp/fairun.log
bootlog=$fairuntmp/bootpc.log
dhcplog=$fairuntmp/dhcp.log
shelllog=$fairuntmp/shell.log
cfenginelog=$fairuntmp/cfengine.log
perllog=$fairuntmp/perl.log
expectlog=$fairuntmp/expect.log
softwarelog=$fairuntmp/software.log
fai_classes=$fairuntmp/FAI_CLASSES

stamp=/tmp/FAI_INSTALLATION_IN_PROGRESS
faiconf=/:/sw/linux/.rw/install/fai/conf
globalconf=$faiconf/fai_config/global.conf

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#move_logfiles() {
#    tar -czf $logdir/localhost/install.fairun_old.tar.gz -C $logdir/localhost install
#}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
read_config() {

    # read global config for FAI
    if [ -r $globalconf ]; then
	[ "$verbose" ] && echo "Reading $globalconf"
	. $globalconf
    fi

    hostconf=$faiconf/fai_config/$HOSTNAME
    if [ -r $hostconf ]; then
	[ "$verbose" ] && echo "Reading $hostconf"
	. $hostconf
    fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
define_variables() {

    # after all classes are defined, define variables
    # source files, which can set variables
    cd $faiconf/class
    for class in $classes ; do
	if [ -f $class.source ]; then
	    [ "$verbose" ] && echo "Executing $class.source"
	    [ "$debug" ] && set -v
	    . $class.source </dev/null
	    [ "$debug" ] && set +v
	fi
    done
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
define_classes() {

    classes="FAIRUN"	# zur Unterscheidung von fairun und rcS_fai

    cd $faiconf/class
    echo "Now defining classes"

    # alphabetical sort is important
    for f in `ls S[0-9]*.{sh,pl}` ; do
	if [ -x $f -a -f $f ]; then
	[ "$verbose" ] && echo "Executing $f"

	case $f in
	    *.pl) newclasses=`perl $f </dev/null` ;;
	    *.sh) newclasses=`sh $f </dev/null | grep -v '^#'` ;;
	esac
	[ "$debug" ] && echo "newclasses= $newclasses"
	classes="$classes $newclasses"
	fi
    done

    for class in $classes ; do
	echo $class >> $fai_classes
    done

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

    set -a # now export all variables

    mkdir -p $fairuntmp

    . $faiconf/bin/subroutines
    # ulimit -c 90000
    FAI_ARCH=`dpkg --print-installation-architecture`
    # location of master files for cfengine
    FAI_FILES=$faiconf/files
    # local disks are mounted on this directory
    FAI_ROOT=/.
    diskvar=$logdir/localhost/install/disk_var.sh
    moduleslog=$fairuntmp/modules.log

    # for cfengine
    chroot=/usr/sbin/chroot
    cf_prefix="cfengine:"
    files=$FAI_FILES
    target=$FAI_ROOT

    umask 022
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin:
    DEBIAN_FRONTEND=Noninteractive

    get_dhcp_info
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fai_setup() {

    read_config # read config from mounted $FAI_LOCATION

    DNSDOMAIN=$DOMAIN     # cfengine 1.5.3 can't use $DOMAIN
    ststd=$FAI_ROOT/sbin/start-stop-daemon

#    for flag in $FAI_FLAGS; do
#	[ "$verbose" ] && echo "FAI_FLAGS: $flag=1"
#	eval "$flag=1"
#    done
    verbose=1

    devnull=/dev/null
    [ "$debug" ] && devnull=/dev/console
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fai_sysinfo() {

    # show some system information and save it on the server
    ( # execute in a subshell to get all output
	if [ -x /usr/local/bin/fai_sysinfo ]; then
	    /usr/local/bin/fai_sysinfo
	else
	    sfdisk -s
	    sfdisk -l
	    lspci
	    [ -f /proc/scsi/scsi ] && cat /proc/scsi/scsi
	    hdparm -iv /dev/hd[a-h]
	    echo -n "xserver for graphic card:"; xviddetect -q
	    #si -p -o shm
	fi
    ) > >( tee -a $rcslog )  2>&1
    define_classes
    define_variables
    load_keymap_consolechars
    save_dmesg
    save_log_remote
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fai_configure() {

# execute scripts; cfengine, shell, perl and expect scripts are known types
cd $faiconf/scripts

for class in $classes ; do
if [ -x $class -a -f $class ]; then
    filetype=`file $class`
    case $filetype in

	*"shell script"*)
	    echo "Executing shell: $class"
	    echo "=====   shell: $class   =====" >> $shelllog 2>&1
	    ./$class >> $shelllog 2>&1
	;;

	*"cfengine script"*)
	    echo "Executing cfengine: $class"
	    echo "=====   cfengine: $class   =====" >> $cfenginelog 2>&1
	    ./$class --no-lock -v -f $class -D${cfclass} >> $cfenginelog 2>&1
	;;

	*"perl script"*)
	    echo "Executing perl: $class"
	    echo "=====   perl: $class   =====" >> $perllog 2>&1
	    ./$class >> $perllog 2>&1
	;;

	*"expect script"*)
	    echo "Executing expect: $class"
	    echo "=====   expect: $class   =====" >> $expectlog 2>&1
	    ./$class >> $expectlog 2>&1
	;;


	*) echo "File $class has unsupported type $filetype." ;;
    esac
fi
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
prepare_apt() {

    chroot $FAI_ROOT apt-get update
    chroot $FAI_ROOT apt-get check
    [ $? -ne 0 ] && chroot $FAI_ROOT apt-get -f -y install </dev/null 
    chroot $FAI_ROOT dpkg -C
    [ $? -ne 0 ] && nice yes ''|  chroot $FAI_ROOT dpkg --configure -a 
    chroot $FAI_ROOT apt-get -f -y remove pcmcia-cs
    chroot $FAI_ROOT apt-get -f -y upgrade </dev/null

}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fai_update() {

    > $stamp

    define_classes > >( tee -a $rcslog )  2>&1
    define_variables > >( tee -a $rcslog )  2>&1
    
    ( # execute in a subshell to get all output

#     if [ -s $diskvar ]; then
# 	. $diskvar
#     else
# 	cat $fairunlog/format.log
# 	die "Error: $diskvar not found."
#     fi

    echo "Installing software may take a while"
    if [ "$debug" ]; then
	prepare_apt | tee -a $fairuntmp/prepare-apt.log 2>&1
    else
	prepare_apt  > $fairuntmp/prepare-apt.log 2>&1
    fi

    if [ "$debug" ]; then
	install_packages | tee -a $softwarelog
    elif [ "$verbose" ]; then
	nice yes '' | install_packages | tee -a $softwarelog
    else
	nice yes '' | install_packages >> $softwarelog 2>&1
    fi

    fai_configure

    case "$UTC" in
       no|"") hwopt="--localtime" ;;
       yes)   hwopt="--utc"       ;;
    esac
    chroot $FAI_ROOT hwclock $hwopt --systohc
    date
    echo -e "FAI finished.\a"

    rm -f $stamp
    # a second time, because loading modules can create new messages
    ) > >( tee -a $rcslog )  2>&1

    find $fairuntmp -maxdepth 1 -size 0 -exec rm {} \;
    mv $fairuntmp $logdir/$HOSTNAME/fairun.${FAI_ACTION}-`date +%m%d%H%M`

    if [ -f $stamp ]; then
	echo "Error while executing commands in subshell."
	echo "$stamp was not removed."
	die "Please look at the log files in $fairuntmp for errors."
    fi

    wait_for_jobs
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Main routine

#move_logfiles

# callarg=$1

fai_init
fai_setup  > >( tee -a $rcslog ) 2>&1
fai_update

# tempor?re Logfiles l?schen
rm 2>/dev/null $rcslog $bootlog $dhcplog $shelllog $cfenginelog $perllog $expectlog $softwarelog $fai_classes


More information about the linux-fai mailing list