#!/bin/bash # $Id$ #********************************************************************* # # fai -- main installation script executed after booting # # This script is part of FAI (Fully Automatic Installation) # (c) 1999-2007 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 stamp=/var/run/fai/FAI_INSTALLATION_IN_PROGRESS romountopt="-o async,noatime,nolock,ro,actimeo=1800" export faimond=0 export renewclass=0 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - fai_init() { set -a # now export all variables umask 022 if [ ! -d "$FAI_ETC_DIR" ]; then echo "$FAI_ETC_DIR is not a directory" exit 6 fi [ -f $FAI_ETC_DIR/fai.conf ] && . $FAI_ETC_DIR/fai.conf if [ -f /etc/RUNNING_FROM_FAICD ]; then # we are booting from fai cd umount /initrd romountopt= FAI_DEBMIRROR="--bind /media/mirror" MNTPOINT=/media/mirror FAI_CONFIG_SRC="file://$FAI" # on a fai-cd the config space is already available fi # some variables from are not needed any more #unset FAI_CONFIGDIR # read subroutine definitions local sub=/usr/lib/fai/subroutines [ -f $sub ] && . $sub [ -f $sub-linux ] && . $sub-linux [ -f "$stamp" ] && { echo "$0 already running, aborting" exit 1 } 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= target=$FAI_ROOT if [ X$action = Xdirinstall -a -n "$newhostname" ]; then HOSTNAME=$newhostname HOST=$newhostname unset newhostname echo "Hostname set to $HOST" | tee -a $LOGDIR/fai.log fi 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 [ $do_init_tasks -eq 1 ]; then eval_cmdline # if HOST was specified on the commandline, set hostname to it if [ -n "$HOST" ]; then HOSTNAME=$HOST hostname $HOST echo "Hostname set to $HOST" | tee -a $LOGDIR/fai.log fi mount -t sysfs sysfs /sys # we really need to start udev [ -x /etc/init.d/udev ] && /etc/init.d/udev start [ -d /var/run/network ] || mkdir /var/run/network [ -d /dev/shm/network ] || mkdir /dev/shm/network # when using initrd kernels ifup lo [ -x /sbin/portmap ] && /sbin/portmap mount -t devpts devpts /dev/pts cat /proc/kmsg >/dev/tty4 & fi # since HOSTNAME may change define classes now, so we can call hooks before fai-class is called [ -z "$classes" ] && classes="DEFAULT $(uname -s | tr a-z A-Z) $HOSTNAME LAST" prcopyleft save_dmesg } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - usage() { cat <<-EOF fai $FAI_VERSION. Copyright (C) 1999-2006 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 -c|--class comma separated list of classes -C|--cfdir CFDIR Use CFDIR for reading the config files EOF exit 0 } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - fstart() { # these tasks can define variables, that are needed later [ -n "$etc_message" ] && echo "" echo "$etc_message" [ $do_init_tasks -eq 1 ] || echo "Using configuration files from $FAI_ETC_DIR" unset etc_message task confdir task setup task defclass unset cmdlineclasses renewclass [ $do_init_tasks -eq 1 ] && set_disk_info task defvar [ $do_init_tasks -eq 1 ] && load_keymap_consolechars } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Main routine # Parse commandline options TEMP=$(getopt -o u:Nhvc:C: --long hostname:,new,help,verbose,class:,cfdir: -n "$0" -- "$@") if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" unset TEMP while true ; do case "$1" in -h|--help) shift usage ;; -v|--verbose) shift export verbose=1 ;; -N|--new) shift renewclass=1 ;; -C|--cfdir) shift cfdir=$1 shift ;; -c|--class) if [ $renewclass -eq 1 ]; then echo "You can't use -c|--classes and -N|--new at the same time." exit 9 fi shift export cmdlineclasses=$1 shift cmdlineclasses=${cmdlineclasses//,/ } ;; -u|--hostname) shift export newhostname=$1 shift ;; --) shift break ;; *) echo "$0: command line parsing error ! $@" exit 1 ;; esac done # use FAI_ETC_DIR from environment variable if [ -n "$FAI_ETC_DIR" -a -z "$cfdir" ]; then # print this message later so it gets into the log files etc_message="Using environment variable \$FAI_ETC_DIR." fi [ -n "$cfdir" ] && FAI_ETC_DIR=$cfdir unset cfdir : ${FAI_ETC_DIR:=/etc/fai} FAI_ETC_DIR=$(readlink -f $FAI_ETC_DIR) # canonicalize path export FAI_ETC_DIR # override FAI_ACTION later if a command line argument is given [ "$1" ] && action=$1 [ "$2" ] && export FAI_ROOT=$2 # only used for dirinstall if [ X$action = Xdirinstall ]; then if [ -z "$FAI_ROOT" ]; then echo "Please specify a target directory. Aborted" exit 3 fi export NFSROOT=$(source $FAI_ETC_DIR/make-fai-nfsroot.conf; echo $NFSROOT) fi if [ $(id -u) != "0" ]; then echo "Run this program as root." exit 1 fi # exit if we do not run from nfsroot and no parameter is given if [ ! -f /.THIS_IS_THE_FAI_NFSROOT -a "X$1" = "X" ]; then echo "Please give more parameters if not run from the nfsroot." exit 2 fi # are we called as an init substitute ? export do_init_tasks=0 [ "$0" = "/etc/init.d/rcS" ] && do_init_tasks=1 if [ $do_init_tasks -eq 1 ]; then renewclass=1 # always renew class list when installing fi export start_seconds=$(cut -d . -f 1 /proc/uptime) [ -d /var/run/fai ] || mkdir /var/run/fai export LOGDIR=/var/log/fai/current [ -d $LOGDIR ] && rm -rf $LOGDIR mkdir -p $LOGDIR # for compability, can be removed later if [ $do_init_tasks -eq 1 ]; then mkdir /tmp/fai mount --bind $LOGDIR /tmp/fai fi fai_init if [ X$action = Xdirinstall ]; then skiptask confdir export FAI=$FAI_CONFIGDIR set -a clean_exit() { rm -f $stamp [ -z "$FAI_ROOT" ] && return [ -d $FAI_ROOT/proc/self ] && umount $FAI_ROOT/proc $FAI_ROOT/sys [ -f /etc/init.d/udev ] && umount $FAI_ROOT/dev } trap 'clean_exit' EXIT fi mkfifo $LOGDIR/logfifo tee -a $LOGDIR/fai.log < $LOGDIR/logfifo & # in bash &> redirect stdout and stderr to file fstart &> $LOGDIR/logfifo rm $LOGDIR/logfifo 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 $LOGDIR/fai.log ) 2>&1 [ "$action" ] && export FAI_ACTION=$action unset action task action 2>&1 | tee -a $LOGDIR/fai.log [ -L "/var/run/fai/current_config" ] && rm -f "/var/run/fai/current_config" echo "End of $0"