Progressbar for extracting Basefiles
Karsten Nordsiek
kno at tuxedocomputers.com
Wed Jan 18 15:45:11 CET 2023
Please find included the both files I have changed.
Hint: you need to install pv in the nfsroot
Am 18.01.23 um 15:19 schrieb Karsten Nordsiek:
> Yes that's working.
>
> I have added the -f Option
> Now it works as fine as it should
>
> thx for the hint.
>
> Regards
>
>
> Karsten Nordsiek
>
>
> Am 18.01.23 um 14:34 sch
> rieb Thomas Lange:
>>>>>>> On Wed, 18 Jan 2023 12:28:26 +0100, Karsten Nordsiek
>>>>>>> <kno at tuxedocomputers.com> said:
>> > -1 Use only first tar file matching
>> class name.
>> > -c class[class] Define classes (space separated).
>> Hmmm, it's hard to see what you have changed. A diff or git diff would
>> be much better to understand.
>>
>> My first guess is to add -f to the pv call.
>>
>> -f, --force output even if standard error is not a
>> terminal
>>
>> Inside FAI we redirect the output to a pipe which also does tee into a
>> file. Or you may try to force the output (does pv use stderr?) to
>> /dev/ttyN.
>>
-------------- next part --------------
#! /bin/bash
#*********************************************************************
#
# ftar -- extract tar files using FAI classes
#
# This script is part of FAI (Fully Automatic Installation)
# Copyright (C) 2001-2017 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#*********************************************************************
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
die() {
local e=$1 # first parameter is the exit code
shift
echo "ftar: $@" >&2 # print error message
exit $e
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
extract() {
local file=$1
local catname=$2
if [ $deletefiles -eq 1 ] ; then
cd $target/$dir && rm -f -- .* * 2>/dev/null
deletefiles=0
fi
if [ $removedir -eq 1 ]; then
cd $target/$dir || die 4 "ERROR: cd to $target/$dir failed. Aborting."
[ $PWD = "/" ] && die 3 "WARNING: Will not do recursive removal of directory /"
rm -rf -- .* * 2>/dev/null
removedir=0
fi
if [ $progress -eq 1 ]; then
echo "ftar: extracting $file to $target/$dir" | tr -s '/'
$catname $file | pv -f -s $(du -sb $file | awk '{print $1}') | tar $xattrs --numeric-owner -C $target/$dir $vflag -xf -
else
echo "ftar: extracting $file to $target/$dir" | tr -s '/'
$catname $file | tar $xattrs --numeric-owner -C $target/$dir $vflag -xf -
tardone=1
# if option -1 is set, only one class will be used
[ $single -eq 1 ] && exit 0
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
usage() {
cat <<EOF
ftar, extract tar files using classes.
Copyright (C) 2001-2017 by Thomas Lange
Usage: ftar [OPTION] ... SOURCE
-1 Use only first tar file matching class name.
-c class[class] Define classes (space separated).
-d Delete all files in target before extracting.
-D Create debug output.
-h Show summary of options.
-p Show progress indicator
-r Recursively remove files in target before extracting.
-s source_dir Look for source files relative to source_dir.
-t target_dir Extract files relativ to target_dir.
-v Be verbose. Not yet used.
EOF
exit 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
source=$FAI/files
target=$FAI_ROOT
deletefiles=0
removedir=0
tardone=0
single=0
ignore=0
progress=0
if [ -n "$classes" ]; then
[ -f $LOGDIR/FAI_CLASSES ] && classes=$(< $LOGDIR/FAI_CLASSES)
fi
echo $@
while getopts 1hDdrvs:t:c:i:p opt ; do
case "$opt" in
d) deletefiles=1 ;;
D) debug=1 ;;
i) ignore=1 ;;
r) removedir=1 ;;
# v) verbose=1 ;;
1) single=1 ;;
s) source=$OPTARG ;;
t) target=$OPTARG ;;
c) classes=$OPTARG ;;
p) progress=1 ;;
h) usage ;;
esac
done
shift $((OPTIND - 1))
[ "$1" ] || usage
# detect target fstype
targetfstype=$(awk -vt="$target" '{if($2==t){print $3}}' /proc/mounts)
if [ "$targetfstype" != "nfs" ]; then
xattrs="--xattrs --xattrs-include=*.* --selinux --acl"
else
xattrs=
fi
# last class has highest priority
# reverse order of classes
for class in $classes; do
revclasses="$class $revclasses"
done
[ "$debug" ] && vflag="-v"
[ "$debug" ] && echo "ftar: classes : $revclasses"
[ -z "$source" ] && die 1 "Source directory undefined."
[ -z "$target" ] && die 1 "Target directory undefined."
# currently only one directory is used
dir=$1
fpath=$source/$dir
[ -d $fpath ] || die 1 "No directory $fpath"
for c in $revclasses ; do
# what if a directory exists which is equal to the hostname or a classname?
[ -f $fpath/$c.tgz ] && extract $fpath/$c.tgz zcat
[ -f $fpath/$c.tar ] && extract $fpath/$c.tar cat
[ -f $fpath/$c.tar.gz ] && extract $fpath/$c.tar.gz zcat
[ -f $fpath/$c.tar.bz2 ] && extract $fpath/$c.tar.bz2 bzcat
[ -f $fpath/$c.tar.xz ] && extract $fpath/$c.tar.xz xzcat
[ -f $fpath/$c.txz ] && extract $fpath/$c.txz xzcat
done
if [ $tardone -eq 0 ]; then
if [ $ignore -eq 1 ]; then
echo "ftar: No matching class found in $fpath"
exit 0
else
die 1 "No matching class found in $fpath"
fi
fi
exit 0
-------------- next part --------------
#! /bin/bash
#*********************************************************************
#
# subroutines -- useful subroutines for FAI
#
# This script is part of FAI (Fully Automatic Installation)
# (c) 2000-2021 by Thomas Lange, lange at informatik.uni-koeln.de
# Universitaet zu Koeln
# (c) 2001-2005 by Henning Glawe, glaweh at physik.fu-berlin.de
# Freie Universitaet Berlin
#
#*********************************************************************
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#*********************************************************************
# source this file, then you have these function available in the shell
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
die() {
# echo comment and exit installation
[ -f $LOGDIR/skip.savelog ] || call_hook savelog
[ -f $LOGDIR/skip.savelog ] || task_savelog
echo "$@"
if [ $do_init_tasks -eq 1 ] ; then
exec bash -i
else
exit 99
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
defnop() {
# define given list of subroutine names as dummy function;
# this will fake unknown commands
local name
for name in "$@";do
eval "$name () { :;}"
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: none
# Required-Var: $classes
# Short-Description: test if one or multiple classes are defined
### END SUBROUTINE INFO
ifclass() {
if [ $# -eq 1 ]; then
_ifclass $1
return $?
fi
case $1 in
-a) shift ; _ifclass_and $* ; return $? ;;
-o) shift ; _ifclass_or $* ; return $? ;;
esac
}
_ifclass() {
# check one single class
[ "${debug:-}" ] && echo "Test if class $1 is in ${classes:-}" >&2
# test if a class is defined
local ret
if [[ "${classes:-}" =~ (^|[[:space:]]+)$1($|[[:space:]]+) ]]; then
ret=0
else
ret=1
fi
[ "${debug:-}" ] && echo "ifclass returns $ret" >&2
return $ret
}
_ifclass_and() {
# check if all classes are defined (logical AND)
local cl
for cl in $*; do
ifclass $cl || return 1
done
return 0
}
_ifclass_or() {
# check if one of the classes is defined (logical OR)
local cl
for cl in $*; do
ifclass $cl && return 0
done
return 1
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
rwmount() {
# remount partition read/write, for interactive use only
mount -o rw,remount $1
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
save_dmesg() {
[ $do_init_tasks -eq 0 ] && return
if [ -x /usr/sbin/logtail ] ; then
logtail -f /var/log/kern.log -o /var/lib/fai/kern.log.offset >> $LOGDIR/dmesg.log
else
dmesg > $LOGDIR/dmesg.log
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
umount_csspace() {
# umount config space if accessed via nfs
if [[ $FAI_CONFIG_SRC =~ ^nfs:// ]]; then
mountpoint -q $FAI && umount $FAI
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
umount_target() {
if [ "$target" != '/' ]; then
# do not umount during softupdate
umount $FAI_ROOT/proc $FAI_ROOT/sys/firmware/efi/efivars $FAI_ROOT/sys $FAI_ROOT/dev/pts $FAI_ROOT/dev 2>/dev/null
for dir in $(mount | grep $target | grep -E -v "media/mirror|tmpfs"| awk '{print $3}' | sort -r); do
mountpoint -q $dir && umount $dir
done
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cleanup_devicemapper() {
local vgroup v
# remove device mapper devices
grep -q 'Executing: vgcreate' $LOGDIR/format.log 2>/dev/null
if [ $? -eq 0 ]; then
# write which vg should be removed, PPID is the fai-diskimage process
> /var/run/fai/vgremove.$PPID
vgroup=$(awk '/Executing: vgcreate/ {print $3}' $LOGDIR/format.log)
for v in $vgroup; do
vgchange -an $v
echo vgremove -f $v >> /var/run/fai/vgremove.$PPID
done
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mk_zerofree_list() {
# make a list of devices for zerofree which have an ext2/3/4 file system
local source fstype mpoint v
if [ X$verbose = X1 ]; then
v=-v
fi
while read -r source fstype mpoint ; do
# skip non ext2/3/4 file systems
case $fstype in
ext*) : ;;
*) continue ;;
esac
if [[ $mpoint =~ $target ]]; then
echo "zerofree $v $source" >> /var/run/fai/zerofree.$PPID
fi
done < <(df --output=source,fstype,target)
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
stop_fai_installation() {
# this subroutine should directly stop the installation process
sendmon "TASKEND $taskname $task_error"
echo "Error in task $taskname. Code: $task_error" >&2
echo "Traceback: $task_error_func" >&2
die "FATAL ERROR. Installation stopped."
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: $task_error
# Required-Var: $1 $2 $task_error
# Short-Description: save the maximum error code,
# Short-Description: $1 is the error that will be saved unless $2 is zero
# Short-Description: if $3 is set to 1 only $task_error is set but the
# Short-Description: installation is not stopped
### END SUBROUTINE INFO
task_error() {
local current
[ X$2 = X0 ] && return
task_error_func=${FUNCNAME[*]}
# save max error for current task
task_local_error=$1
current=$(< $LOGDIR/task_local_error)
if [ $task_local_error -gt $current ]; then
echo $task_local_error > $LOGDIR/task_local_error
fi
# save global max task error
task_error=$(< $LOGDIR/task_error)
if [ $task_local_error -gt $task_error ]; then
task_error=$task_local_error
echo $task_local_error > $LOGDIR/task_error
fi
if [ X$3 = X1 ]; then
:
else
[ $task_error -gt $STOP_ON_ERROR ] && stop_fai_installation
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: $task_error
# Required-Var: $LOGDIR
# Short-Description: call a certain task
### END SUBROUTINE INFO
declare -A taskduration
export duration=0
task() {
# hooks are called before a task is called
# if a task is skipped, also its hooks are skipped
# a hook can set the flag, so the accociated task is skipped
local taskname=$1
shift
local task_local_error=0 # the error code set by every task
echo 0 > $LOGDIR/task_local_error
[ -f $LOGDIR/skip.$taskname ] || call_hook $taskname "$@"
if [ -f $LOGDIR/skip.$taskname ]; then
# skip task
rm $LOGDIR/skip.$taskname # TODO: remove skip files at the very end
[ X$verbose = X1 ] && echo "Skipping task_$taskname"
sendmon "TASKSKIP $taskname"
else
echo "Calling task_$taskname"
sendmon "TASKBEGIN $taskname"
task_error_func=''
taskduration[$taskname]=$SECONDS
task_$taskname "$@"
[ $duration -eq 1 ] && echo "Duration of task $taskname: " $((SECONDS-${taskduration[$taskname]}))"s"
task_local_error=$(< $LOGDIR/task_local_error)
sendmon "TASKEND $taskname $task_local_error"
if [ "$task_local_error" -ne 0 ] ; then
echo "Exit code task_$taskname: $task_local_error" >&2
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var:
# Required-Var: $classes $debug
# Short-Description: call a hook, hook.sh can define additional variables
### END SUBROUTINE INFO
call_hook() {
local hook=$1
shift
local cl dflag hfile
[ "$debug" ] && dflag="-d"
for cl in $classes; do
hfile=$FAI/hooks/$hook.$cl
if [ -f $hfile -a ! -x $hfile ]; then
echo "WARNING: Skipping $hfile because it's not executable." >&2
continue
fi
if [ -f $hfile.sh -a ! -x $hfile.sh ]; then
echo "WARNING: Skipping $hfile.sh because it's not executable." >&2
continue
fi
if [ -f $hfile.source ]; then
echo "WARNING: The suffix .source is deprecated. Use .sh instead." >&2
# continue
fi
if [ -x $hfile.sh ]; then
echo "Source hook: $hook.$cl.sh"
sendmon "HOOK $hook.$cl.sh"
# source this hook
. $hfile.sh $dflag "$@"
check_status $hook.$cl.sh $?
fi
if [ -x $hfile ]; then
echo "Calling hook: $hook.$cl"
sendmon "HOOK $hook.$cl"
# execute the hook
$hfile $dflag "$@"
check_status $hook.$cl $?
fi
# deprecated
if [ -x $hfile.source ]; then
echo "Source hook: $hook.$cl.source"
sendmon "HOOK $hook.$cl.source"
# source this hook
. $hfile.source $dflag "$@"
check_status $hook.$cl.source $?
fi
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
skiptask() {
# mark all given tasks, so they will be skipped
local task
for task in "$@"; do
echo > $LOGDIR/skip.$task # create file with size != 0
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
define_fai_flags() {
local flag
# FAI_FLAGS are comma separated, define all flags
FAI_FLAGS=${FAI_FLAGS//,/ }
echo "FAI_FLAGS: $FAI_FLAGS"
for flag in $FAI_FLAGS; do
# define this flag as 1
eval "flag_$flag=1"
done
[ "$flag_verbose" ] && verbose=1 # for backward compability
[ "$flag_debug" ] && debug=1 # for backward compability
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: $fai_rundate
# Requires-Var: $DOMAIN $do_init_tasks
# Suggests-Var: $flag_createvt $flag_sshd
# Short-Description: <task desc.>
### END SUBROUTINE INFO
task_setup() {
# source user specific subroutines
[ -f $FAI/hooks/subroutines ] && . $FAI/hooks/subroutines
define_fai_flags
# this may be moved to an external script
if [ $do_init_tasks -eq 1 ] ; then
# set the system time and date using rdate or/and ntpdate
[ "$TIMESRVS_1" ] && rdate $TIMESRVS_1
[ "$NTPSRVS_1" ] && ntpdate -b $NTPSRVS
[ "$flag_createvt" ] && {
# create two virtual terminals; acces via alt-F2 and alt-F3
echo "Press ctrl-c to interrupt FAI and to get a shell"
openvt -c2 /bin/bash ; openvt -c3 /bin/bash
echo "The log files are saved in /tmp/fai" > /dev/tty2
echo "The log files are saved in /tmp/fai" > /dev/tty3
trap 'echo "You can reboot with faireboot"; \
echo "The log files are saved in /tmp/fai"; \
cd /tmp/fai;bash' INT QUIT
}
# start secure shell daemon for remote access
if [ "$flag_sshd" -a -x /usr/sbin/sshd ]; then
pgrep -x sshd >/dev/null || /usr/sbin/sshd
fi
udevadm trigger
fi
unset flag_createvt flag_sshd
# now you have enough time to make changes to the config space
# only for debugging
if [ -n "$flag_wait" ]; then
echo "Sleeping. Now you may change the config space in $FAI."
echo "Continue after killall sleep."
sleep 50000
fi
# when did FAI start, using localtime
: ${fai_rundate:=$(date +'%Y%m%d_%H%M%S')}
if [ $do_init_tasks -eq 1 ]; then
echo "Starting FAI execution - $fai_rundate"
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: none
# Requires-Var: $FAI_ACTION
# Short-Description: call task depending on $FAI_ACTION
### END SUBROUTINE INFO
task_action() {
if [ -z "$FAI_ACTION" ]; then
echo "No action in \$FAI_ACTION defined."
sendmon "TASKERROR action 21"
task_faiend
exit
fi
echo "FAI_ACTION: $FAI_ACTION"
case $FAI_ACTION in
install)
if [ $target = "/" ]; then
echo "Cowardly refusing to run a FAI installation on a running system."
return
fi
echo Performing FAI installation. All data may be overwritten!
if [ $do_init_tasks -eq 1 -a X$flag_menu = X ] ; then
echo -ne "\a"; sleep 1
echo -ne "\a"; sleep 1
echo -e "\a"; sleep 5
fi
task install
task faiend
;;
dirinstall)
task dirinstall
task faiend
;;
softupdate)
task softupdate
task faiend
;;
sysinfo)
task sysinfo
task_faiend
die Now you have a shell.
;;
inventory)
task inventory
task_faiend
die Now you have a shell.
;;
*)
if [ -f $FAI/hooks/$FAI_ACTION ]; then
echo "Calling user defined action: $FAI_ACTION"
$FAI/hooks/$FAI_ACTION
task_faiend
else
echo "ERROR: User defined action $FAI/hooks/$FAI_ACTION not found." >&2
sendmon "TASKERROR action 22"
task_faiend
fi
;;
esac
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: $classes $cfclasses
# Requires-Var: $LOGDIR
# Suggests-Var: $renewclass
# Short-Description: define FAI classes and store them in several shell variables
### END SUBROUTINE INFO
task_defclass() {
if [ ! -d $FAI/class ]; then
sendmon "TASKERROR defclass 21"
echo "Subdirectory $FAI/class missing in config space. Following subdirectories are found:"
find $FAI -maxdepth 1 -type d -printf "%p\n"
die "Aborting."
fi
# new script for defining classes; variables imported: $LOGDIR, $verbose, $debug
if [ $renewclass -eq 1 ]; then
# reevaluate new list of classes
fai-class -T $FAI/class $LOGDIR/FAI_CLASSES
# check task error again
local lerr=$(< $LOGDIR/task_local_error)
task_error $lerr
classes=$(< $LOGDIR/FAI_CLASSES)
elif [ -n "$cmdlineclasses" ]; then
classes=$cmdlineclasses
elif [ ! -f /var/lib/fai/FAI_CLASSES ]; then
# use classes defined at installation time
die "Try to read classes from /var/lib/fai/FAI_CLASSES. Failed. Aborting."
else
classes=$(< /var/lib/fai/FAI_CLASSES)
fi
echo "List of all classes: " ${classes:-}
# define classes as: a.b.c.d for cfengine -D
# this doesn't work without echo
cfclasses=$(echo ${classes:-})
cfclasses=${cfclasses// /.}
[ "${debug:-}" ] && echo "cfclasses: $cfclasses"
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_defvar() {
local showvar=1 # TODO: new FAI_FLAG or always set when verbose is used
[ "$showvar" ] && set -x
. $1 </dev/null
[ "$showvar" ] && set +x
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_defvar() {
local svar=$LOGDIR/showvar.log
local odir=$(pwd)
cd $FAI/class
for class in ${classes:-} ; do
if [ -f $class.var -a -r $class.var ]; then
[ X$verbose = X1 ] && echo "Executing $class.var"
# show only lines with ++, we cannot use a pipe, since it would call
# _devfar in a subprocess. Then, variables are not defined
_defvar $class.var > $svar 2>&1
grep -P '^\+\+ \w+=' $svar| sed -e 's/\(.*PW\)=.*$/\1=XXXXXXXXXXXXX/'
rm $svar
fi
done
# /fai/class/* scripts or hooks can write variable definitions
# to additonal.var. now source these definitions
if [ -f $LOGDIR/additional.var -a -r $LOGDIR/additional.var ]; then
echo "Defining variables from additional.var"
_defvar $LOGDIR/additional.var > $svar 2>&1
grep ^++ $svar
rm $svar
fi
unset class svar
# now all variables are defined. Dump them to variables.log, so we can sources them if needed
set | perl -ne 'print if /^\w\w+=/ and not /^(EUID|PPID|SHELLOPTS|UID|rootpw|ROOTPW|USERPW|HOME|PWD|BASHOPTS)|\(/' > $LOGDIR/variables.log
# another approach is to use this. A slightly different format, but seems to be robust.
# declare -x > $LOGDIR/variables.log
cd $odir
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_mountdisks() {
[ ! -f $LOGDIR/fstab ] && die "No $LOGDIR/fstab created."
# mount swap space
if [ $do_init_tasks -eq 1 ]; then
local sd
for sd in $SWAPLIST; do
swapon -p1 $sd && [ X$verbose = X1 ] && echo "Enable swap device $sd"
done
fi
mount2dir $FAI_ROOT $LOGDIR/fstab
if [ "$?" -ne 0 ]; then
sendmon "TASKERROR mountdisks 885"
task_error 885
fi
if [ $do_init_tasks -eq 1 ] && ! mountpoint -q $target; then
echo "$target is not a mount point. Check your disk_config file."
sendmon "TASKERROR mountdisks 886"
task_error 886
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_configure() {
fai-do-scripts $FAI/scripts
task_error 420 $?
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_tests() {
if [ ! -d $FAI/tests ]; then
return
fi
fai-do-scripts $FAI/tests # always returns 0 atm
# check if any test failed
if [ -f $LOGDIR/test.log ]; then
if grep -q "FAILED with " $LOGDIR/test.log; then
sendmon "TASKERROR tests 312"
task_error 312
return 1
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_savelog() {
mkdir -p $FAI_ROOT/var/{lib,log}/fai
fai-savelog -l
[ -f $LOGDIR/FAI_CLASSES ] && cp -pu $LOGDIR/FAI_CLASSES $FAI_ROOT/var/lib/fai
[ -f $LOGDIR/disk_var.sh ] && cp -pu $LOGDIR/disk_var.sh $FAI_ROOT/var/lib/fai
fai-savelog -r
task_error 410 $?
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Description: Always called as last FAI task
### END SUBROUTINE INFO
task_faiend() {
local dir cdromdevice
: ${flag_reboot:=0}
: ${flag_halt:=0}
# reboot/halt without prompting if FAI_FLAG reboot or halt is set
# wait for keypress if neither flag reboot nor halt is set
if [ $do_init_tasks -eq 1 -a "$flag_reboot" -eq 0 -a "$flag_halt" -eq 0 ]; then
echo "Press <RETURN> to reboot (do not remove your removable medium yet)."
read
fi
sendmon "TASKEND faiend 0"
cd /
mk_zerofree_list
umount_target
cleanup_devicemapper
if [ $do_init_tasks -eq 0 ]; then
echo "Log files are saved in $LOGDIR"
return 0
fi
killall -q sshd systemd-udevd rsyslogd
umount $FAI_ROOT/proc $FAI_ROOT/sys/firmware/efi/efivars $FAI_ROOT/sys $FAI_ROOT/dev/pts 2>/dev/null
umount -arf 2>/dev/null
echo "Rebooting $HOSTNAME now"
sendmon "TASKEND reboot 0"
# reboot or halt?
if [ "$flag_halt" -gt "0" ]; then
exec halt -dfp
else
exec reboot -df
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_install() {
echo $$ > $stamp
save_dmesg
task partition
task mountdisks
task extrbase
task debconf
task repository
task updatebase
task instsoft
task configure
task tests
task finish
task chboot
rm -f $stamp
save_dmesg # save again, because new messages could be created
task savelog
if [ -f $stamp ]; then
echo "Error while executing commands in subshell." >&2
echo -n "$stamp was not removed. PID of running process: "
cat $stamp
sendmon "TASKERROR install 21"
die "Please look at the log files in $LOGDIR for errors." >&2
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_dirinstall() {
mkdir -p $FAI_ROOT
FAI_ROOT=$(cd $FAI_ROOT;pwd)
xstamp=${FAI_ROOT//\//=}
stamp=/var/run/fai/dirinstall-$xstamp
unset xstamp
clean_exit() {
rm -f $stamp
[ -z "$FAI_ROOT" ] && return
# sometimes mountpoint may be mounted twice, so try to umount them twice
mountpoint -q $FAI_ROOT/proc && umount $FAI_ROOT/proc
mountpoint -q $FAI_ROOT/sys && umount $FAI_ROOT/sys
mountpoint -q $FAI_ROOT/proc && umount $FAI_ROOT/proc
mountpoint -q $FAI_ROOT/sys && umount $FAI_ROOT/sys
mountpoint -q $FAI_ROOT/dev/pts && umount $FAI_ROOT/dev/pts
mountpoint -q $FAI_ROOT/run/udev && umount $FAI_ROOT/run/udev
# sometimes umount $FAI_ROOT/dev fails, because a process is
# still running in the background and accesses /dev
# this occured sometimes when using dirinst and a long package
# list if dhelp.postinst is starting an index process in the
# bg which did not finished until the installation was finished.
mountpoint -q $FAI_ROOT/dev && umount $FAI_ROOT/dev
mkramdisk -au 2>/dev/null
}
trap 'clean_exit' INT QUIT EXIT
[ -f "$stamp" ] && {
echo -n "fai dirinstall into directory $FAI_ROOT already running or was aborted before. PID: "
cat $stamp
echo "You may remove $stamp and try again."
exit 1
}
echo $$ > $stamp
echo "Installing into directory $FAI_ROOT"
task extrbase
[ -f $target/etc/fstab ] || touch $target/etc/fstab
task debconf
task repository
task updatebase
task instsoft
task configure
task tests
task finish
clean_exit
rm -f $stamp
unset LOGUSER # so logfile are not saved to remote
task savelog
if [ -f $stamp ]; then
echo "Error while executing commands in subshell." >&2
echo -n "$stamp was not removed. PID of running process: "
cat $stamp
sendmon "TASKERROR install 21"
die "Please look at the log files in $LOGDIR for errors." >&2
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_softupdate() {
echo Performing FAI system update. All data may be overwritten!
stamp=/var/run/fai/fai_softupdate_is_running
[ -f "$stamp" ] && die "Lock file $stamp found. Another fai softupdate is already running. Aborting."
echo $$ > $stamp
trap "rm -f $stamp" INT QUIT EXIT
# the following copy operation is required to make $LOGDIR a reliable source
# for disk_var.sh
# use the last disk_var during update if available
[ -f /var/lib/fai/disk_var.sh ] && cp -p /var/lib/fai/disk_var.sh $LOGDIR
save_dmesg
task debconf
task repository
task updatebase
task instsoft
task configure
task tests
task finish
rm -f $stamp
# save again, because new messages could be created
save_dmesg
task savelog
umount_csspace
if [ -f $stamp ]; then
echo "Error while executing commands in subshell." >&2
echo -n "$stamp was not removed. PID of running process: "
cat $stamp
sendmon "TASKERROR softupdate 21"
die "Please look at the log files in $LOGDIR for errors." >&2
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
catnc() {
# cat but no comment lines
grep -E -v "^#" $@
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: $disklist
# Requires-Var:
# Short-Description: create list of available disks
### END SUBROUTINE INFO
set_disk_info() {
# the variable holds a space separated list of devices
disklist=$(fai-disk-info | sort | tr '\n' ' ')
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eval_cmdline() {
# parse kernel parameters and define variables
local word cmdline
echo "Kernel currently running: "
uname -rsmo
cmdline="$(</proc/cmdline)"
echo "Kernel parameters: $cmdline"
for word in $cmdline; do
if echo "$word" | grep -E -q '^[a-zA-Z0-9_]+=' ; then
eval "export $word"
fi
done
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
read_fai_monitor_vars() {
# read variables which are received from the fai-monitor
if [ ! -s /run/initramfs/fai-variables ]; then
return
fi
eval $(grep FAI_CONFIG_SRC /run/initramfs/fai-variables)
eval $(grep FAI_FLAGS /run/initramfs/fai-variables)
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: $faimond $sendid $SERVER $monserver
# Requires-Var: $LOGDIR $FAI
# Suggests-Var: $monserver $FAI_SENDID $FAI_MONITOR_PORT
# Short-Description: <task desc.>
### END SUBROUTINE INFO
task_confdir() {
if [ $do_init_tasks -eq 1 ] ; then
read_fai_monitor_vars
eval_cmdline
get-boot-info
echo "Reading $LOGDIR/boot.log"
. $LOGDIR/boot.log
unset T170 T171 T172 ROOT_PATH BOOTFILE
printk=${printk:-6}
echo $printk > /proc/sys/kernel/printk
create_resolv_conf
if [ -x /usr/sbin/rsyslogd ]; then
/usr/sbin/rsyslogd
fi
fi
define_fai_flags
if [ -z "$SERVER" ]; then
# since SERVER is not set (by DHCP) we extract it from FAI_CONFIG_SRC
# extract server name from FAI_CONFIG_SRC and delete user@ from string
SERVER=$(expr match "$FAI_CONFIG_SRC" '.*://\([^/]*\)/.*' | sed -e 's/.*@//')
if [ -n "$SERVER" ]; then
echo "Setting SERVER=$SERVER. Value extracted from FAI_CONFIG_SRC."
else
SERVER=$(awk '{if($2 == "/live/image") print $1;}' /proc/mounts | cut -d ':' -f 1)
if [ -n "$SERVER" ]; then
echo "Setting SERVER=$SERVER. Value extracted from NFSROOT."
else
echo "NO SERVER FOUND FOR FAI_CONFIG_SRC"
fi
fi
fi
# check if monitor server is available
: ${monserver:=$SERVER}
: ${FAI_MONITOR_PORT:=4711}
if [ -z "$monserver" ]; then
echo "No monitor daemon defined."
faimond=0
else
faimond=1
if [ -n "$NIC1" ]; then
MAC=$(< /sys/class/net/$NIC1/address)
PXE="01-"${MAC//:/-}
fi
: ${FAI_SENDID:=host} # set default if undefined
case "$FAI_SENDID" in
host) sendid=$HOSTNAME ;;
mac) sendid=$MAC ;;
pxe) sendid=$PXE ;;
*) sendid=$FAI_SENDID ;;
esac
if sendmon check; then
echo "Monitoring to server $monserver enabled."
sendmon "TASKBEGIN confdir"
else
faimond=0
echo "Can't connect to monserver on $monserver port $FAI_MONITOR_PORT. Monitoring disabled."
fi
fi
local mdir=/lib/modules/$(uname -r)
if [ $do_init_tasks -eq 1 ] && [ ! -d $mdir ]; then
echo "ERROR: The running kernel does not match the kernel modules inside the nfsroot."
echo "ERROR: Kernel modules directory $mdir not available. Only found:"
ls -d /lib/modules/*
echo ""
task_error 790
fi
get-config-dir || {
echo "Problems accessing the config space."
die ""
}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: $BOOT_DEVICE $ROOT_PARTITION $BOOT_PARTITION $SWAPLIST
# Requires-Var: $LOGDIR $LOGDIR/disk_var.sh
# Short-Description: partition local hard disks
### END SUBROUTINE INFO
task_partition() {
if [ X$USE_SETUP_STORAGE = X1 ]; then
echo "WARNING: The variable USE_SETUP_STORAGE is not needed any more." >&2
echo "setup-storage is now the default tool for partitioning."
fi
[ ! -s $LOGDIR/disk_var.sh ] && setup-storage -X |& tee $LOGDIR/format.log
# if we've created device mapper devices, do cleanup on error
grep -q 'Executing: vgcreate' $LOGDIR/format.log 2>/dev/null
if [ $? -eq 0 ]; then
trap "umount_target;cleanup_devicemapper" QUIT EXIT
fi
# partitioning tool must create $LOGDIR/disk_var.sh file
if [ ! -s $LOGDIR/disk_var.sh ]; then
local conffile=$(grep "Using config file:" $LOGDIR/format.log | cut -d: -f2 )
if [ -n "$conffile" ]; then
echo ""
echo "This is your disk_config file:"
cat $conffile
fi
echo ""
task_error 710
sendmon "TASKERROR partition 21"
die "Partitioning tool did not create $LOGDIR/disk_var.sh file."
fi
# now define variable for root and boot partition and boot device
. $LOGDIR/disk_var.sh
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: none
# Requires-Var: $NFSROOT
# Suggests-Var:
# Short-Description: <task desc.>
### END SUBROUTINE INFO
call_debootstrap() {
local targetarch
local dversion=$(dpkg-query -Wf '${Version}\n' debootstrap)
echo "Creating base system using debootstrap version $dversion"
# Check if we need cross architecture debootstrap
targetarch=$(expr "$FAI_DEBOOTSTRAP_OPTS" : '.*--arch=\([^[:space:]]*\)' || true)
hostarch1=$(dpkg --print-architecture)
_debootstrap=qemu-debootstrap
if [ -z "$targetarch" ]; then
_debootstrap=debootstrap
targetarch=$hostarch1
else
if [ $targetarch = $hostarch1 ]; then
_debootstrap=debootstrap
fi
fi
for arch in $(dpkg --print-foreign-architectures); do
if [ $targetarch = $arch ]; then
_debootstrap=debootstrap
break
fi
done
if [ $_debootstrap = "qemu-debootstrap" ]; then
if ! command -v $_debootstrap >&/dev/null; then
die 1 "qemu-debootstrap not found. Please install the package qemu-user-static."
fi
fi
echo "Calling $_debootstrap $FAI_DEBOOTSTRAP_OPTS $1 $FAI_ROOT $2"
LC_ALL=C $_debootstrap $FAI_DEBOOTSTRAP_OPTS $1 $FAI_ROOT $2
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: none
# Requires-Var: $FAI_ROOT $do_init_tasks $NFSROOT $LOGDIR
# Suggests-Var: $FAI_DEBOOTSTRAP
# Short-Description: extrace minimal base file into target
### END SUBROUTINE INFO
task_extrbase() {
local fs=$FAI_ROOT/etc/fstab
fetch-basefile
# remember, ftar extracts into $FAI_ROOT by default, so / means $FAI_ROOT/
# copy the base file class based if it exists
[ -d $FAI/basefiles ] && ftar -p -1v -s $FAI/basefiles /
if [ $? -ne 0 ]; then
if [ $do_init_tasks -eq 1 ]; then
ftar -p -1v -c base -s /var/tmp /
else
[ -d $NFSROOT/var/tmp ] &&
ftar -p -1v -c base -s $NFSROOT/var/tmp /
fi
# if no base file was extracted, call debootstrap
if [ ! -d $FAI_ROOT/etc ]; then
echo "No base file found. Calling debootstrap."
[ -z "$FAI_DEBOOTSTRAP" ] && die "\$FAI_DEBOOTSTRAP undefined. Aborting"
call_debootstrap $FAI_DEBOOTSTRAP
task_error 801 $?
fi
fi
# now check if this is a cross architecture installation, and install qemu user static if needed
check-cross-arch $FAI_ROOT
# now we can copy fstab
[ -f $LOGDIR/fstab ] && cp -S.old -bp $LOGDIR/fstab $fs
# copy crypttab, if setup-storage created one
[ -f $LOGDIR/crypttab ] && cp -p $LOGDIR/crypttab $FAI_ROOT/etc/crypttab
# make /var/lib/dpkg a ramdisk
mkramdisk -a
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var:
# Requires-Var: $FAI_ROOT $MNTPOINT $romountopt
# Suggests-Var: $FAI_DEBMIRROR $debug
# Short-Description: mount Debian mirror via NFS
### END SUBROUTINE INFO
mount_mirror() {
# mount debian mirror directory
[ "$FAI_DEBMIRROR" ] || return # nothing to do
mkdir -p ${FAI_ROOT}${MNTPOINT}
if mount $romountopt $FAI_DEBMIRROR ${FAI_ROOT}${MNTPOINT}; then
[ "$debug" ] && echo "Mirror mounted from $FAI_DEBMIRROR to ${FAI_ROOT}${MNTPOINT}"
else
sendmon "TASKERROR repository $?"
die "Can't mount $FAI_DEBMIRROR"
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_debconf () {
if [ ! -d $FAI/debconf ]; then
echo "Can't find debconf directory $FAI/debconf. Skipping preseeding."
task_error 2
return
fi
fai-debconf $FAI/debconf
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### BEGIN SUBROUTINE INFO
# Provides-Var: none
# Requires-Var: $classes $FAI $FAI_ROOT $FAI_ETC_DIR $FAI_ALLOW_UNSIGNED
# Suggests-Var:
# Short-Description: prepare access to package repository
### END SUBROUTINE INFO
task_repository () {
# check for old hooks for task prepareapt
local hook cl hfile
hook=prepareapt
for cl in ${classes:-}; do
hfile=$FAI/hooks/$hook.$cl
if [ -f $hfile ]; then
echo "WARNING: The task prepareapt is obsolete. It was renamed to task repository. Please rename your hook $hfile to repository.$cl." >&2
continue
fi
if [ -f $hfile.source ]; then
echo "WARNING: The task prepareapt is obsolete. It was renamed to task repository. Please rename your hook $hfile.source to repository.$cl.source." >&2
continue
fi
done
if [ X$verbose = X1 ]; then
v=-v
fi
[ $do_init_tasks -eq 1 ] && FAI_ETC_DIR=/etc
# some generale network files are needed on the client
# resolv.conf is needed, /etc/hosts is useful in /target
# use a file from the config space or from /etc inside the nfsroot
if ! fcopy -BM $v /etc/resolv.conf ; then
if [ "$(readlink -f /etc/resolv.conf)" = "$(readlink -f $FAI_ROOT/etc/resolv.conf)" ] ; then
:
# no need for copy since both are pointing to the same file
else
[ -f /etc/resolv.conf ] && cp $v /etc/resolv.conf $FAI_ROOT/etc
fi
fi
if ! fcopy -M $v /etc/hosts ; then
[ X$FAI_ROOT = X/ ] || cp $v -bS.orig /etc/hosts $FAI_ROOT/etc
fi
# apt specific things
if ! fcopy -SBM $v /etc/apt/sources.list; then
[ -f $FAI_ETC_DIR/apt/sources.list ] && cp $v $FAI_ETC_DIR/apt/sources.list $FAI_ROOT/etc/apt
fi
if ! fcopy -BM $v /etc/apt/preferences; then
[ -f $FAI_ETC_DIR/apt/preferences ] && cp $v $FAI_ETC_DIR/apt/preferences $FAI_ROOT/etc/apt
fi
fcopy -SBMir /etc/apt # copy all other apt config files from the config space
if [ X$FAI_ALLOW_UNSIGNED = X1 ]; then
cat <<EOF > $FAI_ROOT/etc/apt/apt.conf.d/10fai
APT::Get::AllowUnauthenticated "true";
Acquire::AllowInsecureRepositories "true";
Aptitude::CmdLine::Ignore-Trust-Violations yes;
EOF
else
rm -f $FAI_ROOT/etc/apt/apt.conf.d/10fai
fi
# add apt keys for all classes
for keyfile in ${classes:-}; do
if [ -f $FAI/package_config/$keyfile.gpg ]; then
echo "Copying APT key $keyfile.gpg to target"
cp -v --preserve=timestamp $FAI/package_config/$keyfile.gpg $FAI_ROOT/etc/apt/trusted.gpg.d/
continue
fi
[ ! -f $FAI/package_config/$keyfile.asc ] && continue
echo "Copying APT key from $keyfile.asc to $keyfile.asc.gpg "
rm -f $FAI_ROOT/etc/apt/trusted.gpg.d/$keyfile.asc.gpg
gpg --batch -o $FAI_ROOT/etc/apt/trusted.gpg.d/$keyfile.asc.gpg --dearmor $FAI/package_config/$keyfile.asc
done
# mount Debian mirror via NFS if needed
mount_mirror
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_updatebase() {
# maybe the base system is not up to date
if [ X$verbose = X1 ]; then
updatebase </dev/null |& tee -a $LOGDIR/software.log
task_error 474 ${PIPESTATUS[0]}
else
updatebase </dev/null >> $LOGDIR/software.log 2>&1
task_error 474 $?
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_instsoft() {
if [ X$verbose = X1 ]; then
echo "Installing software may take a while"
fi
if [ "$debug" ]; then
install_packages | tee -a $LOGDIR/software.log
task_error 471 ${PIPESTATUS[0]}
elif [ X$verbose = X1 ]; then
install_packages </dev/null |& tee -a $LOGDIR/software.log
task_error 471 ${PIPESTATUS[0]}
else
install_packages </dev/null >> $LOGDIR/software.log 2>&1
task_error 471 $?
fi
# This almost indicates an error
grep -E "^E:" $LOGDIR/software.log && task_error 472
grep "Couldn't find any package whose name or description matched" $LOGDIR/software.log && task_error 321
grep -q "E: Sub-process /usr/bin/dpkg returned an error code" $LOGDIR/software.log && task_error 620
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_finish() {
mkramdisk -au # umount ramdisk
if [ $do_init_tasks -eq 1 ] ; then
# show some local information
df -PTh | grep -E ':|^/|^Filesystem'
# show rx and tx bytes of network device
grep . /sys/class/net/*/statistics/*x_bytes | perl -ane 'm#/sys/class/net/(.+)/statistics/(.+):(\d+)# && ($3) && ($1 ne lo) && printf "%s %s %.2f Mbytes\n",$1,$2,$3/1000000 '
swapoff -a
else
df -PTh | grep -E "^Filesystem|$target"
fi
# undo fake of all programs made by fai
fai-divert -R
rm -f $FAI_ROOT/etc/apt/apt.conf.d/{10,90}fai
echo -n "FAI finished at: ";date
echo "The $FAI_ACTION took $(($(cut -d . -f 1 /proc/uptime) - start_seconds)) seconds."
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
task_chboot() {
# the whole subroutine may be an externel script
[ -z "$LOGUSER" ] && return # silently return from subroutine
local frsh remotesh
local doexit=0
local hostname
read hostname < /proc/sys/kernel/hostname
local ipaddr=$(grep IPADDR $LOGDIR/boot.log | cut -d= -f2 | sed "s/'//g")
local nexttest=$(grep -E -s ^NEXTTEST= $LOGDIR/test.log | cut -d= -f2)
case "$FAI_LOGPROTO" in
ftp) remotesh=ssh ;;
ssh) remotesh=ssh ;;
rsh) remotesh=rsh ;;
*) echo "ERROR: Unknown value for \$FAI_LOGPROTO." ;;
esac
frsh="$remotesh -l $LOGUSER ${SERVER}"
if [ -z "$SERVER" ] ; then
echo "SERVER not defined. Can't change network boot configuration"
task_error 2
doexit=1
fi
[ $doexit -eq 1 ] && return
# change boot device (local disk or network) when using PXE
# first test if rsh to server works
$frsh true >/dev/null 2>&1
if [ $? -ne 0 ]; then
task_error 3
echo "WARNING: $frsh failed. Can't call fai-chboot on the install server." >&2
else
if [ -n "$nexttest" ]; then
# for test sequences, we want the system to reinstall immediately with
# with different class setup
$frsh /usr/sbin/fai-chboot -k ADDCLASSES=$nexttest -FIv $ipaddr $MAC
else
# remove pxe config, so host will use default and boot from local disk
$frsh /usr/sbin/fai-chboot -vd $ipaddr $MAC
fi
fi
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
sendmon() {
# send message to monitor daemon
echo "$*" >> $LOGDIR/fai-monitor.log
[ "$faimond" -eq 0 ] && return 0
echo "$sendid $*" | nc -w 8 $monserver $FAI_MONITOR_PORT 2>/dev/null
return $?
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
More information about the linux-fai
mailing list