/[fai]/branches/stable/3.4/lib/subroutines
ViewVC logotype

Contents of /branches/stable/3.4/lib/subroutines

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6011 - (show annotations) (download)
Tue Aug 17 12:56:21 2010 UTC (2 years, 9 months ago) by mika
File size: 30278 byte(s)
subroutines: new subroutine umount_csspace, so it can be used in user hooks (thanks to Waldemar for the patch)


Signed-off-by: Michael Prokop <mika@grml.org>
1 #! /bin/bash
2
3 # $Id$
4 #*********************************************************************
5 #
6 # subroutines -- useful subroutines for FAI
7 #
8 # This script is part of FAI (Fully Automatic Installation)
9 # (c) 2000-2010 by Thomas Lange, lange@informatik.uni-koeln.de
10 # Universitaet zu Koeln
11 # (c) 2001-2005 by Henning Glawe, glaweh@physik.fu-berlin.de
12 # Freie Universitaet Berlin
13 #
14 #*********************************************************************
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation; either version 2 of the License, or
18 # (at your option) any later version.
19 #
20 # This program is distributed in the hope that it will be useful, but
21 # WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 # General Public License for more details.
24 #
25 # A copy of the GNU General Public License is available as
26 # `/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
27 # or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
28 # can also obtain it by writing to the Free Software Foundation, Inc.,
29 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
30 #*********************************************************************
31
32 # source this file, then you have these function available in the shell
33
34 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35 die() {
36
37 # echo comment and exit installation
38 task_savelog
39 echo "$@"
40 if [ X$FAI_ACTION = Xinstall ]; then
41 exec bash -i
42 else
43 exit 99
44 fi
45 }
46 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47 defnop() {
48
49 # define given list of subroutine names as dummy function;
50 # this will fake unknown commands
51
52 local name
53 for name in "$@";do
54 eval "$name () { :;}"
55 done
56 }
57 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
58 ### BEGIN SUBROUTINE INFO
59 # Provides-Var: none
60 # Required-Var: $classes
61 # Short-Description: test if class is defined
62 ### END SUBROUTINE INFO
63
64 ifclass() {
65
66 [ "$debug" ] && echo "Test if class $1 is in $classes" >&2
67 # test if a class is defined
68 local cl
69 local ret=1
70
71 for cl in $classes; do
72 [ x$cl = x$1 ] && ret=0 && break
73 done
74 [ "$debug" ] && echo "ifclass returns $ret" >&2
75 return $ret
76 }
77 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
78 rwmount() {
79
80 # remount partition read/write, for interactive use only
81 mount -o rw,remount $1
82 }
83 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
84 save_dmesg() {
85
86 dmesg > $LOGDIR/dmesg.log
87 }
88 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89 umount_csspace() {
90
91 # umount config space if accessed via nfs
92 echo $FAI_CONFIG_SRC | grep -q ^nfs://
93 if [ $? -eq 0 ]; then
94 grep -q " $FAI nfs" /etc/mtab && umount $FAI
95 fi
96 }
97 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
98 jobsrunning() {
99
100 # test if jobs are running
101 ps r | egrep -qv "ps r|TIME COMMAND|rcS"
102 }
103 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
104 wait_for_jobs() {
105
106 # can be an extern script
107 # wait for running (background) jobs to finish (e.g. update-auctex-elisp)
108 local i=0
109 while jobsrunning; do
110 [ $(($i % 3)) -eq 0 ] && echo "Waiting for background jobs to finish."
111 (( i += 1 ))
112 sleep 10
113 done
114 }
115 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116 stop_fai_installation() {
117
118 # this subroutine should directly stop the installation process
119 sendmon "TASKEND $taskname $task_error"
120 echo "Error in task $taskname. Traceback: $task_error_func"
121 die "FATAL ERROR. Installation stopped."
122 }
123 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
124 ### BEGIN SUBROUTINE INFO
125 # Provides-Var: $task_error
126 # Required-Var: $1 $2 $task_error
127 # Short-Description: save the maximum error code,
128 # Short-Description: $1 is the error that will be saved unless $2 is zero
129 ### END SUBROUTINE INFO
130
131 task_error() {
132
133 [ X$2 = X0 ] && return
134 task_error_func=${FUNCNAME[*]}
135 [ $1 -gt $task_error ] && task_error=$1
136 [ $task_error -gt $STOP_ON_ERROR ] && stop_fai_installation
137 }
138 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
139 ### BEGIN SUBROUTINE INFO
140 # Provides-Var: $task_error
141 # Required-Var: $LOGDIR
142 # Short-Description: call a certain task
143 ### END SUBROUTINE INFO
144
145 task() {
146
147 # hooks are called before a task is called
148 # if a task is skipped, also its hooks are skipped
149 # a hook can set the flag, so the accociated task is skipped
150
151 local taskname=$1
152
153 [ -f $LOGDIR/skip.$taskname ] || call_hook $taskname
154
155 if [ -f $LOGDIR/skip.$taskname ]; then
156 # skip task
157 rm $LOGDIR/skip.$taskname # TODO: remove skip files at the very end
158 [ "$verbose" ] && echo "Skiping task_$taskname"
159 sendmon "TASKSKIP $taskname"
160 else
161 echo "Calling task_$taskname"
162 sendmon "TASKBEGIN $taskname"
163 task_error=0 # task can set this variable to indicate an error
164 task_error_func=''
165 task_$taskname
166 sendmon "TASKEND $taskname $task_error"
167 if [ "$task_error" -ne 0 ] ; then
168 echo "Exit code task_$taskname: $task_error"
169 fi
170 fi
171 }
172 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
173 ### BEGIN SUBROUTINE INFO
174 # Provides-Var:
175 # Required-Var: $classes $debug
176 # Short-Description: call a hook, hook.source can define additional variables
177 ### END SUBROUTINE INFO
178
179 call_hook() {
180
181 local hook=$1
182 local cl dflag hfile
183 [ "$debug" ] && dflag="-d"
184
185 for cl in $classes; do
186 hfile=$FAI/hooks/$hook.$cl
187 if [ -f $hfile -a ! -x $hfile ]; then
188 echo "WARNING: Skipping $hfile because it's not executable."
189 continue
190 fi
191 if [ -f $hfile.source -a ! -x $hfile.source ]; then
192 echo "WARNING: Skipping $hfile.source because it's not executable."
193 continue
194 fi
195 if [ -x $hfile ]; then
196 echo "Calling hook: $hook.$cl"
197 sendmon "HOOK $hook.$cl"
198 # execute the hook
199 $hfile $dflag
200 check_status $hook.$cl $?
201 fi
202 if [ -x $hfile.source ]; then
203 echo "Source hook: $hook.$cl.source"
204 sendmon "HOOK $hook.$cl.source"
205 # source this hook
206 . $hfile.source $dflag
207 check_status $hook.$cl.source $?
208 fi
209 done
210 }
211 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
212 skiptask() {
213
214 # mark all given tasks, so they will be skipped
215 local task
216
217 for task in "$@"; do
218 echo > $LOGDIR/skip.$task # create file with size != 0
219 done
220 }
221 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
222 define_fai_flags() {
223
224 local flag
225 # FAI_FLAGS are comma separated, define all flags
226 FAI_FLAGS=${FAI_FLAGS//,/ }
227 echo "FAI_FLAGS: $FAI_FLAGS"
228 for flag in $FAI_FLAGS; do
229 # define this flag as 1
230 eval "flag_$flag=1"
231 done
232 [ "$flag_verbose" ] && verbose=1 # for backward compability
233 [ "$flag_debug" ] && debug=1 # for backward compability
234 }
235 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
236 ### BEGIN SUBROUTINE INFO
237 # Provides-Var: $fai_rundate
238 # Requires-Var: $DOMAIN $do_init_tasks
239 # Suggests-Var: $flag_createvt $flag_sshd
240 # Short-Description: <task desc.>
241 ### END SUBROUTINE INFO
242
243 task_setup() {
244
245 # source user specific subroutines
246 [ -f $FAI/hooks/subroutines ] && . $FAI/hooks/subroutines
247
248 define_fai_flags
249
250 # this may be moved to an external script
251 if [ $do_init_tasks -eq 1 ] ; then
252 # set the system time and date using rdate or/and ntpdate
253 [ "$TIMESRVS_1" ] && rdate $TIMESRVS_1
254 [ "$NTPSRVS_1" ] && ntpdate -b $NTPSRVS
255 [ "$flag_createvt" ] && {
256 # create two virtual terminals; acces via alt-F2 and alt-F3
257 echo "Press ctrl-c to interrupt FAI and to get a shell"
258 openvt -c2 /bin/bash ; openvt -c3 /bin/bash
259 trap 'echo "You can reboot with faireboot";bash' INT QUIT
260 }
261
262 # start secure shell daemon for remote access
263 mkdir -p /var/run/sshd # ubuntu fix for 9.10
264 [ "$flag_sshd" -a -x /usr/sbin/sshd ] && /usr/sbin/sshd
265 fi
266 unset flag_createvt flag_sshd
267
268 # when did FAI start, using localtime
269 : ${fai_rundate:=$(date +'%Y%m%d_%H%M%S')}
270 if [ $do_init_tasks -eq 1 ]; then
271 echo "Starting FAI execution - $fai_rundate"
272 fi
273 }
274 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
275 ### BEGIN SUBROUTINE INFO
276 # Provides-Var: none
277 # Requires-Var: $FAI_ACTION
278 # Short-Description: call task depending on $FAI_ACTION
279 ### END SUBROUTINE INFO
280
281 task_action() {
282
283 if [ -z "$FAI_ACTION" ]; then
284 echo "No action in \$FAI_ACTION defined."
285 sendmon "TASKERROR action 21"
286 task_faiend
287 exit
288 fi
289
290 echo "FAI_ACTION: $FAI_ACTION"
291 case $FAI_ACTION in
292 install)
293 if [ $do_init_tasks -eq 0 ]; then
294 echo "Cowardly refusing to run a FAI installation on a running system."
295 return
296 fi
297 echo Performing FAI installation. All data may be overwritten!
298 echo -ne "\a"; sleep 1
299 echo -ne "\a"; sleep 1
300 echo -e "\a"; sleep 5
301 task install
302 task faiend
303 ;;
304 dirinstall)
305 task dirinstall
306 ;;
307 softupdate)
308 echo Performing FAI system update. All data may be overwritten!
309 task softupdate
310 ;;
311 sysinfo)
312 echo Showing system information.
313 task sysinfo
314 task_faiend
315 die Now you have a shell.
316 ;;
317 *)
318 if [ -f $FAI/hooks/$FAI_ACTION ]; then
319 echo "Calling user defined action: $FAI_ACTION"
320 $FAI/hooks/$FAI_ACTION
321 else
322 echo "ERROR: User defined action $FAI/hooks/$FAI_ACTION not found."
323 sendmon "TASKERROR action 22"
324 task_faiend
325 fi
326 ;;
327 esac
328 }
329 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
330 ### BEGIN SUBROUTINE INFO
331 # Provides-Var: $classes $cfclasses
332 # Requires-Var: $LOGDIR
333 # Suggests-Var: $renewclass
334 # Short-Description: <task desc.>
335 ### END SUBROUTINE INFO
336
337 task_defclass() {
338
339 if [ ! -d $FAI/class ]; then
340 sendmon "TASKERROR defclass 21"
341 echo "Subdirectory $FAI/class missing in config space. Following subdirectories are found:"
342 find $FAI -maxdepth 1 -type d -printf "%p\n"
343 die "Aborting."
344 fi
345
346 # new script for defining classes; variables imported: $LOGDIR, $verbose, $debug
347 if [ $renewclass -eq 1 ]; then
348 # reevaluate new list of classes
349 fai-class -T $FAI/class $LOGDIR/FAI_CLASSES
350 classes=$(< $LOGDIR/FAI_CLASSES)
351 elif [ -n "$cmdlineclasses" ]; then
352 classes=$cmdlineclasses
353 elif [ ! -f /var/lib/fai/FAI_CLASSES ]; then
354 # use classes defined at installation time
355 die "Try to read classes from /var/lib/fai/FAI_CLASSES. Failed. Aborting."
356 else
357 classes=$(< /var/lib/fai/FAI_CLASSES)
358 fi
359 echo "List of all classes: " $classes
360
361 # define classes as: a.b.c.d for cfengine -D
362 # this doesn't work without echo
363 cfclasses=$(echo $classes)
364 cfclasses=${cfclasses// /.}
365 [ "$debug" ] && echo "cfclasses: $cfclasses"
366 }
367 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
368 _defvar() {
369
370 local showvar=1 # TODO: new FAI_FLAG or always set when verbose is used
371 [ "$showvar" ] && set -x
372 . $1 </dev/null
373 [ "$showvar" ] && set +x
374 }
375 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
376 task_defvar() {
377
378 local svar=$LOGDIR/showvar.log
379 local odir=$(pwd)
380 cd $FAI/class
381 for class in $classes ; do
382 if [ -f $class.var -a -r $class.var ]; then
383 [ "$verbose" ] && echo "Executing $class.var"
384 # show only lines with ++, we cannot use a pipe, since it would call
385 # _devfar in a subprocess. Then, variables are not defined
386 _defvar $class.var > $svar 2>&1
387 grep ^++ $svar
388 rm $svar
389 fi
390 done
391
392 # /fai/class/* scripts or hooks can write variable definitions
393 # to additonal.var. now source these definitions
394 if [ -f $LOGDIR/additional.var -a -r $LOGDIR/additional.var ]; then
395 _defvar $LOGDIR/additional.var > $svar 2>&1
396 grep ^++ $svar
397 rm $svar
398 fi
399 unset class svar
400 # now all variables are defined. Dump them to variables.log, so we can sources them if needed
401 set | perl -ne 'print if /^\w\w+=/ and not /^(EUID|PPID|SHELLOPTS|UID|rootpw|ROOTPW|HOME|PWD)|\(/' > $LOGDIR/variables.log
402 # another approach is to use this. A slightly different format, but seems to be robust.
403 # declare -x > $LOGDIR/variables.log
404 cd $odir
405 }
406 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
407 task_mountdisks() {
408
409 [ ! -f $LOGDIR/fstab ] && die "No $LOGDIR/fstab created."
410 # mount swap space
411 local sd
412 for sd in $SWAPLIST; do
413 swapon -p1 $sd && [ "$verbose" ] && echo "Enable swap device $sd"
414 done
415 mount2dir $FAI_ROOT $LOGDIR/fstab
416 if [ "$?" -eq 1 ]; then
417 sendmon "TASKERROR mountdisks 705"
418 task_error 705
419 fi
420 }
421 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
422 task_configure() {
423
424 fai-do-scripts $FAI/scripts
425 task_error 420 $?
426 }
427 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
428 task_tests() {
429
430 if [ -d $FAI/tests ]; then
431 fai-do-scripts $FAI/tests # always returns 0 atm
432 # check if any test failed
433 if [ -f $LOGDIR/test.log ]; then
434 if grep -q "FAILED with " $LOGDIR/test.log; then
435 sendmon "TASKERROR tests 312"
436 task_error 312
437 return 1
438 fi
439 fi
440 else
441 echo "WARNING: Subdirectory tests/ not found. No tests run."
442 fi
443 }
444 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
445 task_savelog() {
446
447 mkdir -p $FAI_ROOT/var/{lib,log}/fai
448 fai-savelog -l
449 [ -f $LOGDIR/FAI_CLASSES ] && cp -pu $LOGDIR/FAI_CLASSES $FAI_ROOT/var/lib/fai
450 [ -f $LOGDIR/disk_var.sh ] && cp -pu $LOGDIR/disk_var.sh $FAI_ROOT/var/lib/fai
451 fai-savelog -r
452 }
453 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
454 task_faiend() {
455
456 local dir cdromdevice
457 [ $do_init_tasks -eq 0 ] && exit 0
458 wait_for_jobs
459 echo "Press <RETURN> to reboot."
460 : ${flag_reboot:=0}
461 [ -s $LOGDIR/error.log -a "$flag_reboot" -gt "0" ] && sleep 10
462 # reboot without prompting if FAI_FLAG reboot is set
463 sendmon "TASKEND faiend 0"
464 [ "$flag_reboot" -lt "1" ] && read
465 echo "Rebooting $HOSTNAME now"
466 sendmon "TASKEND reboot 0"
467 cd /
468 sync
469
470 killall -q sshd udevd
471 if [ -f /etc/RUNNING_FROM_FAICD ]; then
472 cat > $target/tmp/rebootCD <<'EOF'
473 #! /bin/bash
474 device=$1
475 eject -m /dev/$device 2>/dev/null >/dev/null
476 echo "Remove CDROM and press <RETURN> to continue reboot"
477 read
478 eject -t /dev/$device 2>/dev/null >/dev/null
479 exec reboot -df
480 EOF
481 chmod +x $target/tmp/rebootCD
482 sync
483 for dir in $(mount | grep $target | awk '{print $3}' | sort -r); do
484 mount -o remount,ro $dir
485 done
486 cdromdevice=$(awk '/ name:/ {print $3}' /proc/sys/dev/cdrom/info)
487 chroot $target /tmp/rebootCD $cdromdevice
488 # never reached, because chroot will reboot the machine
489 die "Internal error when calling /tmp/rebootCD."
490 fi
491 umount $FAI_ROOT/proc
492 umount -ar
493 exec reboot -dfi
494 }
495 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
496 task_install() {
497
498 echo $$ > $stamp
499
500 save_dmesg
501
502 task partition
503 task mountdisks
504 task extrbase
505 task mirror
506 task debconf
507 task prepareapt
508 task updatebase
509 task instsoft
510 task configure
511 task finish
512 task tests
513 task chboot
514
515 rm -f $stamp
516 save_dmesg # save again, because new messages could be created
517 task savelog
518
519 if [ -f $stamp ]; then
520 echo "Error while executing commands in subshell."
521 echo -n "$stamp was not removed. PID of running process: "
522 cat $stamp
523 sendmon "TASKERROR install 21"
524 die "Please look at the log files in $LOGDIR for errors."
525 fi
526 }
527 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
528 task_dirinstall() {
529
530 mkdir -p $FAI_ROOT
531 FAI_ROOT=$(cd $FAI_ROOT;pwd)
532 xstamp=${FAI_ROOT//\//=}
533 stamp=/var/run/fai/dirinstall-$xstamp
534 unset xstamp
535 clean_exit() {
536 rm -f $stamp
537 [ -z "$FAI_ROOT" ] && return
538 [ -d $FAI_ROOT/proc/self ] && umount $FAI_ROOT/proc
539 [ -d $FAI_ROOT/sys/class ] && umount $FAI_ROOT/sys
540 # /proc + /sys might be empty because they were unmounted inside
541 # $FAI_ROOT but are still registered in /etc/mtab outside $FAI_ROOT,
542 # so let's get rid of them outside the chroot as well
543 if grep -q "${FAI_ROOT}/sys " /etc/mtab ; then
544 umount $FAI_ROOT/sys 2>/dev/null || true
545 fi
546 if grep -q "${FAI_ROOT}/proc " /etc/mtab ; then
547 umount $FAI_ROOT/proc 2>/dev/null || true
548 fi
549 umount $FAI_ROOT/dev/pts 2>/dev/null || true
550 # sometimes umount $FAI_ROOT/dev fails, because a process is
551 # still running in the background and accesses /dev
552 # this occured sometimes when using dirinst and a long package
553 # list if dhelp.postinst is starting an index process in the
554 # bg which did not finished until the installation was finished.
555 [ -f /etc/init.d/udev ] && umount $FAI_ROOT/dev
556 mkramdisk -au 2>/dev/null
557 }
558 trap 'clean_exit' INT QUIT EXIT
559
560
561
562 [ -f "$stamp" ] && {
563 echo -n "fai dirinstall into directory $FAI_ROOT already running or was aborted before. PID: "
564 cat $stamp
565 echo "You may remove $stamp and try again."
566 exit 1
567 }
568
569 echo $$ > $stamp
570 echo "Installing into directory $FAI_ROOT"
571 task extrbase
572 [ -f $target/etc/fstab ] || touch $target/etc/fstab
573 task mirror
574 task debconf
575 task prepareapt
576 task updatebase
577 task instsoft
578 task configure
579 task finish
580 clean_exit
581
582 rm -f $stamp
583 unset LOGUSER # so logfile are not saved to remote
584 task savelog
585
586 if [ -f $stamp ]; then
587 echo "Error while executing commands in subshell."
588 echo -n "$stamp was not removed. PID of running process: "
589 cat $stamp
590 sendmon "TASKERROR install 21"
591 die "Please look at the log files in $LOGDIR for errors."
592 fi
593 }
594 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
595 task_softupdate() {
596
597 stamp=/var/run/fai/fai_softupdate_is_running
598 [ -f "$stamp" ] && die "Lock file $stamp found. Another fai softupdate is already running. Aborting."
599 echo $$ > $stamp
600 trap "rm -f $stamp" INT QUIT EXIT
601
602 # if the system had been installed using fai < 3.0 disk_var.sh is found in /etc/fai
603 if [ ! -f /var/lib/fai/disk_var.sh -a -f /etc/fai/disk_var.sh ] ; then
604 mv /etc/fai/disk_var.sh /var/lib/fai/
605 fi
606 # the following copy operation is required to make $LOGDIR a reliable source
607 # for disk_var.sh
608 # use the last disk_var during update if available
609 [ -f /var/lib/fai/disk_var.sh ] && cp -p /var/lib/fai/disk_var.sh $LOGDIR
610
611 defnop wait_for_jobs
612 save_dmesg
613
614 task mirror
615 task debconf
616 task updatebase
617 task instsoft
618 task configure
619 date
620 [ -f /proc/uptime ] && echo "The $FAI_ACTION took $[$(cut -d . -f 1 /proc/uptime)-$start_seconds] seconds."
621
622 rm -f $stamp
623 # save again, because new messages could be created
624 save_dmesg
625 task savelog
626 umount_csspace
627
628 if [ -f $stamp ]; then
629 echo "Error while executing commands in subshell."
630 echo -n "$stamp was not removed. PID of running process: "
631 cat $stamp
632 sendmon "TASKERROR softupdate 21"
633 die "Please look at the log files in $LOGDIR for errors."
634 fi
635 }
636 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
637
638 catnc() {
639 # cat but no comment lines
640 egrep -v "^#" $@
641 }
642 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
643 ### BEGIN SUBROUTINE INFO
644 # Provides-Var: $disklist
645 # Requires-Var:
646 # Short-Description: create list of available disks
647 ### END SUBROUTINE INFO
648
649 set_disk_info() {
650
651 # the variable holds a space separated list of devices
652 disklist=$(disk-info | sort)
653 }
654 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
655 eval_cmdline() {
656
657 # parse kernel parameters and define variables
658 local word
659
660 echo -n "Kernel currently running: "
661 uname -rsmo
662 echo -n "Kernel parameters: "; cat /proc/cmdline
663 for word in $(cat /proc/cmdline) ; do
664 case $word in
665 FAI_CLASSES=*)
666 eval "$word"
667 for class in ${FAI_CLASSES//,/ }; do
668 echo $class >>/tmp/l
669 done
670 unset FAI_CLASSES
671 ;;
672
673 [a-zA-Z]*=*)
674 eval "export $word"
675 ;;
676 esac
677 done
678 }
679 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
680 ### BEGIN SUBROUTINE INFO
681 # Provides-Var: $faimond $sendhostname
682 # Requires-Var: $LOGDIR $FAI
683 # Suggests-Var: $monserver
684 # Short-Description: <task desc.>
685 ### END SUBROUTINE INFO
686
687 task_confdir() {
688
689 if [ $do_init_tasks -eq 1 ] ; then
690 eval_cmdline
691
692 get-boot-info
693 echo "Reading $LOGDIR/boot.log"
694 . $LOGDIR/boot.log
695 unset T170 T171 T172 ROOT_PATH BOOTFILE
696
697 printk=${printk:-6}
698 echo $printk > /proc/sys/kernel/printk
699 rsyslogd -c3
700
701 create_resolv_conf
702 fi
703 define_fai_flags
704
705 # check if monitor server is available
706 : ${monserver:=$SERVER}
707 if [ -z "$monserver" ]; then
708 echo "No monitor daemon defined."
709 faimond=0
710 else
711 faimond=1
712 sendhostname=$HOSTNAME # save current hostname
713 if sendmon check; then
714 echo "Monitoring to server $monserver enabled."
715 sendmon "TASKBEGIN confdir"
716 else
717 faimond=0
718 echo "Can't connect to monserver on $monserver port 4711. Monitoring disabled."
719 fi
720 fi
721
722 get-config-dir || {
723 echo "Problems accessing the config space."
724 die ""
725 }
726
727 # now you have enough time to make changes to the config space
728 # only for debugging
729 if [ -n "$flag_wait" ]; then
730 echo "Sleeping. Now you may change the config space in $FAI."
731 echo "Continue after killall sleep."
732 sleep 50000
733 fi
734 }
735 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
736 ### BEGIN SUBROUTINE INFO
737 # Provides-Var: $BOOT_DEVICE $ROOT_PARTITION $BOOT_PARTITION $SWAPLIST
738 # Requires-Var: $LOGDIR $LOGDIR/disk_var.sh
739 # Short-Description: partition local hard disk
740 ### END SUBROUTINE INFO
741
742 task_partition() {
743
744 if [ X$USE_SETUP_STORAGE = X1 ]; then
745 echo "Partitioning local harddisks using setup-storage"
746 [ ! -s $LOGDIR/disk_var.sh ] && setup-storage -X 2>&1 | tee $LOGDIR/format.log
747 else
748 echo "Partitioning local harddisks using setup_harddisks"
749 [ ! -s $LOGDIR/disk_var.sh ] && setup_harddisks -d -X 2>&1 | tee $LOGDIR/format.log
750 fi
751
752 # partitioning tool must create $LOGDIR/disk_var.sh file
753 if [ ! -s $LOGDIR/disk_var.sh ]; then
754 task_error 710
755 cat $LOGDIR/format.log
756 sendmon "TASKERROR partition 21"
757 die "Partitioning tool did not create $LOGDIR/disk_var.sh file."
758 fi
759 # now define variable for root and boot partition and boot device
760 . $LOGDIR/disk_var.sh
761 }
762 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
763 ### BEGIN SUBROUTINE INFO
764 # Provides-Var: none
765 # Requires-Var: $NFSROOT
766 # Suggests-Var:
767 # Short-Description: <task desc.>
768 ### END SUBROUTINE INFO
769
770 call_debootstrap() {
771
772 local dversion=$(dpkg -l debootstrap | grep debootstrap | cut -f7 -d' ')
773 echo "Creating base system using debootstrap version $dversion"
774 echo "Calling debootstrap $FAI_DEBOOTSTRAP_OPTS $1 $FAI_ROOT $2"
775 LC_ALL=C debootstrap $FAI_DEBOOTSTRAP_OPTS $1 $FAI_ROOT $2
776 }
777 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
778 ### BEGIN SUBROUTINE INFO
779 # Provides-Var: none
780 # Requires-Var: $FAI_ROOT $do_init_tasks $NFSROOT $LOGDIR
781 # Suggests-Var: $FAI_DEBOOTSTRAP
782 # Short-Description: <task desc.>
783 ### END SUBROUTINE INFO
784
785 task_extrbase() {
786
787 local fs=$FAI_ROOT/etc/fstab
788 local basefile=/var/tmp/base.tgz
789
790 echo "Unpacking Debian base archive"
791 # copy the base file class based if it exists
792 [ -d $FAI/basefiles ] && ftar -1v -s $FAI/basefiles /
793 if [ $? -ne 0 ]; then
794 [ $do_init_tasks -eq 0 ] && basefile=$NFSROOT/live/filesystem.dir/var/tmp/base.tgz
795 if [ -f $basefile ]; then
796 # extract the tar file which was the result of debootstrap
797 echo "Extracting $basefile"
798 gzip -dc $basefile | tar -C $FAI_ROOT -xpf -
799 else
800 echo "No base.tgz found. Calling debootstrap."
801 [ -z "$FAI_DEBOOTSTRAP" ] && die "$FAI_DEBOOTSTRAP undefined. Aborting"
802 call_debootstrap $FAI_DEBOOTSTRAP
803 task_error 801 $?
804 fi
805 fi
806 # now we can copy fstab
807 [ -f $fs ] && mv $fs $fs.old
808 [ -f $LOGDIR/fstab ] && cp -p $LOGDIR/fstab $fs
809 # copy crypttab, if setup-storage created one
810 [ -f $LOGDIR/crypttab ] && cp -p $LOGDIR/crypttab $FAI_ROOT/etc/crypttab
811 # make /var/lib/dpkg a ramdisk
812 mkramdisk -a
813 }
814 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
815 ### BEGIN SUBROUTINE INFO
816 # Provides-Var:
817 # Requires-Var: $FAI_ROOT $MNTPOINT $romountopt
818 # Suggests-Var: $FAI_DEBMIRROR $debug
819 # Short-Description: <task desc.>
820 ### END SUBROUTINE INFO
821
822 task_mirror() {
823
824 # mount debian mirror directory
825 [ "$FAI_DEBMIRROR" ] || return # nothing to do
826 mkdir -p ${FAI_ROOT}${MNTPOINT}
827 if mount $romountopt $FAI_DEBMIRROR ${FAI_ROOT}${MNTPOINT}; then
828 [ "$debug" ] && echo "Mirror mounted from $FAI_DEBMIRROR to ${FAI_ROOT}${MNTPOINT}"
829 else
830 sendmon "TASKERROR mirror $?"
831 die "Can't mount $FAI_DEBMIRROR"
832 fi
833 }
834 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
835 task_debconf () {
836
837 if [ ! -d $FAI/debconf ]; then
838 echo "Can't find debconf directory $FAI/debconf. Skipping preseeding."
839 task_error 2
840 return
841 fi
842 fai-debconf $FAI/debconf
843 }
844 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
845 ### BEGIN SUBROUTINE INFO
846 # Provides-Var: none
847 # Requires-Var: $FAI_ROOT $FAI_ETC_DIR
848 # Suggests-Var: $IPADDR $DOMAIN
849 # Short-Description: <task desc.>
850 ### END SUBROUTINE INFO
851
852 task_prepareapt () {
853
854 # ftp and http needs resolv.conf in chroot environment, /etc/hosts is useful
855 # think about using fcopy for these two files
856 [ -f /etc/resolv.conf ] && cp /etc/resolv.conf $FAI_ROOT/etc
857 [ -f /etc/hosts ] && cp /etc/hosts $FAI_ROOT/etc
858 # set hostname in $FAI_ROOT
859 if [ -f /var/run/fai/FAI_INSTALLATION_IN_PROGRESS ]; then
860 echo $HOSTNAME >$FAI_ROOT/etc/hostname
861 fi
862
863
864 # during normal installation, we need sources.list from /etc/apt
865 # currently /target/etc/apt gets overwritten by the contents of /etc/apt from inside the nfsroot
866 [ $do_init_tasks -eq 1 ] && FAI_ETC_DIR=/etc
867 [ -d $FAI_ETC_DIR/apt ] && cp -r $FAI_ETC_DIR/apt/* $FAI_ROOT/etc/apt/
868
869 rm -f $FAI_ROOT/etc/apt/apt.conf.d/10fai # disable AllowUnauthenticated, which was used in the nfsroot
870 if [ X$FAI_ALLOW_UNSIGNED = X1 ]; then
871 cat <<EOF > $FAI_ROOT/etc/apt/apt.conf.d/10fai
872 APT::Get::AllowUnauthenticated "true";
873 Aptitude::CmdLine::Ignore-Trust-Violations yes;
874 EOF
875 fi
876 }
877 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
878 task_updatebase() {
879
880 # maybe the base system is not up to date
881
882 local keyfile
883 # add apt keys for signed repositories
884 for keyfile in `cd $FAI/package_config; ls *.asc 2>/dev/null`; do
885 echo -n "Loading APT key from $keyfile "
886 cat $FAI/package_config/$keyfile | $ROOTCMD apt-key add -
887 done
888
889 if [ "$verbose" ]; then
890 echo "Updating base"
891 updatebase </dev/null 2>&1 | tee -a $LOGDIR/software.log
892 task_error 474 ${PIPESTATUS[0]}
893 else
894 updatebase </dev/null >> $LOGDIR/software.log 2>&1
895 task_error 474 $?
896 fi
897 }
898 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
899 task_instsoft() {
900
901 echo "Installing software may take a while"
902 if [ "$debug" ]; then
903 install_packages | tee -a $LOGDIR/software.log
904 task_error 471 ${PIPESTATUS[0]}
905 elif [ "$verbose" ]; then
906 install_packages </dev/null 2>&1 | tee -a $LOGDIR/software.log
907 task_error 471 ${PIPESTATUS[0]}
908 else
909 install_packages </dev/null >> $LOGDIR/software.log 2>&1
910 task_error 471 $?
911 fi
912 # This almost indicates an error
913 egrep "^E:" $LOGDIR/software.log && task_error 472
914 grep "Couldn't find any package whose name or description matched" $LOGDIR/software.log && task_error 321
915 grep -q "E: Sub-process /usr/bin/dpkg returned an error code" $LOGDIR/software.log && task_error 620
916 }
917 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
918 task_finish() {
919
920 if [ $do_init_tasks -eq 1 ] ; then
921 # show some local information
922 ip -s link show up; df
923 # umount swap space
924 swapoff -a
925 fi
926
927 mkramdisk -au # umount ramdisk
928 # undo fake of all programs made by fai
929 fai-divert -R
930 rm -f $FAI_ROOT/etc/apt/apt.conf.d/{10,90}fai
931 date
932 echo "The $FAI_ACTION took $[$(cut -d . -f 1 /proc/uptime)-$start_seconds] seconds."
933 }
934 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
935 task_chboot() {
936
937 # the whole subroutine may be an externel script
938
939 [ -z "$LOGUSER" ] && return # silently return from subroutine
940
941 local frsh remotesh
942 local doexit=0
943 local hostname=$(hostname)
944 local ipaddr=$(grep IPADDR $LOGDIR/boot.log | cut -d= -f2 | sed "s/'//g")
945 local nexttest=$(egrep -s ^NEXTTEST= $LOGDIR/test.log | cut -d= -f2)
946
947 case "$FAI_LOGPROTO" in
948 ftp) remotesh=ssh ;;
949 ssh) remotesh=ssh ;;
950 rsh) remotesh=rsh ;;
951 esac
952 frsh="$remotesh -l $LOGUSER ${SERVER}"
953
954 if [ -z "$SERVER" ] ; then
955 echo "SERVER not defined. Can't change network boot configuration"
956 task_error 2
957 doexit=1
958 fi
959 [ $doexit -eq 1 ] && return
960
961 if dmesg | grep -q "Sending BOOTP requests"; then
962 # change boot device (local disk or network) when using bootp
963 [ "$LOGUSER" -a "$TFTPLINK" ] &&
964 $frsh "cd /srv/tftp/fai; rm -f $hostname; ln -s $TFTPLINK $hostname"
965 else
966 # change boot device (local disk or network) when using PXE
967 # first test if rsh to server works
968 $frsh true >/dev/null 2>&1
969 if [ $? -ne 0 ]; then
970 task_error 3
971 echo "WARNING: $frsh failed. Can't call fai-chboot on the install server."
972 else
973 if [ -n "$nexttest" ]; then
974 # for test sequences, we want the system to reinstall immediately with
975 # with different class setup
976 $frsh /usr/sbin/fai-chboot -k ADDCLASSES=$nexttest -FIv $ipaddr
977 else
978 # remove pxe config, so host will use default and boot from local disk
979 $frsh /usr/sbin/fai-chboot -vd $ipaddr
980 fi
981 fi
982 fi
983 }
984 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
985 sendmon() {
986
987 # send message to monitor daemon
988 [ "$faimond" -eq 0 ] && return 0
989 echo "$sendhostname $*" | nc -w 8 $monserver 4711 2>/dev/null
990 return $?
991 }
992 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5