3 # Purpose: build process script for generating a (grml based) Linux Live-ISO
4 # Authors: grml-team (grml.org),
5 # (c) Michael Prokop <mika@grml.org>,
6 # (c) Thorsten Glaser <tg@mirbsd.org>
7 # Bug-Reports: see http://grml.org/bugs/
8 # License: This file is licensed under the GPL v2 or any later version.
9 ################################################################################
11 # some misc and global stuff {{{
15 # define function getfilesize before "set -e"
16 if stat --help >/dev/null 2>&1; then
17 getfilesize='stat -c %s' # GNU stat
19 getfilesize='stat -f %z' # BSD stat
23 # disable for now since it seems to cause some problems
27 GRML_LIVE_VERSION='0.17.0'
30 ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
33 # usage information {{{
37 $PN - build process script for generating a (grml based) Linux Live-ISO
39 Usage: $PN [options, see as follows]
41 -a <architecture> architecture; available values: i386 and amd64
42 -A ensure clean build and pack artifacts
43 -b build the ISO without updating the chroot via FAI
44 -B build the ISO without touching the chroot (skips cleanup)
45 -c <classe[s]> classes to be used for building the ISO via FAI
46 -C <configfile> configuration file for grml-live
47 -d <date> use specified date instead of build time as date of release
48 -D <configdir> use specified configuration directory instead of /etc/grml/fai
49 -F force execution without prompting
50 -g <grml_name> set the grml flavour name
51 -h display short usage information and exit
52 -i <iso_name> name of ISO
53 -I <src_directory> directory which provides files that should become
54 part of the chroot/ISO
55 -n skip generation of ISO
56 -N bootstrap (build chroot) only, do not create files for ISO
57 -o <output_directory> main output directory of the build process
59 -Q skip netboot package build
60 -r <release_name> release name
61 -s <suite> Debian suite; values: etch, lenny, squeeze, sid
62 -t <template_directory> place of the templates
63 -T <tar_name> unpack chroot tar archive before starting
64 -u update existing chroot instead of rebuilding it from scratch
65 -U <username> arrange output to be owned by specified username
66 -v <version_number> specify version number of the release
67 -V increase verbosity in the build process
68 -z use ZLIB instead of LZMA/XZ compression
73 $PN -c GRMLBASE,GRML_FULL,AMD64 -o /dev/shm/grml
74 $PN -c GRMLBASE,GRML_FULL,AMD64 -i grml_0.0-1.iso -v 0.0-1
75 $PN -c GRMLBASE,GRML_FULL,AMD64 -s sid -V -r 'grml-live rocks'
77 More details: man grml-live + /usr/share/doc/grml-live/grml-live.html
78 http://grml.org/grml-live/
80 Please send your bug reports and feedback to the grml-team: http://grml.org/bugs/
84 # make sure it's possible to get usage information without being
85 # root or actually executing the script
86 if [ "$1" = '-h' -o "$1" = '--help' ] ; then
88 [ "$(id -u 2>/dev/null)" != 0 ] && echo "Please notice that this script requires root permissions."
93 # some runtime checks {{{
94 # we need root permissions for the build-process:
95 if [ "$(id -u 2>/dev/null)" != 0 ] ; then
96 echo "Error: please run this script with uid 0 (root)." >&2
100 if [ -r /var/run/fai/FAI_INSTALLATION_IN_PROGRESS ] ; then
101 echo "/usr/sbin/fai already running or was aborted before.">&2
102 echo "You may remove /var/run/fai/FAI_INSTALLATION_IN_PROGRESS and try again.">&2
107 if [ -r /var/run/fai/fai_softupdate_is_running ] ; then
108 echo "/usr/sbin/fai softupdate already running or was aborted before.">&2
109 echo "You may remove /var/run/fai/fai_softupdate_is_running and try again.">&2
114 # lsb-functions and configuration stuff {{{
115 # make sure they are not set by default
124 # don't use colors/escape sequences
125 if [ -r /lib/lsb/init-functions ] ; then
126 . /lib/lsb/init-functions
127 ! log_use_fancy_output && NOCOLORS=true
130 if [ -r /etc/grml/lsb-functions ] ; then
131 . /etc/grml/lsb-functions
133 einfo() { echo " [*] $*" ;}
134 eerror() { echo " [!] $*">&2 ;}
135 ewarn() { echo " [x] $*" ;}
137 eindent() { return 0 ;}
138 eoutdent() { return 0 ;}
141 # source main configuration file:
142 LIVE_CONF=/etc/grml/grml-live.conf
146 # umount all directories {{{
148 # make sure we don't leave any mounts - FAI doesn't remove them always
149 umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
150 umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true
151 umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
152 umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
154 # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry
155 if [ -x /usr/lib/fai/mkramdisk ] ; then
156 /usr/lib/fai/mkramdisk -u "$(readlink -f ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true
159 umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true
160 [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
166 rm -f /var/run/fai/fai_softupdate_is_running \
167 /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
168 [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR"
170 [ -n "$1" ] && EXIT="$1" || EXIT="1"
171 [ -n "$2" ] && eerror "$2">&2
172 if [ -n "$PACK_ARTIFACTS" ]; then
175 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
176 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
179 if [ -n "$CHOWN_USER" ]; then
180 log "Setting ownership"
181 einfo "Setting ownership"
182 [ -n "${OUTPUT}" -a -d "${OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${OUTPUT}"
183 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${BUILD_OUTPUT}"
184 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}"
185 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}"
186 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}"
187 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && chown -R "${CHOWN_USER}:" "${NETBOOT}"
188 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_ARCHIVE}"
191 log "------------------------------------------------------------------------------"
194 trap bailout 1 2 3 3 6 9 14 15
198 # some important functions {{{
201 # usage: log "string to log"
202 log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; }
204 # cut string at character number int = $1
205 # usage: cut_string 5 "1234567890" will output "12345"
207 [ -n "$2" ] || return 1
208 echo "$2" | head -c "$1"; echo -ne "\n"
211 # prepend int = $1 spaces before string = $2
212 # usage: extend_string_begin 5 "123" will output " 123"
213 extend_string_begin() {
214 [ -n "$2" ] || return 1
215 local COUNT="$(echo $2 | wc -c)"
216 local FILL="$(expr $COUNT - $1)"
217 while [ "$FILL" -gt 1 ] ; do
219 local FILL=$(expr $FILL - 1)
221 while [ "$FILL" -lt 1 ] ; do
223 local FILL=$(expr $FILL + 1)
225 echo "$2" | head -c "$1"; echo -ne "\n"
228 # append int = $1 spaces to string = $2
229 # usage: extend_string_begin 5 "123" will output "123 "
230 extend_string_end() {
231 [ -n "$2" ] || return 1
232 echo -n "$2" | head -c "$1"
233 local COUNT="$(echo $2 | wc -c)"
234 local FILL="$(expr $COUNT - $1)"
235 while [ "$FILL" -gt 1 ] ; do
237 local FILL=$(expr $FILL - 1)
239 while [ "$FILL" -lt 1 ] ; do
241 local FILL=$(expr $FILL + 1)
246 # Copy addonfile $1 from either
247 # * the chroot (via $2, the system path),
248 # * or from TEMPLATE_DIRECTORY/compat (if exists),
249 # * or from the host system (again, using $2),
250 # or warn about the missing file.
253 # * We assume that the chroot always has a "good" version of
254 # the file. Also it makes sources handling easier.
255 # * On unstable, we Recommend the Debian packages containing
256 # these files. The user can override them by putting his
257 # "better" version into the chroot.
258 # * On stable, the Debian packages are probably not available,
259 # or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
260 # our grml-live-compat package installs current file versions.
262 DEST="${BUILD_OUTPUT}/boot/$3"
263 if [ ! -d "${DEST}/" ]; then
266 if [ -e "$CHROOT_OUTPUT/$2/$1" ]; then
267 log "Copying $1 from chroot"
268 cp "$CHROOT_OUTPUT/$2/$1" "${DEST}/"
271 if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
272 log "Copying $1 from grml-live-compat"
273 cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
276 if [ -e "$2/$1" ]; then
277 log "Copying $1 from system"
278 cp "$2/$1" "${DEST}/"
282 msg="Missing addon file: \"$1\""
283 ewarn "$msg" ; eend 1
284 log "copy_addon_file: $msg"
288 # command line parsing {{{
289 while getopts "a:C:c:d:D:g:i:I:o:r:s:t:T:U:v:AbBFnNqQuVz" opt; do
292 A) PACK_ARTIFACTS=1 ;;
295 c) CLASSES="$OPTARG" ;;
296 C) GRML_LIVE_LOCAL_CONFIG="$OPTARG" ;;
298 D) GRML_FAI_CONFIG="$OPTARG" ;;
299 g) GRML_NAME="$OPTARG" ;;
300 i) ISO_NAME="$OPTARG" ;;
301 I) CHROOT_INSTALL="$OPTARG" ;;
303 N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;;
304 o) OUTPUT="$OPTARG" ;;
305 q) SKIP_MKSQUASHFS=1 ;;
307 r) RELEASENAME="$OPTARG" ;;
308 s) SUITE="$OPTARG" ;;
309 t) TEMPLATE_DIRECTORY="$OPTARG";;
310 T) UNPACK_CHROOT="$(readlink -f $OPTARG)" ;;
311 v) VERSION="$OPTARG" ;;
314 U) CHOWN_USER="$OPTARG" ;;
316 z) SQUASHFS_ZLIB=1 ;;
317 ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
320 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
323 # read local (non-packaged) configuration {{{
324 if [ -z "$GRML_LIVE_LOCAL_CONFIG" ]; then
325 if [ -r "/etc/grml/grml-live.local" ]; then
326 GRML_LIVE_LOCAL_CONFIG="/etc/grml/grml-live.local"
329 if [ -n "$GRML_LIVE_LOCAL_CONFIG" ]; then
330 if [ -r "$GRML_LIVE_LOCAL_CONFIG" ]; then
331 . $GRML_LIVE_LOCAL_CONFIG
333 eerror "Could not read specified local configuration file \"$GRML_LIVE_LOCAL_CONFIG\"."
336 GRML_LIVE_LOCAL_CONFIG=$(readlink -f "$GRML_LIVE_LOCAL_CONFIG")
338 GRML_LIVE_LOCAL_CONFIG=''
341 if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
342 eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated."
343 ewarn "Please set up \${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead."
348 # assume sane defaults (if not set already) {{{
349 [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
350 [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
351 [ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_FULL,$(echo ${ARCH} | tr 'a-z' 'A-Z')"
352 [ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)"
353 [ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators '
354 [ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
355 [ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
356 [ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
357 [ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
358 [ -n "$GRML_NAME" ] || GRML_NAME='grml'
359 [ -n "$HOSTNAME" ] || HOSTNAME='grml'
360 [ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='manifold'
361 [ -n "$NFSROOT_CONF" ] || NFSROOT_CONF="${GRML_FAI_CONFIG}/make-fai-nfsroot.conf"
362 [ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
363 [ -n "$SQUASHFS_EXCLUDES_FILE" ] || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
364 [ -n "$SUITE" ] || SUITE='squeeze'
365 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
366 [ -n "$USERNAME" ] || USERNAME='grml'
367 [ -n "$VERSION" ] || VERSION='0.0.1'
369 # output specific stuff, depends on $OUTPUT (iff not set):
370 [ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live'
371 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
372 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
373 [ -n "$CHROOT_ARCHIVE" ] || CHROOT_ARCHIVE="$OUTPUT/$(basename $CHROOT_OUTPUT).tgz"
374 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
375 [ -n "$LOG_OUTPUT" ] || LOG_OUTPUT="$OUTPUT/grml_logs"
376 [ -n "$REPORTS" ] || REPORTS="${LOG_OUTPUT}/reports/"
377 [ -n "$NETBOOT" ] || NETBOOT="${OUTPUT}/netboot/"
380 # some misc checks before executing FAI {{{
381 [ -n "$CLASSES" ] || bailout 1 "Error: \$CLASSES unset, please set it in $LIVE_CONF or
382 specify it on the command line using the -c option."
383 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
384 specify it on the command line using the -o option."
386 # trim characters that are known to cause problems inside $GRML_NAME;
387 # for example isolinux does not like '-' inside the directory name
388 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
390 # export variables to have them available in fai scripts:
391 [ -n "$GRML_NAME" ] && export GRML_NAME="$GRML_NAME"
392 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
395 # ZERO_LOGFILE - check for backwards compatibility reasons {{{
396 # this was default behaviour until grml-live 0.9.34:
397 if [ -n "$ZERO_LOGFILE" ] ; then
398 PRESERVE_LOGFILE='' # make sure it's cleaned then
399 ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
400 ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
405 # ask user whether the setup is ok {{{
406 if [ -z "$FORCE" ] ; then
408 echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
410 echo " FAI classes: $CLASSES"
411 [ -n "$GRML_LIVE_LOCAL_CONFIG" ] && echo " Configuration: $GRML_LIVE_LOCAL_CONFIG"
412 [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG"
413 echo " main directory: $OUTPUT"
414 [ -n "$UNPACK_CHROOT" ] && echo " Chroot from: $UNPACK_CHROOT"
415 [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT"
416 [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT"
417 [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT"
418 [ -n "$GRML_NAME" ] && echo " Grml name: $GRML_NAME"
419 [ -n "$RELEASENAME" ] && echo " Release name: $RELEASENAME"
420 [ -n "$DATE" ] && echo " Build date: $DATE"
421 [ -n "$VERSION" ] && echo " Grml version: $VERSION"
422 [ -n "$SUITE" ] && echo " Debian suite: $SUITE"
423 [ -n "$ARCH" ] && echo " Architecture: $ARCH"
424 [ -n "$BOOT_METHOD" ] && echo " Boot method: $BOOT_METHOD"
425 [ -n "$HYBRID_METHOD" ] && echo " Hybrid method: $HYBRID_METHOD"
426 [ -n "$TEMPLATE_DIRECTORY" ] && echo " Template files: $TEMPLATE_DIRECTORY"
427 [ -n "$CHROOT_INSTALL" ] && echo " Install files from directory to chroot: $CHROOT_INSTALL"
428 [ -n "$BOOTID" ] && echo " Boot identifier: $BOOTID"
429 [ -n "$NO_BOOTID" ] && echo " Skipping bootid feature."
430 [ -n "$CHOWN_USER" ] && echo " Output owner: $CHOWN_USER"
431 [ -n "$DEFAULT_BOOTOPTIONS" ] && echo " Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
432 [ -n "$FAI_ARGS" ] && echo " Additional arguments for FAI: $FAI_ARGS"
433 [ -n "$LOGFILE" ] && echo " Logging to file: $LOGFILE"
434 [ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA/XZ) compression."
435 [ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
436 [ -n "$VERBOSE" ] && echo " Using VERBOSE mode."
437 [ -n "$PACK_ARTIFACTS" ] && echo " Will prepare packed artifacts and ensure clean build."
438 [ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation."
439 if [ -n "$BOOTSTRAP_ONLY" ] ; then
440 echo " Bootstrapping only and not building (files for) ISO."
442 [ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file."
443 [ -n "$SKIP_NETBOOT" ] && echo " Skipping creation of NETBOOT package."
444 [ -n "$SKIP_MKISOFS" ] && echo " Skipping creation of ISO file."
445 [ -n "$BUILD_ONLY" ] && echo " Executing BUILD_ONLY instead of fresh installation or UPDATE."
446 [ -n "$BUILD_DIRTY" ] && echo " Executing BUILD_DIRTY to leave chroot untouched."
449 echo -n "Is this ok for you? [y/N] "
451 if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
452 bailout 1 "Exiting as requested."
458 # clean up before start {{{
459 if [ -n "${PACK_ARTIFACTS}" ]; then
460 echo "Wiping old artifacts"
461 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
462 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
463 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && rm -r "${ISO_OUTPUT}"
464 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && rm -r "${LOG_OUTPUT}"
465 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && rm -r "${NETBOOT}"
469 # create log file {{{
470 [ -n "$LOGFILE" ] || LOGFILE=${LOG_OUTPUT}/grml-live.log
471 mkdir -p $(dirname "${LOGFILE}")
473 chown root:adm $LOGFILE
477 # clean/zero/remove logfiles {{{
479 if [ -n "$PRESERVE_LOGFILE" ] ; then
480 echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
482 # make sure it is empty (as it is e.g. appended to grml-live-db)
486 if [ -n "$ZERO_FAI_LOGFILE" ] ; then
487 if [ -d /var/log/fai/"$HOSTNAME" ] ; then
488 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
489 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
490 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
491 rm -f /var/log/fai/"$HOSTNAME"/last \
492 /var/log/fai/"$HOSTNAME"/last-dirinstall \
493 /var/log/fai/"$HOSTNAME"/last-softupdate
498 # source config and startup {{{
499 if [ -n "$CONFIG" ] ; then
500 if ! [ -f "$CONFIG" ] ; then
501 log "Error: $CONFIG could not be read. Exiting. [$(date)]"
502 eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
505 log "Sourcing $CONFIG"
510 start_seconds=$(cut -d . -f 1 /proc/uptime)
511 log "------------------------------------------------------------------------------"
512 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
513 log "Using local config file: $GRML_LIVE_LOCAL_CONFIG"
514 log "Executed grml-live command line:"
517 einfo "Logging actions to logfile $LOGFILE"
521 if [ -n "${UNPACK_CHROOT}" ]; then
522 log "Unpacking chroot from ${UNPACK_CHROOT}"
523 einfo "Unpacking chroot from ${UNPACK_CHROOT}"
524 [ -d "$CHROOT_OUTPUT" ] || mkdir -p "${CHROOT_OUTPUT}"
525 tar -xf "${UNPACK_CHROOT}" -C "${CHROOT_OUTPUT}/" --strip-components 1 ; RC=$?
526 if [ "$RC" != 0 ] ; then
534 # cleanup CHROOT_ARCHIVE now {{{
535 if [ -n "${PACK_ARTIFACTS}" ]; then
536 # can't do this earlier, as UNPACK_CHROOT might point to CHROOT_ARCHIVE
537 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}"
541 # on-the-fly configuration {{{
542 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
543 sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
546 # does this suck? YES!
547 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
549 unstable) SUITE='sid' ; CLASSES="DEBIAN_UNSTABLE,$CLASSES" ;;
550 *) CLASSES="DEBIAN_$(echo $SUITE | tr 'a-z' 'A-Z'),$CLASSES";;
552 export SUITE # make sure it's available in FAI scripts
554 for file in "$LIVE_CONF" "$GRML_LIVE_LOCAL_CONFIG" "$NFSROOT_CONF" ; do
555 if [ -n "$file" ] ; then
556 sed "s|^FAI_DEBOOTSTRAP=\"[a-z]* |FAI_DEBOOTSTRAP=\"$SUITE |" "$file" | sponge "$file"
560 # validate whether the specified architecture class matches the
561 # architecture (option), otherwise installation of kernel will fail
562 if echo $CLASSES | grep -qi i386 ; then
563 if ! [[ "$ARCH" == "i386" ]] ; then
564 log "Error: You specified the I386 class but are trying to build something else (AMD64?)."
565 eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
566 eerror "Tip: Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
570 elif echo $CLASSES | grep -qi amd64 ; then
571 if ! [[ "$ARCH" == "amd64" ]] ; then
572 log "Error: You specified the AMD64 class but are trying to build something else (I386?)."
573 eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
574 eerror "Tip: Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
580 if grep -q -- 'FAI_DEBOOTSTRAP_OPTS.*--arch' "$NFSROOT_CONF" ; then
581 sed "s/--arch [a-z0-9]* /--arch $ARCH /" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
583 sed "s|^FAI_DEBOOTSTRAP_OPTS=\"\(.*\)|FAI_DEBOOTSTRAP_OPTS=\"--arch $ARCH \1|" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
587 # CHROOT_OUTPUT - execute FAI {{{
588 if [ -n "$BUILD_DIRTY" ]; then
589 log "Skipping stage 'fai' as requested via option -B"
590 ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
592 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
594 # provide inform fai about the ISO we build
595 [ -d "$CHROOT_OUTPUT/etc/" ] || mkdir -p "$CHROOT_OUTPUT/etc/"
596 echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
597 [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
598 [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
600 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
601 FAI_ACTION=softupdate
603 FAI_ACTION=dirinstall
606 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
607 if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
608 log "Error: does not look like you have a working chroot. Updating/building not possible."
609 eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
615 if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
616 log "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
617 ewarn "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
619 mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
621 if [ -n "${MIRROR_DIRECTORY}" ] ; then
622 mkdir -p "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
623 mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
626 mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
627 mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
629 # tell dpkg to use "unsafe io" during the build
630 [ -d "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d" ] || mkdir -p "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d"
631 echo force-unsafe-io > "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
633 log "Executed FAI command line:"
634 log "BUILD_ONLY=$BUILD_ONLY BOOTSTRAP_ONLY=$BOOTSTRAP_ONLY GRML_LIVE_LOCAL_CONFIG=$GRML_LIVE_LOCAL_CONFIG fai $VERBOSE -C $GRML_FAI_CONFIG -s file:///$GRML_FAI_CONFIG/config -c$CLASSES -u $HOSTNAME $FAI_ACTION $CHROOT_OUTPUT $FAI_ARGS"
635 BUILD_ONLY="$BUILD_ONLY" BOOTSTRAP_ONLY="$BOOTSTRAP_ONLY" GRML_LIVE_LOCAL_CONFIG="$GRML_LIVE_LOCAL_CONFIG" fai $VERBOSE \
636 -C "$GRML_FAI_CONFIG" -s "file:///$GRML_FAI_CONFIG/config" -c"$CLASSES" \
637 -u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
638 RC="$PIPESTATUS" # notice: bash-only
640 rm -f "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
642 FORCE_ISO_REBUILD=true
644 if [ "$RC" != 0 ] ; then
645 log "Error: critical error while executing fai [exit code ${RC}]. Exiting."
646 eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
649 einfo "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
650 log "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
651 echo "$GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]" > $CHROOT_OUTPUT/etc/grml_version
652 chmod 644 $CHROOT_OUTPUT/etc/grml_version
653 einfo "Rebuilding initramfs"
654 # make sure new /etc/grml_version reaches initramfs, iterate over all
655 # present kernel versions (note: we can't really handle more than one
656 # kernel version anyway right now)
657 # chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :(
658 for initrd in "$(basename $CHROOT_OUTPUT/boot/vmlinuz-*)" ; do
659 if ! chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -c ; then
660 einfo "Creating fresh initrd did not work, trying update instead:"
661 log "Creating fresh initrd did not work, trying update instead:"
662 chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -u
668 # move fai logs into grml_logs directory
669 mkdir -p "$LOG_OUTPUT"/fai/
670 cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
671 rm -rf "$CHROOT_OUTPUT"/var/log/fai
672 # copy fai package list
673 cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/
675 chown root:adm "$LOG_OUTPUT"/fai/*
676 chmod 664 "$LOG_OUTPUT"/fai/*
680 # notice: 'fai dirinstall' does not seem to exit appropriate, so:
682 CHECKLOG="$LOG_OUTPUT"/fai/
683 if [ -r "$CHECKLOG/software.log" ] ; then
684 # 1 errors during executing of commands
685 grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1
686 grep 'E: Method http has died unexpectedly!' $CHECKLOG/software.log >> $LOGFILE && ERROR=2
687 grep 'ERROR: chroot' $CHECKLOG/software.log >> $LOGFILE && ERROR=3
688 grep 'E: Failed to fetch' $CHECKLOG/software.log >> $LOGFILE && ERROR=4
689 grep 'Unable to write mmap - msync (28 No space left on device)' $CHECKLOG/software.log >> $LOGFILE && ERROR=5
692 if [ -r "$CHECKLOG/shell.log" ] ; then
693 grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=6
696 if [ -n "$ERROR" ] ; then
697 log "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
698 eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
699 eerror "Note: check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
703 log "Finished execution of stage 'fai dirinstall' [$(date)]"
704 einfo "Finished execution of stage 'fai dirinstall'"
710 # package validator {{{
711 CHECKLOG=/var/log/fai/$HOSTNAME/last
712 if [ -r "$CHECKLOG/dpkg.selections" ] ; then
713 package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}')
715 package_count="unknown"
719 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
721 # check for missing packages
722 if ! [ -s "$CHECKLOG/package_errors.log" ] ; then
723 einfo "No missing packages found, generating empty junit report."
725 cat > "${REPORT_MISSING_PACKAGES}" << EOF
726 <?xml version="1.0" encoding="UTF-8"?>
727 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="0" errors="0" skipped="0" assertions="0">
728 <testcase name="test_missing_packages" time="0" assertions="0">
738 einfo "Missing packages found, generating junit report."
740 if [ -r "$CHECKLOG/package_errors.log" ] ; then
741 package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}')
743 package_errors="unknown"
747 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
749 cat > "${REPORT_MISSING_PACKAGES}" << EOF
750 <?xml version="1.0" encoding="UTF-8"?>
751 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
754 for package in $(awk '{print $5}' "${CHECKLOG}/package_errors.log" | sed 's/\.$//') ; do
755 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
756 <testcase name="test_missing_packages_${package}" time="0" assertions="0">
757 <failure type="RuntimeError" message="Package ${package} is missing">
758 Package $package is missing in chroot
764 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
773 if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
774 eerror "The following packages were requested for installation but could not be processed:"
775 cat "$CHECKLOG/package_errors.log"
776 eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
780 ewarn "The following packages were requested for installation but could not be processed:"
781 cat "$CHECKLOG/package_errors.log"
787 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
788 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
789 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
792 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
793 if [ -n "$BOOTSTRAP_ONLY" ] ; then
794 log "Skipping stage 'boot' as building with bootstrap only."
795 ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
797 if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
798 log "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
799 ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
802 [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
803 [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
805 # if we don't have an initrd we a) can't boot and b) there was an error
806 # during build, so check for the file:
807 INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
808 if [ -n "$INITRD" ] ; then
809 cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
810 find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
812 log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
813 eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
817 KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
818 if [ -n "$KERNEL_IMAGE" ] ; then
819 cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/linux26
821 log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
822 eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
826 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
827 if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
828 log "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
829 eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
833 # copy _required_ isolinux files
834 for file in ifcpu64.c32 isolinux.bin vesamenu.c32; do
835 copy_addon_file "${file}" /usr/lib/syslinux isolinux
838 # *always* copy files to output directory so the variables
839 # get adjusted according to the build.
840 cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
842 if [ -n "$NO_ADDONS" ] ; then
843 log "Skipping installation of boot addons as requested via \$NO_ADDONS."
844 einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
846 if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
847 log "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
848 ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
850 # copy addons from system packages or grml-live-compat
851 copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
852 copy_addon_file pci.ids /usr/share/misc addons
853 copy_addon_file memtest86+.bin /boot addons
854 for file in memdisk chain.c32 hdt.c32 menu.c32; do
855 copy_addon_file "${file}" /usr/lib/syslinux addons
858 # make memtest filename FAT16/8.3 compatible
859 mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
860 "${BUILD_OUTPUT}/boot/addons/memtest"
862 # copy only files so we can handle bsd4grml on its own
863 for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
864 test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
867 if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
868 log "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
869 einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
871 if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
872 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
874 log "Missing addon file: bsd4grml"
875 ewarn "Missing addon file: bsd4grml" ; eend 0
879 fi # no "$TEMPLATE_DIRECTORY"/boot/addons
882 if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
883 mkdir -p "${BUILD_OUTPUT}/boot/grub"
885 cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
887 # copy grub files from target
888 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/
889 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/
890 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/
891 cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
892 cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
894 if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
895 log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
896 eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
900 [ -d "$BUILD_OUTPUT"/GRML ] || mkdir "$BUILD_OUTPUT"/GRML
901 cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/
903 # adjust boot splash information:
904 RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
905 RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
906 RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
908 if [ -r "$BUILD_OUTPUT"/GRML/grml-version ] ; then
909 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
910 sed -i "s/%DATE%/$DATE/" "$BUILD_OUTPUT"/GRML/grml-version
913 # make sure the squashfs filename is set accordingly:
914 SQUASHFS_NAME="$GRML_NAME.squashfs"
916 if [ -n "$NO_BOOTID" ] ; then
917 log 'Skipping bootid feature as requested via $NO_BOOTID.'
918 einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
920 [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
921 [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
922 einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
923 log "Generating /conf/bootid.txt with entry ${BOOTID}."
924 echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
928 # adjust all variables in the templates with the according distribution information
929 for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
930 "${BUILD_OUTPUT}"/boot/grub/* ; do
931 if [ -r "${file}" ] ; then
932 sed -i "s/%ARCH%/$ARCH/g" "${file}"
933 sed -i "s/%DATE%/$DATE/g" "${file}"
934 sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g" "${file}"
935 sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g" "${file}"
936 sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g" "${file}"
937 sed -i "s/%GRML_NAME%/$GRML_NAME/g" "${file}"
938 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g" "${file}"
939 sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g" "${file}"
940 sed -i "s/%SHORT_NAME%/$SHORT_NAME/g" "${file}"
941 sed -i "s/%VERSION%/$VERSION/g" "${file}"
943 [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s/ boot=live/ boot=live $DEFAULT_BOOTOPTIONS/" "${file}"
945 if [ -n "$NO_BOOTID" ] ; then
946 sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
948 sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
953 # adjust bootsplash accordingly but make sure the string has the according lenght
954 SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
955 SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
956 for file in f4 f5 ; do
957 if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
958 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
959 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
963 # generate addon list
964 rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
965 for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
966 include_name=$(basename "$name")
967 echo "include $include_name" >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
970 if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
971 log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
972 echo "include grmlmain.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
973 echo "include default.cfg" > "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
974 echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
975 echo "include grml.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
977 for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
978 echo "include $(basename $f)" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
981 echo "include options.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
982 if [ ! -n "$NO_ADDONS" ] ; then
983 echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
985 echo "include isoprompt.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
986 echo "include hd.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
987 echo "include hidden.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
988 else # assume we are building a custom distribution:
989 log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
990 einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
991 if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
992 log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
994 einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
998 log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
999 echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1000 [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1004 # use old style console based isolinux method only if requested:
1005 if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
1006 log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1007 einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1008 if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1009 einfo "include for console.cfg already found, nothing to do."
1012 log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1013 einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1014 echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1018 log 'Using graphical boot menu.'
1019 if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
1020 log "include for vesamenu.cfg already found, nothing to do."
1022 log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1023 echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1027 if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
1028 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
1031 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
1032 if ! [ -r "$DPKG_LIST" ] ; then
1033 ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
1035 einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
1036 cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
1040 # autostart for Windows:
1041 if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
1042 cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
1045 FORCE_ISO_REBUILD=true
1046 einfo "Finished execution of stage 'boot'" ; eend 0
1050 log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
1051 eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
1055 # support installation of local files into the chroot/ISO
1056 if [ -n "$CHROOT_INSTALL" ] ; then
1057 if ! [ -d "$CHROOT_INSTALL" ] ; then
1058 log "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1059 ewarn "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1061 log "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1062 einfo "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1063 rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
1065 einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
1066 FORCE_ISO_REBUILD=true
1070 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1071 log "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
1072 ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
1073 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
1074 log "Skipping stage 'squashfs' as requested via option -q or -N"
1075 ewarn "Skipping stage 'squashfs' as requested via option -q or -N" ; eend 0
1077 [ -d "$BUILD_OUTPUT"/live ] || mkdir "$BUILD_OUTPUT"/live
1078 # make sure we don't leave (even an empty) base.tgz:
1079 [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
1081 # if unconfigured default to squashfs-tools' mksquashfs binary
1082 if [ -z "$SQUASHFS_BINARY" ] ; then
1083 SQUASHFS_BINARY='mksquashfs'
1086 if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
1087 log "Using mksquashfs binary ${SQUASHFS_BINARY}"
1088 einfo "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
1090 log "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
1091 eerror "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
1095 # use sane defaults if $SQUASHFS_OPTIONS isn't set
1096 if [ -z "$SQUASHFS_OPTIONS" ] ; then
1097 # use blocksize 256k as this gives best result with regards to time + compression
1098 SQUASHFS_OPTIONS="-b 256k"
1100 # set lzma/xz compression by default, unless -z option has been specified on command line
1101 if [ -z "$SQUASHFS_ZLIB" ] ; then
1102 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp xz"
1104 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp gzip"
1108 # support exclusion of files via exclude-file:
1109 if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
1110 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE -wildcards"
1113 # get rid of unnecessary files when building grml-small for final release:
1114 if echo "$CLASSES" | grep -q GRML_SMALL ; then
1115 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
1119 SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
1121 # informational stuff
1122 [ -n "$SQUASHFS_OPTIONS" ] && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
1123 [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
1124 einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
1126 log "$SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS"
1128 if $SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
1129 -noappend $SQUASHFS_OPTIONS 2>"${SQUASHFS_STDERR}" ; then
1130 echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
1131 log "Finished execution of stage 'squashfs' [$(date)]"
1132 einfo "Finished execution of stage 'squashfs'" ; eend 0
1134 log "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
1135 log "$(cat $SQUASHFS_STDERR)"
1136 eerror "Error: there was a critical error executing stage 'squashfs':"
1137 cat "${SQUASHFS_STDERR}"
1142 FORCE_ISO_REBUILD=true
1145 # create md5sum file:
1146 if [ -z "$BOOTSTRAP_ONLY" ] ; then
1147 ( cd $BUILD_OUTPUT/GRML &&
1148 find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
1152 # ISO_OUTPUT - mkisofs {{{
1153 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
1154 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
1156 if [ "$BOOT_METHOD" = "isolinux" ] ; then
1157 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
1158 elif [ "$BOOT_METHOD" = "grub2" ] ; then
1159 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
1162 # Just until http://bts.grml.org/grml/issue945 has been resolved.
1163 # HYBRID_METHOD defaults to manifold, so make sure the default works OOTB.
1164 if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
1165 log "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1166 ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1167 HYBRID_METHOD='grub2'
1171 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
1172 log "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
1173 ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
1174 elif [ -n "$SKIP_MKISOFS" ] ; then
1175 log "Skipping stage 'iso build' as requested via option -n or -N"
1176 ewarn "Skipping stage 'iso build' as requested via option -n or -N" ; eend 0
1178 mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
1180 if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; then
1181 log "Forcing rebuild of ISO because files on ISO have been modified."
1182 einfo "Forcing rebuild of ISO because files on ISO have been modified."
1185 # support xorriso as well mkisofs and genisoimage
1186 if which xorriso >/dev/null 2>&1 ; then
1187 MKISOFS='xorriso -as mkisofs'
1188 elif which mkisofs >/dev/null 2>&1; then
1190 elif which genisoimage >/dev/null 2>&1; then
1191 MKISOFS='genisoimage'
1193 log "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO."
1194 eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1
1200 # using -eltorito-alt-boot is limited to xorriso for now
1203 einfo "Using xorriso for ISO generation." ; eend 0
1206 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
1207 log "Disabling (U)EFI boot support since xorriso version is not recent enough."
1208 ewarn "Disabling (U)EFI boot support since xorriso version is not recent enough." ; eend 0
1210 log "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support."
1211 einfo "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support." ; eend 0
1213 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" ] ; then
1214 einfo "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1215 log "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1216 mv "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" "${BUILD_OUTPUT}/boot/efi.img"
1220 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" ] ; then
1221 einfo "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1222 log "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1223 mkdir -p "${BUILD_OUTPUT}/efi/boot/"
1224 mv "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi"
1228 if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then
1229 einfo "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1230 log "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1231 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
1243 if cd "$BUILD_OUTPUT" ; then
1244 if [ "$BOOT_METHOD" = "grub2" ]; then
1245 # make a 2048-byte bootsector for El Torito
1246 dd if=/dev/zero of=boot/grub/toriboot.bin bs=512 count=4 2>/dev/null
1247 # those are in 2048-byte sectors, so 1 16 matches 4 63 below
1248 echo 1 16 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -B 11 | \
1249 dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
1251 log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
1252 $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
1253 -l -r -J $BOOT_ARGS -no-pad \
1254 -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
1255 # both of these need core.img there, so it’s easier to write it here
1256 if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
1257 # must be <= 30720 bytes
1258 dd if=boot/grub/core.img of="${ISO_OUTPUT}/${ISO_NAME}" \
1259 conv=notrunc bs=512 seek=4 2>/dev/null
1262 # pad the output ISO to multiples of 256 KiB for partition table support
1263 siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
1264 cyls=$((siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
1265 siz=$((cyls * 16 * 32 * 512)) # size after padding
1266 dd if=/dev/zero bs=1 count=1 seek=$((siz - 1)) \
1267 of="${ISO_OUTPUT}/${ISO_NAME}" 2>/dev/null
1269 # support disabling hybrid ISO image
1270 if [ "$HYBRID_METHOD" = "disable" ] ; then\
1271 log "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1272 einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1274 elif [ "$HYBRID_METHOD" = "manifold" ] ; then
1275 # isoinfo is part of both mkisofs and genisoimage so we're good
1276 bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
1277 sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p')
1278 if ! [ -r boot/grub/core.img ] ; then
1279 ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
1280 elif [ "${bootoff:-0}" -lt 1 ] ; then
1281 ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
1283 log "Creating hybrid ISO file with manifold method"
1284 einfo "Creating hybrid ISO file with manifold method"
1285 if [ "$HYBRID_METHOD" = "grub2" ] ; then
1286 # 512 bytes: MBR, partition table, load GRUB 2
1287 echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
1289 # read only one but 2048-byte sized (scale: << 2) sector
1290 echo $bootoff $bootoff | \
1291 mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
1292 fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
1295 # use isohybrid as default
1297 if ! which isohybrid >/dev/null 2>&1 ; then
1298 bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
1300 log "Creating hybrid ISO file with isohybrid method"
1301 einfo "Creating hybrid ISO file with isohybrid method"
1302 # Notes for consideration:
1303 # "-entry 4 -type 1c"
1304 # * using 4 as the partition number is supposed to help with BIOSes
1305 # that only support USB-Zip boot
1306 # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
1307 # (hidden NTFS, IIRC), as the partition type is sometimes needed
1308 # to get the BIOS even look at the partition created by isohybrid
1309 if isohybrid --help | grep -q -- --uefi ; then
1310 einfo "Detected uefi support for isohybrid, enabling."
1311 ISOHYBRID_OPTIONS=--uefi
1314 log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
1315 isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
1320 # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
1321 case $CLASSES in *RELEASE*)
1324 if cd $ISO_OUTPUT ; then
1325 md5sum ${ISO_NAME} > ${ISO_NAME}.md5 && \
1326 touch -r ${ISO_NAME} ${ISO_NAME}.md5
1327 sha1sum ${ISO_NAME} > ${ISO_NAME}.sha1 && \
1328 touch -r ${ISO_NAME} ${ISO_NAME}.sha1
1337 if [ "$RC" = 0 ] ; then
1338 log "Finished execution of stage 'iso build' [$(date)]"
1339 einfo "Finished execution of stage 'iso build'" ; eend 0
1341 log "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
1342 eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
1348 # netboot package {{{
1349 create_netbootpackage() {
1350 local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2"
1352 if [ -f "${OUTPUT_FILE}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1353 log "Skipping stage 'netboot' as $OUTPUT_FILE exists already."
1354 ewarn "Skipping stage 'netboot' as $OUTPUT_FILE exists already." ; eend 0
1356 elif [ -n "$SKIP_NETBOOT" ] ; then
1357 log "Skipping stage 'netboot' as requested via option -Q"
1358 ewarn "Skipping stage 'netboot' as requested via option -Q" ; eend 0
1364 if ! [ -r "${CHROOT}/usr/lib/syslinux/pxelinux.0" ] ; then
1365 ewarn "File /usr/lib/syslinux/pxelinux.0 not found in build chroot." ; eend 0
1367 einfo "Install syslinux[-common] package in chroot to get a netboot package."
1372 local OUTPUTDIR="${NETBOOT}/build_tmp"
1373 local WORKING_DIR="${OUTPUTDIR}/grml_netboot_package_${GRML_NAME}_${VERSION}/tftpboot/"
1375 mkdir -p "$WORKING_DIR"
1377 cp "${CHROOT_OUTPUT}"/boot/vmlinuz-* "$WORKING_DIR"/linux26
1378 cp "${CHROOT_OUTPUT}"/boot/initrd.img-* "$WORKING_DIR"/initrd.img
1379 cp "${CHROOT_OUTPUT}"/usr/lib/syslinux/pxelinux.0 "${WORKING_DIR}/pxelinux.0"
1381 if [ -r "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" ] ; then
1382 mkdir -p "${WORKING_DIR}/pxelinux.cfg/default"
1383 cp "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" "${WORKING_DIR}/pxelinux.cfg/default"
1385 ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found." ; eend 0
1388 mkdir -p "${WORKING_DIR}/pxelinux.cfg"
1390 if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
1391 einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0
1392 rm -rf "${OUTPUTDIR}"
1394 rm -rf "${OUTPUTDIR}"
1395 eerror "Could not generate netboot package ${OUTPUT_FILE}" ; eend 1
1400 create_netbootpackage
1403 # pack artifacts {{{
1404 if [ -n "$PACK_ARTIFACTS" ]; then
1405 log "Packing artifcats"
1406 einfo "Packing artifacts"
1407 [ -f "${CHROOT_ARCHIVE}" ] && rm -r "${CHROOT_ARCHIVE}"
1408 tar -c -a -f ${CHROOT_ARCHIVE} --preserve-permissions -C "$(dirname ${CHROOT_OUTPUT})" "$(basename ${CHROOT_OUTPUT})"
1413 # log build information to database if grml-live-db is installed and enabled {{{
1415 if [ -d /usr/share/grml-live-db ] ; then
1418 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
1419 [ -n "$DPKG_DATABASE" ] || DPKG_DATABASE=/var/log/grml-live.db
1420 [ -n "$DPKG_DBSCRIPT" ] || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
1421 [ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
1423 if ! [ -x "$DPKG_DBSCRIPT" ] ; then
1424 log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
1425 eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
1429 # disable by default for now, not sure whether really everyone is using a local db file
1430 #if ! touch "$DPKG_DATABASE" ; then
1431 # eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
1435 if ! [ -r "$DPKG_LIST" ] ; then
1436 log "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
1437 ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
1439 einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
1440 log "Logging $DPKG_LIST to database $DPKG_DATABASE"
1441 log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
1444 if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
1460 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
1461 log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
1463 dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
1465 einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
1469 ## END OF FILE #################################################################
1470 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2