/[fai]/trunk/lib/subroutines
ViewVC logotype

Contents of /trunk/lib/subroutines

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4677 - (show annotations) (download)
Sat Nov 10 13:55:48 2007 UTC (5 years, 6 months ago) by lange
File size: 15833 byte(s)
update FSF address (closes: #444154)
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-2007 by Thomas Lange, lange@informatik.uni-koeln.de
10 # Universitaet zu Koeln
11 #
12 #*********************************************************************
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2 of the License, or
16 # (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 # General Public License for more details.
22 #
23 # A copy of the GNU General Public License is available as
24 # `/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
25 # or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
26 # can also obtain it by writing to the Free Software Foundation, Inc.,
27 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28 #*********************************************************************
29
30 # source this file, then you have these function available in the shell
31
32 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33 die() {
34
35 # echo comment and exit installation
36 task_savelog
37 echo "$@"
38 if [ X$FAI_ACTION = Xinstall ]; then
39 exec bash -i
40 else
41 exit 99
42 fi
43 }
44 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
45 defnop() {
46
47 # define given list of subroutine names as dummy function;
48 # this will fake unknown commands
49
50 local name
51 for name in "$@";do
52 eval "$name () { :;}"
53 done
54 }
55 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
56 ### BEGIN SUBROUTINE INFO
57 # Provides-Var: none
58 # Required-Var: $classes
59 # Short-Description: test if class is defined
60 ### END SUBROUTINE INFO
61
62 ifclass() {
63
64 [ "$debug" ] && echo "Test if class $1 is in $classes" >&2
65 # test if a class is defined
66 local cl
67 local ret=1
68
69 for cl in $classes; do
70 [ x$cl = x$1 ] && ret=0 && break
71 done
72 [ "$debug" ] && echo "ifclass returns $ret" >&2
73 return $ret
74 }
75 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
76 rwmount() {
77
78 # remount partition read/write
79 mount -o rw,remount $1
80 }
81 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
82 save_dmesg() {
83
84 dmesg > $LOGDIR/dmesg.log
85 }
86 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
87 wait_for_jobs() {
88
89 # can be an extern script
90 # wait for running (background) jobs to finish (e.g. update-auctex-elisp)
91 local i=0
92 while jobsrunning; do
93 [ $(($i % 3)) -eq 0 ] && echo "Waiting for background jobs to finish."
94 (( i += 1 ))
95 sleep 10
96 done
97 }
98 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
99 ### BEGIN SUBROUTINE INFO
100 # Provides-Var: $task_error
101 # Required-Var: $LOGDIR
102 # Short-Description: call a certain task
103 ### END SUBROUTINE INFO
104
105 task() {
106
107 # hooks are called before a task is called
108 # if a task is skipped, also its hooks are skipped
109 # a hook can set the flag, so the accociated task is skipped
110
111 local taskname=$1
112
113 [ -f $LOGDIR/skip.$taskname ] || call_hook $taskname
114
115 if [ -f $LOGDIR/skip.$taskname ]; then
116 # skip task
117 rm $LOGDIR/skip.$taskname # TODO: remove skip files at the very end
118 [ "$verbose" ] && echo "Skiping task_$taskname"
119 sendmon "TASKSKIP $taskname"
120 else
121 echo "Calling task_$taskname"
122 sendmon "TASKBEGIN $taskname"
123 task_error=0 # task can set this variable to indicate an error
124 task_$taskname
125 sendmon "TASKEND $taskname $task_error"
126 fi
127 # since the subroutine is not needed any more, we can undefine it
128 unset task_$taskname
129 }
130 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
131 ### BEGIN SUBROUTINE INFO
132 # Provides-Var:
133 # Required-Var: $classes $debug
134 # Short-Description: call a hook, hook.source can define additional variables
135 ### END SUBROUTINE INFO
136
137 call_hook() {
138
139 local hook=$1
140 local cl dflag hfile
141 [ "$debug" ] && dflag="-d"
142
143 for cl in $classes; do
144 hfile=$FAI/hooks/$hook.$cl
145 if [ -f $hfile -a ! -x $hfile ]; then
146 echo "WARNING: Skipping $hfile execustion because it's not executable."
147 continue
148 fi
149 if [ -f $hfile.source -a ! -x $hfile.source ]; then
150 echo "WARNING: Skipping $hfile.source execustion because it's not executable."
151 continue
152 fi
153 if [ -x $hfile ]; then
154 echo "Calling hook: $hook.$cl"
155 sendmon "HOOK $hook.$cl"
156 # execute the hook
157 $hfile $dflag
158 check_status $hook.$cl $?
159 fi
160 if [ -x $hfile.source ]; then
161 echo "Source hook: $hook.$cl.source"
162 sendmon "HOOK $hook.$cl.source"
163 # source this hook
164 . $hfile.source $dflag
165 check_status $hook.$cl.source $?
166 fi
167 done
168 }
169 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
170 skiptask() {
171
172 # mark all given tasks, so they will be skipped
173 local task
174
175 for task in "$@"; do
176 > $LOGDIR/skip.$task
177 done
178 }
179 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
180 define_fai_flags() {
181
182 local flag
183 # FAI_FLAGS are comma separated, define all flags
184 FAI_FLAGS=${FAI_FLAGS//,/ }
185 echo "FAI_FLAGS: $FAI_FLAGS"
186 for flag in $FAI_FLAGS; do
187 # define this flag as 1
188 eval "flag_$flag=1"
189 done
190 [ "$flag_verbose" ] && verbose=1 # for backward compability
191 [ "$flag_debug" ] && debug=1 # for backward compability
192 }
193 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
194 ### BEGIN SUBROUTINE INFO
195 # Provides-Var: $fai_rundate
196 # Requires-Var: $DOMAIN $do_init_tasks
197 # Suggests-Var: $flag_createvt $flag_sshd
198 # Short-Description: <task desc.>
199 ### END SUBROUTINE INFO
200
201 task_setup() {
202
203 # source user specific subroutines
204 [ -f $FAI/hooks/subroutines ] && . $FAI/hooks/subroutines
205
206 if [ -f /boot/RUNNING_FROM_FAICD ]; then
207 local cdrom=$(mount| awk '/dev.+on \/ /{print $1}')
208 hdparm -d $cdrom | grep -q off 2>/dev/null
209 if [ $? -eq 0 ]; then
210 echo "WARNING: CD-ROM does not use DMA mode. The installation will be sloooow."
211 fi
212 fi
213
214 define_fai_flags
215
216 # this may be moved to an external script
217 if [ $do_init_tasks -eq 1 ] ; then
218 # set the system time and date using rdate or/and ntpdate
219 [ "$TIMESRVS_1" ] && rdate $TIMESRVS_1
220 [ "$NTPSRVS_1" ] && ntpdate -b $NTPSRVS
221 [ "$flag_createvt" ] && {
222 # create two virtual terminals; acces via alt-F2 and alt-F3
223 echo "Press ctrl-c to interrupt FAI and to get a shell"
224 openvt -c2 /bin/bash ; openvt -c3 /bin/bash
225 trap 'echo "You can reboot with faireboot";bash' INT QUIT
226 }
227
228 # start secure shell daemon for remote access
229 [ "$flag_sshd" -a -x /usr/sbin/sshd ] && /usr/sbin/sshd
230 fi
231 unset flag_createvt flag_sshd
232
233 # when did FAI start, using localtime
234 fai_rundate=$(date +'%Y%m%d_%H%M%S')
235 }
236 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
237 ### BEGIN SUBROUTINE INFO
238 # Provides-Var: none
239 # Requires-Var: $FAI_ACTION
240 # Short-Description: call task depending on $FAI_ACTION
241 ### END SUBROUTINE INFO
242
243 task_action() {
244
245 if [ -z "$FAI_ACTION" ]; then
246 echo "No action in \$FAI_ACTION defined."
247 sendmon "TASKERROR action 21"
248 task_faiend
249 exit
250 fi
251 echo "FAI_ACTION: $FAI_ACTION"
252 case $FAI_ACTION in
253
254 install)
255 if [ $do_init_tasks -eq 0 ]; then
256 echo "Cowardly refusing to run a FAI installation on a running system."
257 return
258 fi
259 echo Performing FAI installation. All data may be overwritten!
260 echo -ne "\a"; sleep 1
261 echo -ne "\a"; sleep 1
262 echo -e "\a"; sleep 5
263 task install
264 task faiend
265 ;;
266 dirinstall)
267 task dirinstall
268 ;;
269 softupdate)
270 echo Performing FAI system update. All data may be overwritten!
271 task softupdate
272 ;;
273 sysinfo)
274 echo Showing system information.
275 task sysinfo
276 task_faiend
277 die Now you have a shell.
278 ;;
279 *)
280 if [ -f $FAI/hooks/$FAI_ACTION ]; then
281 echo "Calling user defined action: $FAI_ACTION"
282 $FAI/hooks/$FAI_ACTION
283 else
284 echo "ERROR: User defined action $FAI/hooks/$FAI_ACTION not found."
285 sendmon "TASKERROR action 22"
286 task_faiend
287 fi
288 ;;
289 esac
290 }
291 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
292 ### BEGIN SUBROUTINE INFO
293 # Provides-Var: $classes $cfclasses
294 # Requires-Var: $LOGDIR
295 # Suggests-Var: $renewclass
296 # Short-Description: <task desc.>
297 ### END SUBROUTINE INFO
298
299 task_defclass() {
300
301 if [ ! -d $FAI/class ]; then
302 sendmon "TASKERROR defclass 21"
303 echo "Directory $FAI/class not found. Following subdirectories are found:"
304 find $FAI -maxdepth 1 -type d -printf "%p\n"
305 die "Aborting."
306 fi
307
308 # new script for defining classes; variables imported: $LOGDIR, $verbose, $debug
309 if [ $renewclass -eq 1 ]; then
310 # reevaluate new list of classes
311 fai-class -T $FAI/class $LOGDIR/FAI_CLASSES
312 classes=$(< $LOGDIR/FAI_CLASSES)
313 elif [ -n "$cmdlineclasses" ]; then
314 classes=$cmdlineclasses
315 elif [ ! -f /var/lib/fai/FAI_CLASSES ]; then
316 # use classes defined at installation time
317 die "Try to read classes from /var/lib/fai/FAI_CLASSES. Failed. Aborting."
318 else
319 classes=$(< /var/lib/fai/FAI_CLASSES)
320 fi
321 echo "List of all classes: " $classes
322
323 # define classes as: a.b.c.d for cfengine -D
324 # this doesn't work without echo
325 cfclasses=$(echo $classes)
326 cfclasses=${cfclasses// /.}
327 [ "$debug" ] && echo "cfclasses: $cfclasses"
328 }
329 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
330 _defvar() {
331
332 local showvar=1 # TODO: new FAI_FLAG or always set when verbose is used
333 [ "$showvar" ] && set -x
334 . $1 </dev/null
335 [ "$showvar" ] && set +x
336 }
337 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
338 task_defvar() {
339
340 local svar=$LOGDIR/showvar.log
341 local odir=$(pwd)
342 cd $FAI/class
343 for class in $classes ; do
344 if [ -f $class.var ]; then
345 [ "$verbose" ] && echo "Executing $class.var"
346 # show only lines with ++, we cannot use a pipe, since it would call
347 # _devfar in a subprocess. Then, variables are not defined
348 _defvar $class.var > $svar 2>&1
349 grep ^++ $svar
350 rm $svar
351 fi
352 done
353
354 # /fai/class/S* scripts or hooks can write variable definitions
355 # to additonal.var. now source these definitions
356 if [ -f $LOGDIR/additional.var ]; then
357 _defvar $LOGDIR/additional.var > $svar 2>&1
358 grep ^++ $svar
359 rm $svar
360 fi
361 unset class svar
362 # now all variables are defined. Dump them to variables.log
363 set | perl -ne 'print if /^\w\w+=/ and not /^(BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID|rootpw|ROOTPW|HOME|PWD)/' > $LOGDIR/variables.log
364 cd $odir
365 }
366 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
367 task_mountdisks() {
368
369 [ ! -f $LOGDIR/fstab ] && die "No $LOGDIR/fstab created."
370 # mount swap space
371 local sd
372 for sd in $SWAPLIST; do
373 swapon -p1 $sd && [ "$verbose" ] && echo "Enable swap device $sd"
374 done
375 mount2dir $FAI_ROOT $LOGDIR/fstab
376 }
377 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
378 task_configure() {
379
380 fai-do-scripts $FAI/scripts
381 }
382 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
383 task_savelog() {
384
385 mkdir -p $FAI_ROOT/var/lib/fai
386 mkdir -p $FAI_ROOT/var/log/fai
387 fai-savelog -l
388 [ -f $LOGDIR/FAI_CLASSES ] && cp -pu $LOGDIR/FAI_CLASSES $FAI_ROOT/var/lib/fai
389 [ -f $LOGDIR/disk_var.sh ] && cp -pu $LOGDIR/disk_var.sh $FAI_ROOT/var/lib/fai
390 fai-savelog -r
391 }
392 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
393 task_faiend() {
394
395 local dir cdromdevice
396 [ $do_init_tasks -eq 0 ] && exit 0
397 wait_for_jobs
398 echo "Press <RETURN> to reboot."
399 [ -z "$flag_reboot" ] && : ${flag_reboot:=0}
400 [ -s $LOGDIR/error.log -a "$flag_reboot" -gt "0" ] && sleep 10
401 # reboot without prompting if FAI_FLAG reboot is set
402 [ "$flag_reboot" -lt "1" ] && read
403 echo "Rebooting $HOSTNAME now"
404 sendmon "TASKEND REBOOT 0"
405 cd /
406 sync
407
408 killall -q sshd udevd
409 if [ -f /boot/RUNNING_FROM_FAICD ]; then
410 cat > $target/tmp/rebootCD <<'EOF'
411 #! /bin/bash
412 device=$1
413 eject -m /dev/$device 2>/dev/null >/dev/null
414 echo "Remove CDROM and press <RETURN> to continue reboot"
415 read
416 eject -t /dev/$device 2>/dev/null >/dev/null
417 exec reboot -df
418 EOF
419 chmod +x $target/tmp/rebootCD
420 sync
421 for dir in $(mount | grep $target | awk '{print $3}' | sort -r); do
422 mount -o remount,ro $dir
423 done
424 cdromdevice=$(awk '/ name:/ {print $3}' /proc/sys/dev/cdrom/info)
425 chroot $target /tmp/rebootCD $cdromdevice
426 # never reached, because chroot will reboot the machine
427 die "Internal error when calling /tmp/rebootCD."
428 fi
429 umount $FAI_ROOT/proc
430 umount -ar
431 exec reboot -dfi
432 }
433 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
434 task_install() {
435
436 > $stamp
437
438 save_dmesg
439
440 task partition
441 task mountdisks
442 task extrbase
443 task mirror
444 task debconf
445 task prepareapt
446 task updatebase
447 task instsoft
448 task configure
449 task finish
450 task chboot
451
452 rm -f $stamp
453 # save again, because new messages could be created
454 save_dmesg
455 task savelog
456
457 if [ -f $stamp ]; then
458 echo "Error while executing commands in subshell."
459 echo "$stamp was not removed."
460 sendmon "TASKERROR install 21"
461 die "Please look at the log files in $LOGDIR for errors."
462 fi
463 }
464 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
465 task_dirinstall() {
466
467 > $stamp
468
469 mkdir -p $FAI_ROOT
470 FAI_ROOT=$(cd $FAI_ROOT;pwd)
471 echo "Installing into directory $FAI_ROOT"
472 task extrbase
473 [ -f $target/etc/fstab ] || touch $target/etc/fstab
474 task mirror
475 task debconf
476 task prepareapt
477 task updatebase
478 task instsoft
479 task configure
480 task finish
481
482 rm -f $stamp
483 unset LOGUSER # so logfile are not saved to remote
484 task savelog
485
486 if [ -f $stamp ]; then
487 echo "Error while executing commands in subshell."
488 echo "$stamp was not removed."
489 sendmon "TASKERROR install 21"
490 die "Please look at the log files in $LOGDIR for errors."
491 fi
492 }
493 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
494 task_softupdate() {
495
496 local stamp=/var/run/fai/fai_softupdate_is_running
497
498 [ -f "$stamp" ] && die "Another fai softupdate is already running. Aborting."
499 > $stamp
500 # if the system had been installed using fai < 3.0 disk_var.sh is found in /etc/fai
501 if [ ! -f /var/lib/fai/disk_var.sh -a -f /etc/fai/disk_var.sh ] ; then
502 mv /etc/fai/disk_var.sh /var/lib/fai/
503 fi
504 # the following copy operation is required to make $LOGDIR a reliable source
505 # for disk_var.sh
506 # use the last disk_var during update if available
507 [ -f /var/lib/fai/disk_var.sh ] && cp -p /var/lib/fai/disk_var.sh $LOGDIR
508
509 defnop wait_for_jobs
510 save_dmesg
511
512 task mirror
513 task debconf
514 task updatebase
515 task instsoft
516 task configure
517 date
518 echo "The $FAI_ACTION took $[$(cut -d . -f 1 /proc/uptime)-$start_seconds] seconds."
519
520 rm -f $stamp
521 # save again, because new messages could be created
522 save_dmesg
523 task savelog
524
525 if [ -f $stamp ]; then
526 echo "Error while executing commands in subshell."
527 echo "$stamp was not removed."
528 sendmon "TASKERROR softupdate 21"
529 die "Please look at the log files in $LOGDIR for errors."
530 fi
531 echo $FAI_CONFIG_SRC | grep -q ^nfs://
532 if [ $? -eq 0 ]; then
533 grep -q ^$FAI /etc/mtab && umount $FAI
534 fi
535 }
536 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
537
538 catnc() {
539 # cat but no comment lines
540 egrep -v "^#" $@
541 }
542 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5