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
126 # don't use colors/escape sequences
127 if [ -r /lib/lsb/init-functions ] ; then
128 . /lib/lsb/init-functions
129 ! log_use_fancy_output && NOCOLORS=true
132 if [ -r /etc/grml/lsb-functions ] ; then
133 . /etc/grml/lsb-functions
135 einfo() { echo " [*] $*" ;}
136 eerror() { echo " [!] $*">&2 ;}
137 ewarn() { echo " [x] $*" ;}
139 eindent() { return 0 ;}
140 eoutdent() { return 0 ;}
143 # source main configuration file:
144 LIVE_CONF=/etc/grml/grml-live.conf
148 # umount all directories {{{
150 # make sure we don't leave any mounts - FAI doesn't remove them always
151 umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
152 umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true
153 umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
154 umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
156 # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry
157 if [ -x /usr/lib/fai/mkramdisk ] ; then
158 /usr/lib/fai/mkramdisk -u "$(readlink -f ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true
161 umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true
162 [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
168 rm -f /var/run/fai/fai_softupdate_is_running \
169 /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
170 [ -n "$CONFIGDUMP" ] && rm -f "$CONFIGDUMP"
171 [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR"
173 [ -n "$1" ] && EXIT="$1" || EXIT="1"
174 [ -n "$2" ] && eerror "$2">&2
175 if [ -n "$PACK_ARTIFACTS" ]; then
178 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
179 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
182 if [ -n "$CHOWN_USER" ]; then
183 log "Setting ownership"
184 einfo "Setting ownership"
185 [ -n "${OUTPUT}" -a -d "${OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${OUTPUT}"
186 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${BUILD_OUTPUT}"
187 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}"
188 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}"
189 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}"
190 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && chown -R "${CHOWN_USER}:" "${NETBOOT}"
191 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_ARCHIVE}"
194 log "------------------------------------------------------------------------------"
197 trap bailout 1 2 3 3 6 9 14 15
201 # some important functions {{{
204 # usage: log "string to log"
205 log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; }
207 # cut string at character number int = $1
208 # usage: cut_string 5 "1234567890" will output "12345"
210 [ -n "$2" ] || return 1
211 echo "$2" | head -c "$1"; echo -ne "\n"
214 # prepend int = $1 spaces before string = $2
215 # usage: extend_string_begin 5 "123" will output " 123"
216 extend_string_begin() {
217 [ -n "$2" ] || return 1
218 local COUNT="$(echo $2 | wc -c)"
219 local FILL="$(expr $COUNT - $1)"
220 while [ "$FILL" -gt 1 ] ; do
222 local FILL=$(expr $FILL - 1)
224 while [ "$FILL" -lt 1 ] ; do
226 local FILL=$(expr $FILL + 1)
228 echo "$2" | head -c "$1"; echo -ne "\n"
231 # append int = $1 spaces to string = $2
232 # usage: extend_string_begin 5 "123" will output "123 "
233 extend_string_end() {
234 [ -n "$2" ] || return 1
235 echo -n "$2" | head -c "$1"
236 local COUNT="$(echo $2 | wc -c)"
237 local FILL="$(expr $COUNT - $1)"
238 while [ "$FILL" -gt 1 ] ; do
240 local FILL=$(expr $FILL - 1)
242 while [ "$FILL" -lt 1 ] ; do
244 local FILL=$(expr $FILL + 1)
249 # Copy addonfile $1 from either
250 # * the chroot (via $2, the system path),
251 # * or from TEMPLATE_DIRECTORY/compat (if exists),
252 # * or from the host system (again, using $2),
253 # or warn about the missing file.
256 # * We assume that the chroot always has a "good" version of
257 # the file. Also it makes sources handling easier.
258 # * On unstable, we Recommend the Debian packages containing
259 # these files. The user can override them by putting his
260 # "better" version into the chroot.
261 # * On stable, the Debian packages are probably not available,
262 # or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
263 # our grml-live-compat package installs current file versions.
265 DEST="${BUILD_OUTPUT}/boot/$3"
266 if [ ! -d "${DEST}/" ]; then
269 if [ -e "$CHROOT_OUTPUT/$2/$1" ]; then
270 log "Copying $1 from chroot"
271 cp "$CHROOT_OUTPUT/$2/$1" "${DEST}/"
274 if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
275 log "Copying $1 from grml-live-compat"
276 cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
279 if [ -e "$2/$1" ]; then
280 log "Copying $1 from system"
281 cp "$2/$1" "${DEST}/"
285 msg="Missing addon file: \"$1\""
286 ewarn "$msg" ; eend 1
287 log "copy_addon_file: $msg"
291 # command line parsing {{{
292 while getopts "a:C:c:d:D:g:i:I:o:r:s:t:T:U:v:AbBFnNqQuVz" opt; do
295 A) PACK_ARTIFACTS=1 ;;
298 c) CLASSES="$OPTARG" ;;
299 C) LOCAL_CONFIG="$(readlink -f $OPTARG)" ;;
301 D) GRML_FAI_CONFIG="$(readlink -f $OPTARG)" ;;
302 g) GRML_NAME="$OPTARG" ;;
303 i) ISO_NAME="$OPTARG" ;;
304 I) CHROOT_INSTALL="$OPTARG" ;;
306 N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;;
307 o) OUTPUT="$(readlink -f $OPTARG)" ;;
308 q) SKIP_MKSQUASHFS=1 ;;
310 r) RELEASENAME="$OPTARG" ;;
311 s) SUITE="$OPTARG" ;;
312 t) TEMPLATE_DIRECTORY="$OPTARG";;
313 T) UNPACK_CHROOT="$(readlink -f $OPTARG)" ;;
314 v) VERSION="$OPTARG" ;;
317 U) CHOWN_USER="$OPTARG" ;;
319 z) SQUASHFS_ZLIB=1 ;;
320 ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
323 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
326 # read local (non-packaged) configuration {{{
327 if [ -z "$LOCAL_CONFIG" ]; then
328 if [ -r "/etc/grml/grml-live.local" ]; then
329 LOCAL_CONFIG="/etc/grml/grml-live.local"
332 if [ -n "$LOCAL_CONFIG" ]; then
333 if [ -r "$LOCAL_CONFIG" ]; then
336 eerror "Could not read specified local configuration file \"$LOCAL_CONFIG\"."
339 LOCAL_CONFIG=$(readlink -f "$LOCAL_CONFIG")
344 if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
345 eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated."
346 ewarn "Please set up \${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead."
351 # assume sane defaults (if not set already) {{{
352 [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
353 [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
354 [ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_FULL,$(echo ${ARCH} | tr 'a-z' 'A-Z')"
355 [ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)"
356 [ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators '
357 [ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
358 [ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
359 [ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
360 [ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
361 [ -n "$GRML_NAME" ] || GRML_NAME='grml'
362 [ -n "$HOSTNAME" ] || HOSTNAME='grml'
363 [ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='manifold'
364 [ -n "$NFSROOT_CONF" ] || NFSROOT_CONF="${GRML_FAI_CONFIG}/make-fai-nfsroot.conf"
365 [ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
366 [ -n "$SQUASHFS_EXCLUDES_FILE" ] || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
367 [ -n "$SUITE" ] || SUITE='squeeze'
368 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
369 [ -n "$USERNAME" ] || USERNAME='grml'
370 [ -n "$VERSION" ] || VERSION='0.0.1'
372 # output specific stuff, depends on $OUTPUT (iff not set):
373 [ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live'
374 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
375 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
376 [ -n "$CHROOT_ARCHIVE" ] || CHROOT_ARCHIVE="$OUTPUT/$(basename $CHROOT_OUTPUT).tgz"
377 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
378 [ -n "$LOG_OUTPUT" ] || LOG_OUTPUT="$OUTPUT/grml_logs"
379 [ -n "$REPORTS" ] || REPORTS="${LOG_OUTPUT}/reports/"
380 [ -n "$NETBOOT" ] || NETBOOT="${OUTPUT}/netboot/"
383 # some misc checks before executing FAI {{{
384 [ -n "$CLASSES" ] || bailout 1 "Error: \$CLASSES unset, please set it in $LIVE_CONF or
385 specify it on the command line using the -c option."
386 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
387 specify it on the command line using the -o option."
389 # trim characters that are known to cause problems inside $GRML_NAME;
390 # for example isolinux does not like '-' inside the directory name
391 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
393 # export variables to have them available in fai scripts:
394 [ -n "$GRML_NAME" ] && export GRML_NAME="$GRML_NAME"
395 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
398 # ZERO_LOGFILE - check for backwards compatibility reasons {{{
399 # this was default behaviour until grml-live 0.9.34:
400 if [ -n "$ZERO_LOGFILE" ] ; then
401 PRESERVE_LOGFILE='' # make sure it's cleaned then
402 ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
403 ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
408 # ask user whether the setup is ok {{{
409 if [ -z "$FORCE" ] ; then
411 echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
413 echo " FAI classes: $CLASSES"
414 [ -n "$LOCAL_CONFIG" ] && echo " Configuration: $LOCAL_CONFIG"
415 [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG"
416 echo " main directory: $OUTPUT"
417 [ -n "$UNPACK_CHROOT" ] && echo " Chroot from: $UNPACK_CHROOT"
418 [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT"
419 [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT"
420 [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT"
421 [ -n "$GRML_NAME" ] && echo " Grml name: $GRML_NAME"
422 [ -n "$RELEASENAME" ] && echo " Release name: $RELEASENAME"
423 [ -n "$DATE" ] && echo " Build date: $DATE"
424 [ -n "$VERSION" ] && echo " Grml version: $VERSION"
425 [ -n "$SUITE" ] && echo " Debian suite: $SUITE"
426 [ -n "$ARCH" ] && echo " Architecture: $ARCH"
427 [ -n "$BOOT_METHOD" ] && echo " Boot method: $BOOT_METHOD"
428 [ -n "$HYBRID_METHOD" ] && echo " Hybrid method: $HYBRID_METHOD"
429 [ -n "$TEMPLATE_DIRECTORY" ] && echo " Template files: $TEMPLATE_DIRECTORY"
430 [ -n "$CHROOT_INSTALL" ] && echo " Install files from directory to chroot: $CHROOT_INSTALL"
431 [ -n "$BOOTID" ] && echo " Boot identifier: $BOOTID"
432 [ -n "$NO_BOOTID" ] && echo " Skipping bootid feature."
433 [ -n "$CHOWN_USER" ] && echo " Output owner: $CHOWN_USER"
434 [ -n "$DEFAULT_BOOTOPTIONS" ] && echo " Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
435 [ -n "$FAI_ARGS" ] && echo " Additional arguments for FAI: $FAI_ARGS"
436 [ -n "$LOGFILE" ] && echo " Logging to file: $LOGFILE"
437 [ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA/XZ) compression."
438 [ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
439 [ -n "$VERBOSE" ] && echo " Using VERBOSE mode."
440 [ -n "$PACK_ARTIFACTS" ] && echo " Will prepare packed artifacts and ensure clean build."
441 [ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation."
442 if [ -n "$BOOTSTRAP_ONLY" ] ; then
443 echo " Bootstrapping only and not building (files for) ISO."
445 [ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file."
446 [ -n "$SKIP_NETBOOT" ] && echo " Skipping creation of NETBOOT package."
447 [ -n "$SKIP_MKISOFS" ] && echo " Skipping creation of ISO file."
448 [ -n "$BUILD_ONLY" ] && echo " Executing BUILD_ONLY instead of fresh installation or UPDATE."
449 [ -n "$BUILD_DIRTY" ] && echo " Executing BUILD_DIRTY to leave chroot untouched."
452 echo -n "Is this ok for you? [y/N] "
454 if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
455 bailout 1 "Exiting as requested."
461 # clean up before start {{{
462 if [ -n "${PACK_ARTIFACTS}" ]; then
463 echo "Wiping old artifacts"
464 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
465 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
466 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && rm -r "${ISO_OUTPUT}"
467 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && rm -r "${LOG_OUTPUT}"
468 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && rm -r "${NETBOOT}"
472 # create log file {{{
473 [ -n "$LOGFILE" ] || LOGFILE=${LOG_OUTPUT}/grml-live.log
474 mkdir -p $(dirname "${LOGFILE}")
476 chown root:adm $LOGFILE
480 # clean/zero/remove logfiles {{{
482 if [ -n "$PRESERVE_LOGFILE" ] ; then
483 echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
485 # make sure it is empty (as it is e.g. appended to grml-live-db)
489 if [ -n "$ZERO_FAI_LOGFILE" ] ; then
490 if [ -d /var/log/fai/"$HOSTNAME" ] ; then
491 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
492 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
493 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
494 rm -f /var/log/fai/"$HOSTNAME"/last \
495 /var/log/fai/"$HOSTNAME"/last-dirinstall \
496 /var/log/fai/"$HOSTNAME"/last-softupdate
501 # source config and startup {{{
502 if [ -n "$CONFIG" ] ; then
503 if ! [ -f "$CONFIG" ] ; then
504 log "Error: $CONFIG could not be read. Exiting. [$(date)]"
505 eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
508 log "Sourcing $CONFIG"
513 start_seconds=$(cut -d . -f 1 /proc/uptime)
514 log "------------------------------------------------------------------------------"
515 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
516 log "Using local config file: $LOCAL_CONFIG"
517 log "Executed grml-live command line:"
520 einfo "Logging actions to logfile $LOGFILE"
523 # dump config variables into file, for script access {{{
526 '^(GRML_NAME|RELEASENAME|DATE|VERSION|SUITE|ARCH|DISTRI_NAME|USERNAME|HOSTNAME|APT_PROXY)=' \
531 if [ -n "${UNPACK_CHROOT}" ]; then
532 log "Unpacking chroot from ${UNPACK_CHROOT}"
533 einfo "Unpacking chroot from ${UNPACK_CHROOT}"
534 [ -d "$CHROOT_OUTPUT" ] || mkdir -p "${CHROOT_OUTPUT}"
535 tar -xf "${UNPACK_CHROOT}" -C "${CHROOT_OUTPUT}/" --strip-components 1 ; RC=$?
536 if [ "$RC" != 0 ] ; then
544 # cleanup CHROOT_ARCHIVE now {{{
545 if [ -n "${PACK_ARTIFACTS}" ]; then
546 # can't do this earlier, as UNPACK_CHROOT might point to CHROOT_ARCHIVE
547 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}"
551 # on-the-fly configuration {{{
552 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
553 sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
556 # does this suck? YES!
557 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
559 unstable) SUITE='sid' ; CLASSES="DEBIAN_UNSTABLE,$CLASSES" ;;
560 *) CLASSES="DEBIAN_$(echo $SUITE | tr 'a-z' 'A-Z'),$CLASSES";;
562 export SUITE # make sure it's available in FAI scripts
564 for file in "$LIVE_CONF" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do
565 if [ -n "$file" ] ; then
566 sed "s|^FAI_DEBOOTSTRAP=\"[a-z]* |FAI_DEBOOTSTRAP=\"$SUITE |" "$file" | sponge "$file"
570 # validate whether the specified architecture class matches the
571 # architecture (option), otherwise installation of kernel will fail
572 if echo $CLASSES | grep -qi i386 ; then
573 if ! [[ "$ARCH" == "i386" ]] ; then
574 log "Error: You specified the I386 class but are trying to build something else (AMD64?)."
575 eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
576 eerror "Tip: Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
580 elif echo $CLASSES | grep -qi amd64 ; then
581 if ! [[ "$ARCH" == "amd64" ]] ; then
582 log "Error: You specified the AMD64 class but are trying to build something else (I386?)."
583 eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
584 eerror "Tip: Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
590 if grep -q -- 'FAI_DEBOOTSTRAP_OPTS.*--arch' "$NFSROOT_CONF" ; then
591 sed "s/--arch [a-z0-9]* /--arch $ARCH /" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
593 sed "s|^FAI_DEBOOTSTRAP_OPTS=\"\(.*\)|FAI_DEBOOTSTRAP_OPTS=\"--arch $ARCH \1|" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
597 # CHROOT_OUTPUT - execute FAI {{{
598 if [ -n "$BUILD_DIRTY" ]; then
599 log "Skipping stage 'fai' as requested via option -B"
600 ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
602 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
604 # provide inform fai about the ISO we build
605 [ -d "$CHROOT_OUTPUT/etc/" ] || mkdir -p "$CHROOT_OUTPUT/etc/"
606 echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
607 [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
608 [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
610 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
611 FAI_ACTION=softupdate
613 FAI_ACTION=dirinstall
616 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
617 if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
618 log "Error: does not look like you have a working chroot. Updating/building not possible."
619 eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
625 if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
626 log "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
627 ewarn "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
629 mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
631 if [ -n "${MIRROR_DIRECTORY}" ] ; then
632 mkdir -p "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
633 mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
636 mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
637 mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
639 # tell dpkg to use "unsafe io" during the build
640 [ -d "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d" ] || mkdir -p "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d"
641 echo force-unsafe-io > "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
643 log "Executed FAI command line:"
644 log "BUILD_ONLY=$BUILD_ONLY BOOTSTRAP_ONLY=$BOOTSTRAP_ONLY GRML_LIVE_CONFIG=$CONFIGDUMP fai $VERBOSE -C $GRML_FAI_CONFIG -s file:///$GRML_FAI_CONFIG/config -c$CLASSES -u $HOSTNAME $FAI_ACTION $CHROOT_OUTPUT $FAI_ARGS"
645 BUILD_ONLY="$BUILD_ONLY" BOOTSTRAP_ONLY="$BOOTSTRAP_ONLY" GRML_LIVE_CONFIG="$CONFIGDUMP" fai $VERBOSE \
646 -C "$GRML_FAI_CONFIG" -s "file:///$GRML_FAI_CONFIG/config" -c"$CLASSES" \
647 -u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
648 RC="$PIPESTATUS" # notice: bash-only
650 rm -f "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
652 FORCE_ISO_REBUILD=true
654 if [ "$RC" != 0 ] ; then
655 log "Error: critical error while executing fai [exit code ${RC}]. Exiting."
656 eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
659 einfo "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
660 log "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
661 echo "$GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]" > $CHROOT_OUTPUT/etc/grml_version
662 chmod 644 $CHROOT_OUTPUT/etc/grml_version
663 einfo "Rebuilding initramfs"
664 # make sure new /etc/grml_version reaches initramfs, iterate over all
665 # present kernel versions (note: we can't really handle more than one
666 # kernel version anyway right now)
667 # chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :(
668 for initrd in "$(basename $CHROOT_OUTPUT/boot/vmlinuz-*)" ; do
669 if ! chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -c ; then
670 einfo "Creating fresh initrd did not work, trying update instead:"
671 log "Creating fresh initrd did not work, trying update instead:"
672 chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -u
678 # move fai logs into grml_logs directory
679 mkdir -p "$LOG_OUTPUT"/fai/
680 cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
681 rm -rf "$CHROOT_OUTPUT"/var/log/fai
682 # copy fai package list
683 cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/
685 chown root:adm "$LOG_OUTPUT"/fai/*
686 chmod 664 "$LOG_OUTPUT"/fai/*
690 # notice: 'fai dirinstall' does not seem to exit appropriate, so:
692 CHECKLOG="$LOG_OUTPUT"/fai/
693 if [ -r "$CHECKLOG/software.log" ] ; then
694 # 1 errors during executing of commands
695 grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1
696 grep 'E: Method http has died unexpectedly!' $CHECKLOG/software.log >> $LOGFILE && ERROR=2
697 grep 'ERROR: chroot' $CHECKLOG/software.log >> $LOGFILE && ERROR=3
698 grep 'E: Failed to fetch' $CHECKLOG/software.log >> $LOGFILE && ERROR=4
699 grep 'Unable to write mmap - msync (28 No space left on device)' $CHECKLOG/software.log >> $LOGFILE && ERROR=5
702 if [ -r "$CHECKLOG/shell.log" ] ; then
703 grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=6
706 if [ -n "$ERROR" ] ; then
707 log "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
708 eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
709 eerror "Note: check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
713 log "Finished execution of stage 'fai dirinstall' [$(date)]"
714 einfo "Finished execution of stage 'fai dirinstall'"
720 # package validator {{{
721 CHECKLOG=/var/log/fai/$HOSTNAME/last
722 if [ -r "$CHECKLOG/dpkg.selections" ] ; then
723 package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}')
725 package_count="unknown"
729 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
731 # check for missing packages
732 if ! [ -s "$CHECKLOG/package_errors.log" ] ; then
733 einfo "No missing packages found, generating empty junit report."
735 cat > "${REPORT_MISSING_PACKAGES}" << EOF
736 <?xml version="1.0" encoding="UTF-8"?>
737 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="0" errors="0" skipped="0" assertions="0">
738 <testcase name="test_missing_packages" time="0" assertions="0">
748 einfo "Missing packages found, generating junit report."
750 if [ -r "$CHECKLOG/package_errors.log" ] ; then
751 package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}')
753 package_errors="unknown"
757 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
759 cat > "${REPORT_MISSING_PACKAGES}" << EOF
760 <?xml version="1.0" encoding="UTF-8"?>
761 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
764 for package in $(awk '{print $5}' "${CHECKLOG}/package_errors.log" | sed 's/\.$//') ; do
765 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
766 <testcase name="test_missing_packages_${package}" time="0" assertions="0">
767 <failure type="RuntimeError" message="Package ${package} is missing">
768 Package $package is missing in chroot
774 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
783 if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
784 eerror "The following packages were requested for installation but could not be processed:"
785 cat "$CHECKLOG/package_errors.log"
786 eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
790 ewarn "The following packages were requested for installation but could not be processed:"
791 cat "$CHECKLOG/package_errors.log"
797 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
798 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
799 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
802 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
803 if [ -n "$BOOTSTRAP_ONLY" ] ; then
804 log "Skipping stage 'boot' as building with bootstrap only."
805 ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
807 if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
808 log "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
809 ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
812 [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
813 [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
815 # if we don't have an initrd we a) can't boot and b) there was an error
816 # during build, so check for the file:
817 INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
818 if [ -n "$INITRD" ] ; then
819 cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
820 find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
822 log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
823 eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
827 KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
828 if [ -n "$KERNEL_IMAGE" ] ; then
829 cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/linux26
831 log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
832 eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
836 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
837 if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
838 log "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
839 eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
843 # copy _required_ isolinux files
844 for file in ifcpu64.c32 isolinux.bin vesamenu.c32; do
845 copy_addon_file "${file}" /usr/lib/syslinux isolinux
848 # *always* copy files to output directory so the variables
849 # get adjusted according to the build.
850 cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
852 if [ -n "$NO_ADDONS" ] ; then
853 log "Skipping installation of boot addons as requested via \$NO_ADDONS."
854 einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
856 if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
857 log "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
858 ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
860 # copy addons from system packages or grml-live-compat
861 copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
862 copy_addon_file pci.ids /usr/share/misc addons
863 copy_addon_file memtest86+.bin /boot addons
864 for file in memdisk chain.c32 hdt.c32 menu.c32; do
865 copy_addon_file "${file}" /usr/lib/syslinux addons
868 # make memtest filename FAT16/8.3 compatible
869 mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
870 "${BUILD_OUTPUT}/boot/addons/memtest"
872 # copy only files so we can handle bsd4grml on its own
873 for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
874 test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
877 if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
878 log "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
879 einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
881 if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
882 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
884 log "Missing addon file: bsd4grml"
885 ewarn "Missing addon file: bsd4grml" ; eend 0
889 fi # no "$TEMPLATE_DIRECTORY"/boot/addons
892 if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
893 mkdir -p "${BUILD_OUTPUT}/boot/grub"
895 cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
897 # copy grub files from target
898 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/
899 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/
900 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/
901 cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
902 cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
904 if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
905 log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
906 eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
910 [ -d "$BUILD_OUTPUT"/GRML ] || mkdir "$BUILD_OUTPUT"/GRML
911 cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/
913 # adjust boot splash information:
914 RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
915 RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
916 RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
918 if [ -r "$BUILD_OUTPUT"/GRML/grml-version ] ; then
919 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
920 sed -i "s/%DATE%/$DATE/" "$BUILD_OUTPUT"/GRML/grml-version
923 # make sure the squashfs filename is set accordingly:
924 SQUASHFS_NAME="$GRML_NAME.squashfs"
926 if [ -n "$NO_BOOTID" ] ; then
927 log 'Skipping bootid feature as requested via $NO_BOOTID.'
928 einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
930 [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
931 [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
932 einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
933 log "Generating /conf/bootid.txt with entry ${BOOTID}."
934 echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
938 # adjust all variables in the templates with the according distribution information
939 for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
940 "${BUILD_OUTPUT}"/boot/grub/* ; do
941 if [ -r "${file}" ] ; then
942 sed -i "s/%ARCH%/$ARCH/g" "${file}"
943 sed -i "s/%DATE%/$DATE/g" "${file}"
944 sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g" "${file}"
945 sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g" "${file}"
946 sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g" "${file}"
947 sed -i "s/%GRML_NAME%/$GRML_NAME/g" "${file}"
948 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g" "${file}"
949 sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g" "${file}"
950 sed -i "s/%SHORT_NAME%/$SHORT_NAME/g" "${file}"
951 sed -i "s/%VERSION%/$VERSION/g" "${file}"
953 [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s/ boot=live/ boot=live $DEFAULT_BOOTOPTIONS/" "${file}"
955 if [ -n "$NO_BOOTID" ] ; then
956 sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
958 sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
963 # adjust bootsplash accordingly but make sure the string has the according lenght
964 SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
965 SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
966 for file in f4 f5 ; do
967 if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
968 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
969 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
973 # generate addon list
974 rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
975 for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
976 include_name=$(basename "$name")
977 echo "include $include_name" >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
980 if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
981 log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
982 echo "include grmlmain.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
983 echo "include default.cfg" > "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
984 echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
985 echo "include grml.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
987 for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
988 echo "include $(basename $f)" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
991 echo "include options.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
992 if [ ! -n "$NO_ADDONS" ] ; then
993 echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
995 echo "include isoprompt.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
996 echo "include hd.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
997 echo "include hidden.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
998 else # assume we are building a custom distribution:
999 log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1000 einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1001 if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1002 log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1004 einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1008 log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1009 echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1010 [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1014 # use old style console based isolinux method only if requested:
1015 if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
1016 log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1017 einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1018 if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1019 einfo "include for console.cfg already found, nothing to do."
1022 log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1023 einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1024 echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1028 log 'Using graphical boot menu.'
1029 if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
1030 log "include for vesamenu.cfg already found, nothing to do."
1032 log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1033 echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1037 if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
1038 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
1041 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
1042 if ! [ -r "$DPKG_LIST" ] ; then
1043 ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
1045 einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
1046 cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
1050 # autostart for Windows:
1051 if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
1052 cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
1055 FORCE_ISO_REBUILD=true
1056 einfo "Finished execution of stage 'boot'" ; eend 0
1060 log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
1061 eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
1065 # support installation of local files into the chroot/ISO
1066 if [ -n "$CHROOT_INSTALL" ] ; then
1067 if ! [ -d "$CHROOT_INSTALL" ] ; then
1068 log "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1069 ewarn "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1071 log "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1072 einfo "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1073 rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
1075 einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
1076 FORCE_ISO_REBUILD=true
1080 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1081 log "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
1082 ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
1083 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
1084 log "Skipping stage 'squashfs' as requested via option -q or -N"
1085 ewarn "Skipping stage 'squashfs' as requested via option -q or -N" ; eend 0
1087 [ -d "$BUILD_OUTPUT"/live ] || mkdir "$BUILD_OUTPUT"/live
1088 # make sure we don't leave (even an empty) base.tgz:
1089 [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
1091 # if unconfigured default to squashfs-tools' mksquashfs binary
1092 if [ -z "$SQUASHFS_BINARY" ] ; then
1093 SQUASHFS_BINARY='mksquashfs'
1096 if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
1097 log "Using mksquashfs binary ${SQUASHFS_BINARY}"
1098 einfo "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
1100 log "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
1101 eerror "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
1105 # use sane defaults if $SQUASHFS_OPTIONS isn't set
1106 if [ -z "$SQUASHFS_OPTIONS" ] ; then
1107 # use blocksize 256k as this gives best result with regards to time + compression
1108 SQUASHFS_OPTIONS="-b 256k"
1110 # set lzma/xz compression by default, unless -z option has been specified on command line
1111 if [ -z "$SQUASHFS_ZLIB" ] ; then
1112 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp xz"
1114 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp gzip"
1118 # support exclusion of files via exclude-file:
1119 if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
1120 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE -wildcards"
1123 # get rid of unnecessary files when building grml-small for final release:
1124 if echo "$CLASSES" | grep -q GRML_SMALL ; then
1125 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
1129 SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
1131 # informational stuff
1132 [ -n "$SQUASHFS_OPTIONS" ] && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
1133 [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
1134 einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
1136 log "$SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS"
1138 if $SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
1139 -noappend $SQUASHFS_OPTIONS 2>"${SQUASHFS_STDERR}" ; then
1140 echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
1141 log "Finished execution of stage 'squashfs' [$(date)]"
1142 einfo "Finished execution of stage 'squashfs'" ; eend 0
1144 log "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
1145 log "$(cat $SQUASHFS_STDERR)"
1146 eerror "Error: there was a critical error executing stage 'squashfs':"
1147 cat "${SQUASHFS_STDERR}"
1152 FORCE_ISO_REBUILD=true
1155 # create md5sum file:
1156 if [ -z "$BOOTSTRAP_ONLY" ] ; then
1157 ( cd $BUILD_OUTPUT/GRML &&
1158 find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
1162 # ISO_OUTPUT - mkisofs {{{
1163 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
1164 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
1166 if [ "$BOOT_METHOD" = "isolinux" ] ; then
1167 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
1168 elif [ "$BOOT_METHOD" = "grub2" ] ; then
1169 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
1172 # Just until http://bts.grml.org/grml/issue945 has been resolved.
1173 # HYBRID_METHOD defaults to manifold, so make sure the default works OOTB.
1174 if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
1175 log "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1176 ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1177 HYBRID_METHOD='grub2'
1181 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
1182 log "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
1183 ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
1184 elif [ -n "$SKIP_MKISOFS" ] ; then
1185 log "Skipping stage 'iso build' as requested via option -n or -N"
1186 ewarn "Skipping stage 'iso build' as requested via option -n or -N" ; eend 0
1188 mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
1190 if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; then
1191 log "Forcing rebuild of ISO because files on ISO have been modified."
1192 einfo "Forcing rebuild of ISO because files on ISO have been modified."
1195 # support xorriso as well mkisofs and genisoimage
1196 if which xorriso >/dev/null 2>&1 ; then
1197 MKISOFS='xorriso -as mkisofs'
1198 elif which mkisofs >/dev/null 2>&1; then
1200 elif which genisoimage >/dev/null 2>&1; then
1201 MKISOFS='genisoimage'
1203 log "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO."
1204 eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1
1210 # using -eltorito-alt-boot is limited to xorriso for now
1213 einfo "Using xorriso for ISO generation." ; eend 0
1216 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
1217 log "Disabling (U)EFI boot support since xorriso version is not recent enough."
1218 ewarn "Disabling (U)EFI boot support since xorriso version is not recent enough." ; eend 0
1220 log "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support."
1221 einfo "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support." ; eend 0
1223 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" ] ; then
1224 einfo "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1225 log "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1226 mv "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" "${BUILD_OUTPUT}/boot/efi.img"
1230 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" ] ; then
1231 einfo "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1232 log "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1233 mkdir -p "${BUILD_OUTPUT}/efi/boot/"
1234 mv "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi"
1238 if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then
1239 einfo "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1240 log "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1241 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
1253 if cd "$BUILD_OUTPUT" ; then
1254 if [ "$BOOT_METHOD" = "grub2" ]; then
1255 # make a 2048-byte bootsector for El Torito
1256 dd if=/dev/zero of=boot/grub/toriboot.bin bs=512 count=4 2>/dev/null
1257 # those are in 2048-byte sectors, so 1 16 matches 4 63 below
1258 echo 1 16 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -B 11 | \
1259 dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
1261 log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
1262 $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
1263 -l -r -J $BOOT_ARGS -no-pad \
1264 -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
1265 # both of these need core.img there, so it’s easier to write it here
1266 if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
1267 # must be <= 30720 bytes
1268 dd if=boot/grub/core.img of="${ISO_OUTPUT}/${ISO_NAME}" \
1269 conv=notrunc bs=512 seek=4 2>/dev/null
1272 # pad the output ISO to multiples of 256 KiB for partition table support
1273 siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
1274 cyls=$((siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
1275 siz=$((cyls * 16 * 32 * 512)) # size after padding
1276 dd if=/dev/zero bs=1 count=1 seek=$((siz - 1)) \
1277 of="${ISO_OUTPUT}/${ISO_NAME}" 2>/dev/null
1279 # support disabling hybrid ISO image
1280 if [ "$HYBRID_METHOD" = "disable" ] ; then\
1281 log "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1282 einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1284 elif [ "$HYBRID_METHOD" = "manifold" ] ; then
1285 # isoinfo is part of both mkisofs and genisoimage so we're good
1286 bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
1287 sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p')
1288 if ! [ -r boot/grub/core.img ] ; then
1289 ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
1290 elif [ "${bootoff:-0}" -lt 1 ] ; then
1291 ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
1293 log "Creating hybrid ISO file with manifold method"
1294 einfo "Creating hybrid ISO file with manifold method"
1295 if [ "$HYBRID_METHOD" = "grub2" ] ; then
1296 # 512 bytes: MBR, partition table, load GRUB 2
1297 echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
1299 # read only one but 2048-byte sized (scale: << 2) sector
1300 echo $bootoff $bootoff | \
1301 mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
1302 fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
1305 # use isohybrid as default
1307 if ! which isohybrid >/dev/null 2>&1 ; then
1308 bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
1310 log "Creating hybrid ISO file with isohybrid method"
1311 einfo "Creating hybrid ISO file with isohybrid method"
1312 # Notes for consideration:
1313 # "-entry 4 -type 1c"
1314 # * using 4 as the partition number is supposed to help with BIOSes
1315 # that only support USB-Zip boot
1316 # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
1317 # (hidden NTFS, IIRC), as the partition type is sometimes needed
1318 # to get the BIOS even look at the partition created by isohybrid
1319 if isohybrid --help | grep -q -- --uefi ; then
1320 einfo "Detected uefi support for isohybrid, enabling."
1321 ISOHYBRID_OPTIONS=--uefi
1324 log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
1325 isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
1330 # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
1331 case $CLASSES in *RELEASE*)
1334 if cd $ISO_OUTPUT ; then
1335 md5sum ${ISO_NAME} > ${ISO_NAME}.md5 && \
1336 touch -r ${ISO_NAME} ${ISO_NAME}.md5
1337 sha1sum ${ISO_NAME} > ${ISO_NAME}.sha1 && \
1338 touch -r ${ISO_NAME} ${ISO_NAME}.sha1
1347 if [ "$RC" = 0 ] ; then
1348 log "Finished execution of stage 'iso build' [$(date)]"
1349 einfo "Finished execution of stage 'iso build'" ; eend 0
1351 log "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
1352 eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
1358 # netboot package {{{
1359 create_netbootpackage() {
1360 local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2"
1362 if [ -f "${OUTPUT_FILE}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1363 log "Skipping stage 'netboot' as $OUTPUT_FILE exists already."
1364 ewarn "Skipping stage 'netboot' as $OUTPUT_FILE exists already." ; eend 0
1366 elif [ -n "$SKIP_NETBOOT" ] ; then
1367 log "Skipping stage 'netboot' as requested via option -Q"
1368 ewarn "Skipping stage 'netboot' as requested via option -Q" ; eend 0
1374 if ! [ -r "${CHROOT}/usr/lib/syslinux/pxelinux.0" ] ; then
1375 ewarn "File /usr/lib/syslinux/pxelinux.0 not found in build chroot." ; eend 0
1377 einfo "Install syslinux[-common] package in chroot to get a netboot package."
1382 local OUTPUTDIR="${NETBOOT}/build_tmp"
1383 local WORKING_DIR="${OUTPUTDIR}/grml_netboot_package_${GRML_NAME}_${VERSION}/tftpboot/"
1385 mkdir -p "$WORKING_DIR"
1387 cp "${CHROOT_OUTPUT}"/boot/vmlinuz-* "$WORKING_DIR"/linux26
1388 cp "${CHROOT_OUTPUT}"/boot/initrd.img-* "$WORKING_DIR"/initrd.img
1389 cp "${CHROOT_OUTPUT}"/usr/lib/syslinux/pxelinux.0 "${WORKING_DIR}/pxelinux.0"
1391 if [ -r "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" ] ; then
1392 mkdir -p "${WORKING_DIR}/pxelinux.cfg/default"
1393 cp "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" "${WORKING_DIR}/pxelinux.cfg/default"
1395 ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found." ; eend 0
1398 mkdir -p "${WORKING_DIR}/pxelinux.cfg"
1400 if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
1401 einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0
1402 rm -rf "${OUTPUTDIR}"
1404 rm -rf "${OUTPUTDIR}"
1405 eerror "Could not generate netboot package ${OUTPUT_FILE}" ; eend 1
1410 create_netbootpackage
1413 # pack artifacts {{{
1414 if [ -n "$PACK_ARTIFACTS" ]; then
1415 log "Packing artifcats"
1416 einfo "Packing artifacts"
1417 [ -f "${CHROOT_ARCHIVE}" ] && rm -r "${CHROOT_ARCHIVE}"
1418 tar -c -a -f ${CHROOT_ARCHIVE} --preserve-permissions -C "$(dirname ${CHROOT_OUTPUT})" "$(basename ${CHROOT_OUTPUT})"
1423 # log build information to database if grml-live-db is installed and enabled {{{
1425 if [ -d /usr/share/grml-live-db ] ; then
1428 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
1429 [ -n "$DPKG_DATABASE" ] || DPKG_DATABASE=/var/log/grml-live.db
1430 [ -n "$DPKG_DBSCRIPT" ] || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
1431 [ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
1433 if ! [ -x "$DPKG_DBSCRIPT" ] ; then
1434 log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
1435 eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
1439 # disable by default for now, not sure whether really everyone is using a local db file
1440 #if ! touch "$DPKG_DATABASE" ; then
1441 # eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
1445 if ! [ -r "$DPKG_LIST" ] ; then
1446 log "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
1447 ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
1449 einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
1450 log "Logging $DPKG_LIST to database $DPKG_DATABASE"
1451 log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
1454 if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
1470 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
1471 log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
1473 dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
1475 einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
1479 ## END OF FILE #################################################################
1480 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2