#!/bin/bash
# $Id: fai 3027 2005-11-10 22:37:16Z lange $
#*********************************************************************
#
# fai -- main installation script executed after booting
#
# This script is part of FAI (Fully Automatic Installation)
# (c) 1999-2005 by Thomas Lange, lange@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

export PATH=/usr/local/sbin:/usr/local/bin:/usr/lib/fai:/bin:/sbin:/usr/bin:/usr/sbin:
# some variables
export FAI_VERSION=FAIVERSIONSTRING
rundir=/var/run/fai
stamp=$rundir/FAI_INSTALLATION_IN_PROGRESS
romountopt="-o async,noatime,nolock,ro,actimeo=1800"
fstab=fstab  # Solaris uses vfstab

# the type of operating system (linux, sunos)
oclass=$(uname -s | tr /a-z/ /A-Z/)
# $classes is now set so we can call hooks before fai-class defines the classes
classes="DEFAULT $oclass $HOSTNAME LAST"
faimond=0
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
prcopyleft() {

    cat <<-EOF
             -----------------------------------------------------
               Fully Automatic Installation for $osname
               $FAI_VERSION    Copyright (c) 1999-2005

               Thomas Lange      <lange@informatik.uni-koeln.de>
             -----------------------------------------------------
EOF
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fai_init() {

    local sub osname
    set -a # now export all variables

    umask 022
    # read fai.conf
    # linux dir
    [ -f /etc/fai/fai.conf ] && . /etc/fai/fai.conf
    # solaris dir
    [ -f /tmp/install_config/fai/fai.conf ] && . /tmp/install_config/fai/fai.conf

    if [ -f /boot/RUNNING_FROM_FAICD ]; then   # we are booting from fai cd
	umount /initrd
	romountopt=
	FAI_DEBMIRROR="--bind /media/mirror"
	MNTPOINT=/media/mirror
	FAI_LOCATION=
    fi

    # some variables from are not needed any more
    unset NFSROOT FAI_CONFIGDIR installserver

    # read subroutine definitions
    sub=/usr/share/fai/subroutines
    [ -f $sub ] && . $sub
    [ -f $sub-$OS_TYPE ] && . $sub-$OS_TYPE

    [ -f "$stamp" ] && {
       echo "$0 already running, aborting"
       exit 1
    }

    # HG: are we called as an init substitute ?
    DO_INIT_TASKS=0
    [ "$0" = "/etc/init.d/rcS" ] && DO_INIT_TASKS=1
    [ $DO_INIT_TASKS -eq 1 ] && renewclass=1 # always renew class list when installing

    # color logo only if initial install
    COLOR_FAI_LOGO=$DO_INIT_TASKS

    DEBIAN_FRONTEND=noninteractive
    # local disks are mounted to $FAI_ROOT
    if [ -z "$FAI_ROOT" ] ; then
      [ $DO_INIT_TASKS -eq 1 ] && FAI_ROOT=/tmp/target || FAI_ROOT=/
    fi
    # executed command in the environment of the new system
    ROOTCMD="chroot $FAI_ROOT"
    # no chroot needed
    [ "$FAI_ROOT" = '/' ] && ROOTCMD=

    # Solaris has already a writable /tmp directory
    [ "$oclass" = LINUX -a $DO_INIT_TASKS -eq 1 ] && create_ramdisk
    unset oclass

    # directory where temporary log files are stored
    # set default value if nothing is set in fai.conf
    if [ -z "$LOGDIR" -a $DO_INIT_TASKS -eq 1 ]; then
	LOGDIR=/tmp/fai
	mkdir -p $LOGDIR
    fi
    [ $DO_INIT_TASKS -eq 0 ] && LOGDIR=$(mktemp -t -d fai.XXXXXX)
    ln -s $LOGDIR $rundir/current_log

    # several log files
    diskvar=$LOGDIR/disk_var.sh
    moduleslog=$LOGDIR/modules.log
    rcslog=$LOGDIR/fai.log

    # variables for cfengine
    files=$FAI/files
    target=$FAI_ROOT

    if [ $DO_INIT_TASKS -eq 1 ]; then
        trap 'echo "Now rebooting";faireboot' INT QUIT ;
    else
        trap "echo 'Aborted';rm -f $stamp" INT QUIT ;
    fi

    # if HOST was specified on the commandline, set hostname to it
    eval_cmdline
    if [ -n "$HOST" ]; then
	HOSTNAME=$HOST
	hostname $HOST
	echo "Hostname set to $HOST" | tee -a $rcslog
	sleep 3
    fi
    export HOSTNAME

    if [ X$OS_TYPE = Xlinux ]; then
	osname='Debian GNU/Linux'
	if [ $DO_INIT_TASKS -eq 1 ]; then
	    grep -q '[[:space:]]sysfs' /proc/filesystems && mount -t sysfs sysfs /sys
	    ifup lo
	    [ -x /sbin/portmap ] && /sbin/portmap
	    mount -t devpts devpts /dev/pts
	    # add other options for nfs mount of /dev/root to root-path in dhcpd.conf
	    mount -o remount,noatime,ro /dev/root /
	    cat /proc/kmsg >/dev/tty4 &
	fi
    fi
    if [ X$OS_TYPE = Xsunos ]; then
	osname='Sun Solaris'
    fi

    # set red color, but not on some archs
    [ -e /.nocolorlogo ] && COLOR_FAI_LOGO=0
    case $HOSTTYPE in
	sparc*|powerpc*) COLOR_FAI_LOGO=0 ;;
    esac

    [ $COLOR_FAI_LOGO -eq 1 ] && echo -ne "\ec\e[1;31m"

    prcopyleft | tee -a $rcslog

    if [ $COLOR_FAI_LOGO -eq 1 ]; then
	echo -ne "\e[7;0r"
	echo -ne "\e[9B\e[1;m"
    fi
    save_dmesg
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
usage() {
    cat <<-EOF
	fai $FAI_VERSION. Copyright (C) 1999-2005 Thomas Lange
	Usage: $0 [options] [action]
       
	Options:
	   -v|--verbose      display more information during the update
	   -h|--help         display this help message
	   -N|--new          renew list of classes
EOF
    exit 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fstart() {

    # these tasks can define variables, that are needed later
    task confdir
    task setup
    task defclass
    set_disk_info
    task defvar
    [ $DO_INIT_TASKS -eq 1 ] && load_keymap_consolechars
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Main routine

export renewclass=0
# Parse commandline options
TEMP=$(getopt -o Nhv --long new,help,verbose -n "$0" -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
    case "$1" in
        -h|--help)
	    shift
	    usage
            ;;
	-v|--verbose)
	    shift
	    verbose=1
	    ;;
	-N|--new)
	    shift
	    renewclass=1
	    ;;
        --) 
            shift
            break
            ;;
         *)
            echo "$0: command line parsing error ! $@"
            exit 1
            ;;
    esac
done

fai_init

lpipe=$LOGDIR/logfifo
mkfifo $lpipe
tee -a $rcslog < $lpipe &
# in bash &> redirect stdout and stderr to file
fstart &> $lpipe
rm $lpipe
unset lpipe
sleep 1 # wait for tee to complete. One second should be ok

# old code
# {
# # a bash group command with { does not work on sparc
# task confdir
# task setup
# task defclass
# task defvar
# load_keymap_consolechars
# set_disk_info
# } > >( tee -a $rcslog )  2>&1

# override FAI_ACTION if a command line argument is given
[ "$1" ] && FAI_ACTION=$1

task action 2>&1 | tee -a $rcslog

# not quiet happy with it
[ "$FAI_CVSROOT" ] && rm -rf $FAI
rm -rf $LOGDIR

[ -L "$rundir/current_log" ] && rm -f "$rundir/current_log"
[ -L "$rundir/current_config" ] && rm -f "$rundir/current_config"

echo "End of $0"
