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
125 # don't use colors/escape sequences
126 if [ -r /lib/lsb/init-functions ] ; then
127 . /lib/lsb/init-functions
128 ! log_use_fancy_output && NOCOLORS=true
131 if [ -r /etc/grml/lsb-functions ] ; then
132 . /etc/grml/lsb-functions
134 einfo() { echo " [*] $*" ;}
135 eerror() { echo " [!] $*">&2 ;}
136 ewarn() { echo " [x] $*" ;}
138 eindent() { return 0 ;}
139 eoutdent() { return 0 ;}
142 # source main configuration file:
143 LIVE_CONF=/etc/grml/grml-live.conf
147 # umount all directories {{{
149 # make sure we don't leave any mounts - FAI doesn't remove them always
150 umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
151 umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true
152 umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
153 umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
155 # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry
156 if [ -x /usr/lib/fai/mkramdisk ] ; then
157 /usr/lib/fai/mkramdisk -u "$(readlink -f ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true
160 umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true
161 [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
167 rm -f /var/run/fai/fai_softupdate_is_running \
168 /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
169 [ -n "$CONFIGDUMP" ] && rm -f "$CONFIGDUMP"
170 [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR"
172 [ -n "$1" ] && EXIT="$1" || EXIT="1"
173 [ -n "$2" ] && eerror "$2">&2
174 if [ -n "$PACK_ARTIFACTS" ]; then
177 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
178 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
181 if [ -n "$CHOWN_USER" ]; then
182 log "Setting ownership"
183 einfo "Setting ownership"
184 [ -n "${OUTPUT}" -a -d "${OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${OUTPUT}"
185 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${BUILD_OUTPUT}"
186 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}"
187 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}"
188 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}"
189 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && chown -R "${CHOWN_USER}:" "${NETBOOT}"
190 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_ARCHIVE}"
193 log "------------------------------------------------------------------------------"
196 trap bailout 1 2 3 3 6 9 14 15
200 # some important functions {{{
203 # usage: log "string to log"
204 log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; }
206 # cut string at character number int = $1
207 # usage: cut_string 5 "1234567890" will output "12345"
209 [ -n "$2" ] || return 1
210 echo "$2" | head -c "$1"; echo -ne "\n"
213 # prepend int = $1 spaces before string = $2
214 # usage: extend_string_begin 5 "123" will output " 123"
215 extend_string_begin() {
216 [ -n "$2" ] || return 1
217 local COUNT="$(echo $2 | wc -c)"
218 local FILL="$(expr $COUNT - $1)"
219 while [ "$FILL" -gt 1 ] ; do
221 local FILL=$(expr $FILL - 1)
223 while [ "$FILL" -lt 1 ] ; do
225 local FILL=$(expr $FILL + 1)
227 echo "$2" | head -c "$1"; echo -ne "\n"
230 # append int = $1 spaces to string = $2
231 # usage: extend_string_begin 5 "123" will output "123 "
232 extend_string_end() {
233 [ -n "$2" ] || return 1
234 echo -n "$2" | head -c "$1"
235 local COUNT="$(echo $2 | wc -c)"
236 local FILL="$(expr $COUNT - $1)"
237 while [ "$FILL" -gt 1 ] ; do
239 local FILL=$(expr $FILL - 1)
241 while [ "$FILL" -lt 1 ] ; do
243 local FILL=$(expr $FILL + 1)
248 # Copy addonfile $1 from either
249 # * the chroot (via $2, the system path),
250 # * or from TEMPLATE_DIRECTORY/compat (if exists),
251 # * or from the host system (again, using $2),
252 # or warn about the missing file.
255 # * We assume that the chroot always has a "good" version of
256 # the file. Also it makes sources handling easier.
257 # * On unstable, we Recommend the Debian packages containing
258 # these files. The user can override them by putting his
259 # "better" version into the chroot.
260 # * On stable, the Debian packages are probably not available,
261 # or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
262 # our grml-live-compat package installs current file versions.
264 DEST="${BUILD_OUTPUT}/boot/$3"
265 if [ ! -d "${DEST}/" ]; then
268 if [ -e "$CHROOT_OUTPUT/$2/$1" ]; then
269 log "Copying $1 from chroot"
270 cp "$CHROOT_OUTPUT/$2/$1" "${DEST}/"
273 if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
274 log "Copying $1 from grml-live-compat"
275 cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
278 if [ -e "$2/$1" ]; then
279 log "Copying $1 from system"
280 cp "$2/$1" "${DEST}/"
284 msg="Missing addon file: \"$1\""
285 ewarn "$msg" ; eend 1
286 log "copy_addon_file: $msg"
290 # command line parsing {{{
291 while getopts "a:C:c:d:D:g:i:I:o:r:s:t:T:U:v:AbBFnNqQuVz" opt; do
294 A) PACK_ARTIFACTS=1 ;;
297 c) CLASSES="$OPTARG" ;;
298 C) LOCAL_CONFIG="$(readlink -f $OPTARG)" ;;
300 D) GRML_FAI_CONFIG="$(readlink -f $OPTARG)" ;;
301 g) GRML_NAME="$OPTARG" ;;
302 i) ISO_NAME="$OPTARG" ;;
303 I) CHROOT_INSTALL="$OPTARG" ;;
305 N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;;
306 o) OUTPUT="$(readlink -f $OPTARG)" ;;
307 q) SKIP_MKSQUASHFS=1 ;;
309 r) RELEASENAME="$OPTARG" ;;
310 s) SUITE="$OPTARG" ;;
311 t) TEMPLATE_DIRECTORY="$OPTARG";;
312 T) UNPACK_CHROOT="$(readlink -f $OPTARG)" ;;
313 v) VERSION="$OPTARG" ;;
316 U) CHOWN_USER="$OPTARG" ;;
318 z) SQUASHFS_ZLIB=1 ;;
319 ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
322 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
325 # read local (non-packaged) configuration {{{
326 if [ -z "$LOCAL_CONFIG" ]; then
327 if [ -r "/etc/grml/grml-live.local" ]; then
328 LOCAL_CONFIG="/etc/grml/grml-live.local"
331 if [ -n "$LOCAL_CONFIG" ]; then
332 if [ -r "$LOCAL_CONFIG" ]; then
335 eerror "Could not read specified local configuration file \"$LOCAL_CONFIG\"."
338 LOCAL_CONFIG=$(readlink -f "$LOCAL_CONFIG")
343 if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
344 eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated."
345 ewarn "Please set up \${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead."
350 # assume sane defaults (if not set already) {{{
351 [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
352 [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
353 [ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_FULL,$(echo ${ARCH} | tr 'a-z' 'A-Z')"
354 [ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)"
355 [ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators '
356 [ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
357 [ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
358 [ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
359 [ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
360 [ -n "$GRML_NAME" ] || GRML_NAME='grml'
361 [ -n "$HOSTNAME" ] || HOSTNAME='grml'
362 [ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='manifold'
363 [ -n "$NFSROOT_CONF" ] || NFSROOT_CONF="${GRML_FAI_CONFIG}/make-fai-nfsroot.conf"
364 [ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
365 [ -n "$SQUASHFS_EXCLUDES_FILE" ] || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
366 [ -n "$SUITE" ] || SUITE='squeeze'
367 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
368 [ -n "$USERNAME" ] || USERNAME='grml'
369 [ -n "$VERSION" ] || VERSION='0.0.1'
371 # output specific stuff, depends on $OUTPUT (iff not set):
372 [ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live'
373 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
374 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
375 [ -n "$CHROOT_ARCHIVE" ] || CHROOT_ARCHIVE="$OUTPUT/$(basename $CHROOT_OUTPUT).tgz"
376 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
377 [ -n "$LOG_OUTPUT" ] || LOG_OUTPUT="$OUTPUT/grml_logs"
378 [ -n "$REPORTS" ] || REPORTS="${LOG_OUTPUT}/reports/"
379 [ -n "$NETBOOT" ] || NETBOOT="${OUTPUT}/netboot/"
382 # some misc checks before executing FAI {{{
383 [ -n "$CLASSES" ] || bailout 1 "Error: \$CLASSES unset, please set it in $LIVE_CONF or
384 specify it on the command line using the -c option."
385 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
386 specify it on the command line using the -o option."
388 # trim characters that are known to cause problems inside $GRML_NAME;
389 # for example isolinux does not like '-' inside the directory name
390 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
392 # export variables to have them available in fai scripts:
393 [ -n "$GRML_NAME" ] && export GRML_NAME="$GRML_NAME"
394 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
397 # ZERO_LOGFILE - check for backwards compatibility reasons {{{
398 # this was default behaviour until grml-live 0.9.34:
399 if [ -n "$ZERO_LOGFILE" ] ; then
400 PRESERVE_LOGFILE='' # make sure it's cleaned then
401 ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
402 ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
407 # ask user whether the setup is ok {{{
408 if [ -z "$FORCE" ] ; then
410 echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
412 echo " FAI classes: $CLASSES"
413 [ -n "$LOCAL_CONFIG" ] && echo " Configuration: $LOCAL_CONFIG"
414 [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG"
415 echo " main directory: $OUTPUT"
416 [ -n "$UNPACK_CHROOT" ] && echo " Chroot from: $UNPACK_CHROOT"
417 [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT"
418 [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT"
419 [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT"
420 [ -n "$GRML_NAME" ] && echo " Grml name: $GRML_NAME"
421 [ -n "$RELEASENAME" ] && echo " Release name: $RELEASENAME"
422 [ -n "$DATE" ] && echo " Build date: $DATE"
423 [ -n "$VERSION" ] && echo " Grml version: $VERSION"
424 [ -n "$SUITE" ] && echo " Debian suite: $SUITE"
425 [ -n "$ARCH" ] && echo " Architecture: $ARCH"
426 [ -n "$BOOT_METHOD" ] && echo " Boot method: $BOOT_METHOD"
427 [ -n "$HYBRID_METHOD" ] && echo " Hybrid method: $HYBRID_METHOD"
428 [ -n "$TEMPLATE_DIRECTORY" ] && echo " Template files: $TEMPLATE_DIRECTORY"
429 [ -n "$CHROOT_INSTALL" ] && echo " Install files from directory to chroot: $CHROOT_INSTALL"
430 [ -n "$BOOTID" ] && echo " Boot identifier: $BOOTID"
431 [ -n "$NO_BOOTID" ] && echo " Skipping bootid feature."
432 [ -n "$CHOWN_USER" ] && echo " Output owner: $CHOWN_USER"
433 [ -n "$DEFAULT_BOOTOPTIONS" ] && echo " Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
434 [ -n "$FAI_ARGS" ] && echo " Additional arguments for FAI: $FAI_ARGS"
435 [ -n "$LOGFILE" ] && echo " Logging to file: $LOGFILE"
436 [ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA/XZ) compression."
437 [ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
438 [ -n "$VERBOSE" ] && echo " Using VERBOSE mode."
439 [ -n "$PACK_ARTIFACTS" ] && echo " Will prepare packed artifacts and ensure clean build."
440 [ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation."
441 if [ -n "$BOOTSTRAP_ONLY" ] ; then
442 echo " Bootstrapping only and not building (files for) ISO."
444 [ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file."
445 [ -n "$SKIP_NETBOOT" ] && echo " Skipping creation of NETBOOT package."
446 [ -n "$SKIP_MKISOFS" ] && echo " Skipping creation of ISO file."
447 [ -n "$BUILD_ONLY" ] && echo " Executing BUILD_ONLY instead of fresh installation or UPDATE."
448 [ -n "$BUILD_DIRTY" ] && echo " Executing BUILD_DIRTY to leave chroot untouched."
451 echo -n "Is this ok for you? [y/N] "
453 if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
454 bailout 1 "Exiting as requested."
460 # clean up before start {{{
461 if [ -n "${PACK_ARTIFACTS}" ]; then
462 echo "Wiping old artifacts"
463 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
464 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
465 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && rm -r "${ISO_OUTPUT}"
466 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && rm -r "${LOG_OUTPUT}"
467 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && rm -r "${NETBOOT}"
471 # create log file {{{
472 [ -n "$LOGFILE" ] || LOGFILE=${LOG_OUTPUT}/grml-live.log
473 mkdir -p $(dirname "${LOGFILE}")
475 chown root:adm $LOGFILE
479 # clean/zero/remove logfiles {{{
481 if [ -n "$PRESERVE_LOGFILE" ] ; then
482 echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
484 # make sure it is empty (as it is e.g. appended to grml-live-db)
488 if [ -n "$ZERO_FAI_LOGFILE" ] ; then
489 if [ -d /var/log/fai/"$HOSTNAME" ] ; then
490 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
491 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
492 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
493 rm -f /var/log/fai/"$HOSTNAME"/last \
494 /var/log/fai/"$HOSTNAME"/last-dirinstall \
495 /var/log/fai/"$HOSTNAME"/last-softupdate
500 # source config and startup {{{
501 if [ -n "$CONFIG" ] ; then
502 if ! [ -f "$CONFIG" ] ; then
503 log "Error: $CONFIG could not be read. Exiting. [$(date)]"
504 eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
507 log "Sourcing $CONFIG"
512 start_seconds=$(cut -d . -f 1 /proc/uptime)
513 log "------------------------------------------------------------------------------"
514 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
515 log "Using local config file: $LOCAL_CONFIG"
516 log "Executed grml-live command line:"
519 einfo "Logging actions to logfile $LOGFILE"
522 # dump config variables into file, for script access {{{
525 '^(GRML_NAME|RELEASENAME|DATE|VERSION|SUITE|ARCH|DISTRI_NAME|USERNAME|HOSTNAME|APT_PROXY)=' \
530 if [ -n "${UNPACK_CHROOT}" ]; then
531 log "Unpacking chroot from ${UNPACK_CHROOT}"
532 einfo "Unpacking chroot from ${UNPACK_CHROOT}"
533 [ -d "$CHROOT_OUTPUT" ] || mkdir -p "${CHROOT_OUTPUT}"
534 tar -xf "${UNPACK_CHROOT}" -C "${CHROOT_OUTPUT}/" --strip-components 1 ; RC=$?
535 if [ "$RC" != 0 ] ; then
543 # cleanup CHROOT_ARCHIVE now {{{
544 if [ -n "${PACK_ARTIFACTS}" ]; then
545 # can't do this earlier, as UNPACK_CHROOT might point to CHROOT_ARCHIVE
546 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}"
550 # on-the-fly configuration {{{
551 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
552 sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
555 # does this suck? YES!
556 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
558 unstable) SUITE='sid' ; CLASSES="DEBIAN_UNSTABLE,$CLASSES" ;;
559 *) CLASSES="DEBIAN_$(echo $SUITE | tr 'a-z' 'A-Z'),$CLASSES";;
561 export SUITE # make sure it's available in FAI scripts
563 for file in "$LIVE_CONF" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do
564 if [ -n "$file" ] ; then
565 sed "s|^FAI_DEBOOTSTRAP=\"[a-z]* |FAI_DEBOOTSTRAP=\"$SUITE |" "$file" | sponge "$file"
569 # validate whether the specified architecture class matches the
570 # architecture (option), otherwise installation of kernel will fail
571 if echo $CLASSES | grep -qi i386 ; then
572 if ! [[ "$ARCH" == "i386" ]] ; then
573 log "Error: You specified the I386 class but are trying to build something else (AMD64?)."
574 eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
575 eerror "Tip: Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
579 elif echo $CLASSES | grep -qi amd64 ; then
580 if ! [[ "$ARCH" == "amd64" ]] ; then
581 log "Error: You specified the AMD64 class but are trying to build something else (I386?)."
582 eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
583 eerror "Tip: Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
589 if grep -q -- 'FAI_DEBOOTSTRAP_OPTS.*--arch' "$NFSROOT_CONF" ; then
590 sed "s/--arch [a-z0-9]* /--arch $ARCH /" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
592 sed "s|^FAI_DEBOOTSTRAP_OPTS=\"\(.*\)|FAI_DEBOOTSTRAP_OPTS=\"--arch $ARCH \1|" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
596 # CHROOT_OUTPUT - execute FAI {{{
597 if [ -n "$BUILD_DIRTY" ]; then
598 log "Skipping stage 'fai' as requested via option -B"
599 ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
601 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
603 # provide inform fai about the ISO we build
604 [ -d "$CHROOT_OUTPUT/etc/" ] || mkdir -p "$CHROOT_OUTPUT/etc/"
605 echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
606 [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
607 [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
609 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
610 FAI_ACTION=softupdate
612 FAI_ACTION=dirinstall
615 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
616 if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
617 log "Error: does not look like you have a working chroot. Updating/building not possible."
618 eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
624 if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
625 log "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
626 ewarn "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
628 mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
630 if [ -n "${MIRROR_DIRECTORY}" ] ; then
631 mkdir -p "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
632 mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
635 mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
636 mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
638 # tell dpkg to use "unsafe io" during the build
639 [ -d "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d" ] || mkdir -p "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d"
640 echo force-unsafe-io > "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
642 log "Executed FAI command line:"
643 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"
644 BUILD_ONLY="$BUILD_ONLY" BOOTSTRAP_ONLY="$BOOTSTRAP_ONLY" GRML_LIVE_CONFIG="$CONFIGDUMP" fai $VERBOSE \
645 -C "$GRML_FAI_CONFIG" -s "file:///$GRML_FAI_CONFIG/config" -c"$CLASSES" \
646 -u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
647 RC="$PIPESTATUS" # notice: bash-only
649 rm -f "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
651 FORCE_ISO_REBUILD=true
653 if [ "$RC" != 0 ] ; then
654 log "Error: critical error while executing fai [exit code ${RC}]. Exiting."
655 eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
658 einfo "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
659 log "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
660 echo "$GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]" > $CHROOT_OUTPUT/etc/grml_version
661 chmod 644 $CHROOT_OUTPUT/etc/grml_version
662 einfo "Rebuilding initramfs"
663 # make sure new /etc/grml_version reaches initramfs, iterate over all
664 # present kernel versions (note: we can't really handle more than one
665 # kernel version anyway right now)
666 # chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :(
667 for initrd in "$(basename $CHROOT_OUTPUT/boot/vmlinuz-*)" ; do
668 if ! chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -c ; then
669 einfo "Creating fresh initrd did not work, trying update instead:"
670 log "Creating fresh initrd did not work, trying update instead:"
671 chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -u
677 # move fai logs into grml_logs directory
678 mkdir -p "$LOG_OUTPUT"/fai/
679 cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
680 rm -rf "$CHROOT_OUTPUT"/var/log/fai
681 # copy fai package list
682 cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/
684 chown root:adm "$LOG_OUTPUT"/fai/*
685 chmod 664 "$LOG_OUTPUT"/fai/*
689 # notice: 'fai dirinstall' does not seem to exit appropriate, so:
691 CHECKLOG="$LOG_OUTPUT"/fai/
692 if [ -r "$CHECKLOG/software.log" ] ; then
693 # 1 errors during executing of commands
694 grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1
695 grep 'E: Method http has died unexpectedly!' $CHECKLOG/software.log >> $LOGFILE && ERROR=2
696 grep 'ERROR: chroot' $CHECKLOG/software.log >> $LOGFILE && ERROR=3
697 grep 'E: Failed to fetch' $CHECKLOG/software.log >> $LOGFILE && ERROR=4
698 grep 'Unable to write mmap - msync (28 No space left on device)' $CHECKLOG/software.log >> $LOGFILE && ERROR=5
701 if [ -r "$CHECKLOG/shell.log" ] ; then
702 grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=6
705 if [ -n "$ERROR" ] ; then
706 log "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
707 eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
708 eerror "Note: check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
712 log "Finished execution of stage 'fai dirinstall' [$(date)]"
713 einfo "Finished execution of stage 'fai dirinstall'"
719 # package validator {{{
720 CHECKLOG=/var/log/fai/$HOSTNAME/last
721 if [ -r "$CHECKLOG/dpkg.selections" ] ; then
722 package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}')
724 package_count="unknown"
728 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
730 # check for missing packages
731 if ! [ -s "$CHECKLOG/package_errors.log" ] ; then
732 einfo "No missing packages found, generating empty junit report."
734 cat > "${REPORT_MISSING_PACKAGES}" << EOF
735 <?xml version="1.0" encoding="UTF-8"?>
736 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="0" errors="0" skipped="0" assertions="0">
737 <testcase name="test_missing_packages" time="0" assertions="0">
747 einfo "Missing packages found, generating junit report."
749 if [ -r "$CHECKLOG/package_errors.log" ] ; then
750 package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}')
752 package_errors="unknown"
756 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
758 cat > "${REPORT_MISSING_PACKAGES}" << EOF
759 <?xml version="1.0" encoding="UTF-8"?>
760 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
763 for package in $(awk '{print $5}' "${CHECKLOG}/package_errors.log" | sed 's/\.$//') ; do
764 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
765 <testcase name="test_missing_packages_${package}" time="0" assertions="0">
766 <failure type="RuntimeError" message="Package ${package} is missing">
767 Package $package is missing in chroot
773 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
782 if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
783 eerror "The following packages were requested for installation but could not be processed:"
784 cat "$CHECKLOG/package_errors.log"
785 eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
789 ewarn "The following packages were requested for installation but could not be processed:"
790 cat "$CHECKLOG/package_errors.log"
796 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
797 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
798 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
801 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
802 if [ -n "$BOOTSTRAP_ONLY" ] ; then
803 log "Skipping stage 'boot' as building with bootstrap only."
804 ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
806 if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
807 log "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
808 ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
811 [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
812 [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
814 # if we don't have an initrd we a) can't boot and b) there was an error
815 # during build, so check for the file:
816 INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
817 if [ -n "$INITRD" ] ; then
818 cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
819 find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
821 log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
822 eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
826 KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
827 if [ -n "$KERNEL_IMAGE" ] ; then
828 cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/linux26
830 log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
831 eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
835 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
836 if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
837 log "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
838 eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
842 # copy _required_ isolinux files
843 for file in ifcpu64.c32 isolinux.bin vesamenu.c32; do
844 copy_addon_file "${file}" /usr/lib/syslinux isolinux
847 # *always* copy files to output directory so the variables
848 # get adjusted according to the build.
849 cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
851 if [ -n "$NO_ADDONS" ] ; then
852 log "Skipping installation of boot addons as requested via \$NO_ADDONS."
853 einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
855 if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
856 log "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
857 ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
859 # copy addons from system packages or grml-live-compat
860 copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
861 copy_addon_file pci.ids /usr/share/misc addons
862 copy_addon_file memtest86+.bin /boot addons
863 for file in memdisk chain.c32 hdt.c32 menu.c32; do
864 copy_addon_file "${file}" /usr/lib/syslinux addons
867 # make memtest filename FAT16/8.3 compatible
868 mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
869 "${BUILD_OUTPUT}/boot/addons/memtest"
871 # copy only files so we can handle bsd4grml on its own
872 for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
873 test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
876 if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
877 log "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
878 einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
880 if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
881 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
883 log "Missing addon file: bsd4grml"
884 ewarn "Missing addon file: bsd4grml" ; eend 0
888 fi # no "$TEMPLATE_DIRECTORY"/boot/addons
891 if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
892 mkdir -p "${BUILD_OUTPUT}/boot/grub"
894 cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
896 # copy grub files from target
897 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/
898 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/
899 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/
900 cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
901 cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
903 if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
904 log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
905 eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
909 [ -d "$BUILD_OUTPUT"/GRML ] || mkdir "$BUILD_OUTPUT"/GRML
910 cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/
912 # adjust boot splash information:
913 RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
914 RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
915 RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
917 if [ -r "$BUILD_OUTPUT"/GRML/grml-version ] ; then
918 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
919 sed -i "s/%DATE%/$DATE/" "$BUILD_OUTPUT"/GRML/grml-version
922 # make sure the squashfs filename is set accordingly:
923 SQUASHFS_NAME="$GRML_NAME.squashfs"
925 if [ -n "$NO_BOOTID" ] ; then
926 log 'Skipping bootid feature as requested via $NO_BOOTID.'
927 einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
929 [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
930 [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
931 einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
932 log "Generating /conf/bootid.txt with entry ${BOOTID}."
933 echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
937 # adjust all variables in the templates with the according distribution information
938 for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
939 "${BUILD_OUTPUT}"/boot/grub/* ; do
940 if [ -r "${file}" ] ; then
941 sed -i "s/%ARCH%/$ARCH/g" "${file}"
942 sed -i "s/%DATE%/$DATE/g" "${file}"
943 sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g" "${file}"
944 sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g" "${file}"
945 sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g" "${file}"
946 sed -i "s/%GRML_NAME%/$GRML_NAME/g" "${file}"
947 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g" "${file}"
948 sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g" "${file}"
949 sed -i "s/%SHORT_NAME%/$SHORT_NAME/g" "${file}"
950 sed -i "s/%VERSION%/$VERSION/g" "${file}"
952 [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s/ boot=live/ boot=live $DEFAULT_BOOTOPTIONS/" "${file}"
954 if [ -n "$NO_BOOTID" ] ; then
955 sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
957 sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
962 # adjust bootsplash accordingly but make sure the string has the according lenght
963 SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
964 SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
965 for file in f4 f5 ; do
966 if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
967 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
968 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
972 # generate addon list
973 rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
974 for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
975 include_name=$(basename "$name")
976 echo "include $include_name" >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
979 if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
980 log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
981 echo "include grmlmain.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
982 echo "include default.cfg" > "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
983 echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
984 echo "include grml.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
986 for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
987 echo "include $(basename $f)" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
990 echo "include options.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
991 if [ ! -n "$NO_ADDONS" ] ; then
992 echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
994 echo "include isoprompt.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
995 echo "include hd.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
996 echo "include hidden.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
997 else # assume we are building a custom distribution:
998 log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
999 einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1000 if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1001 log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1003 einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1007 log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1008 echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1009 [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1013 # use old style console based isolinux method only if requested:
1014 if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
1015 log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1016 einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1017 if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1018 einfo "include for console.cfg already found, nothing to do."
1021 log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1022 einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1023 echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1027 log 'Using graphical boot menu.'
1028 if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
1029 log "include for vesamenu.cfg already found, nothing to do."
1031 log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1032 echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1036 if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
1037 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
1040 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
1041 if ! [ -r "$DPKG_LIST" ] ; then
1042 ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
1044 einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
1045 cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
1049 # autostart for Windows:
1050 if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
1051 cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
1054 FORCE_ISO_REBUILD=true
1055 einfo "Finished execution of stage 'boot'" ; eend 0
1059 log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
1060 eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
1064 # support installation of local files into the chroot/ISO
1065 if [ -n "$CHROOT_INSTALL" ] ; then
1066 if ! [ -d "$CHROOT_INSTALL" ] ; then
1067 log "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1068 ewarn "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1070 log "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1071 einfo "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1072 rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
1074 einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
1075 FORCE_ISO_REBUILD=true
1079 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1080 log "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
1081 ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
1082 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
1083 log "Skipping stage 'squashfs' as requested via option -q or -N"
1084 ewarn "Skipping stage 'squashfs' as requested via option -q or -N" ; eend 0
1086 [ -d "$BUILD_OUTPUT"/live ] || mkdir "$BUILD_OUTPUT"/live
1087 # make sure we don't leave (even an empty) base.tgz:
1088 [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
1090 # if unconfigured default to squashfs-tools' mksquashfs binary
1091 if [ -z "$SQUASHFS_BINARY" ] ; then
1092 SQUASHFS_BINARY='mksquashfs'
1095 if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
1096 log "Using mksquashfs binary ${SQUASHFS_BINARY}"
1097 einfo "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
1099 log "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
1100 eerror "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
1104 # use sane defaults if $SQUASHFS_OPTIONS isn't set
1105 if [ -z "$SQUASHFS_OPTIONS" ] ; then
1106 # use blocksize 256k as this gives best result with regards to time + compression
1107 SQUASHFS_OPTIONS="-b 256k"
1109 # set lzma/xz compression by default, unless -z option has been specified on command line
1110 if [ -z "$SQUASHFS_ZLIB" ] ; then
1111 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp xz"
1113 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp gzip"
1117 # support exclusion of files via exclude-file:
1118 if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
1119 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE -wildcards"
1122 # get rid of unnecessary files when building grml-small for final release:
1123 if echo "$CLASSES" | grep -q GRML_SMALL ; then
1124 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
1128 SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
1130 # informational stuff
1131 [ -n "$SQUASHFS_OPTIONS" ] && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
1132 [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
1133 einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
1135 log "$SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS"
1137 if $SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
1138 -noappend $SQUASHFS_OPTIONS 2>"${SQUASHFS_STDERR}" ; then
1139 echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
1140 log "Finished execution of stage 'squashfs' [$(date)]"
1141 einfo "Finished execution of stage 'squashfs'" ; eend 0
1143 log "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
1144 log "$(cat $SQUASHFS_STDERR)"
1145 eerror "Error: there was a critical error executing stage 'squashfs':"
1146 cat "${SQUASHFS_STDERR}"
1151 FORCE_ISO_REBUILD=true
1154 # create md5sum file:
1155 if [ -z "$BOOTSTRAP_ONLY" ] ; then
1156 ( cd $BUILD_OUTPUT/GRML &&
1157 find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
1161 # ISO_OUTPUT - mkisofs {{{
1162 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
1163 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
1165 if [ "$BOOT_METHOD" = "isolinux" ] ; then
1166 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
1167 elif [ "$BOOT_METHOD" = "grub2" ] ; then
1168 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
1171 # Just until http://bts.grml.org/grml/issue945 has been resolved.
1172 # HYBRID_METHOD defaults to manifold, so make sure the default works OOTB.
1173 if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
1174 log "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1175 ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1176 HYBRID_METHOD='grub2'
1180 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
1181 log "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
1182 ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
1183 elif [ -n "$SKIP_MKISOFS" ] ; then
1184 log "Skipping stage 'iso build' as requested via option -n or -N"
1185 ewarn "Skipping stage 'iso build' as requested via option -n or -N" ; eend 0
1187 mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
1189 if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; then
1190 log "Forcing rebuild of ISO because files on ISO have been modified."
1191 einfo "Forcing rebuild of ISO because files on ISO have been modified."
1194 # support xorriso as well mkisofs and genisoimage
1195 if which xorriso >/dev/null 2>&1 ; then
1196 MKISOFS='xorriso -as mkisofs'
1197 elif which mkisofs >/dev/null 2>&1; then
1199 elif which genisoimage >/dev/null 2>&1; then
1200 MKISOFS='genisoimage'
1202 log "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO."
1203 eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1
1209 # using -eltorito-alt-boot is limited to xorriso for now
1212 einfo "Using xorriso for ISO generation." ; eend 0
1215 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
1216 log "Disabling (U)EFI boot support since xorriso version is not recent enough."
1217 ewarn "Disabling (U)EFI boot support since xorriso version is not recent enough." ; eend 0
1219 log "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support."
1220 einfo "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support." ; eend 0
1222 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" ] ; then
1223 einfo "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1224 log "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1225 mv "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" "${BUILD_OUTPUT}/boot/efi.img"
1229 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" ] ; then
1230 einfo "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1231 log "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1232 mkdir -p "${BUILD_OUTPUT}/efi/boot/"
1233 mv "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi"
1237 if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then
1238 einfo "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1239 log "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1240 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
1252 if cd "$BUILD_OUTPUT" ; then
1253 if [ "$BOOT_METHOD" = "grub2" ]; then
1254 # make a 2048-byte bootsector for El Torito
1255 dd if=/dev/zero of=boot/grub/toriboot.bin bs=512 count=4 2>/dev/null
1256 # those are in 2048-byte sectors, so 1 16 matches 4 63 below
1257 echo 1 16 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -B 11 | \
1258 dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
1260 log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
1261 $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
1262 -l -r -J $BOOT_ARGS -no-pad \
1263 -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
1264 # both of these need core.img there, so it’s easier to write it here
1265 if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
1266 # must be <= 30720 bytes
1267 dd if=boot/grub/core.img of="${ISO_OUTPUT}/${ISO_NAME}" \
1268 conv=notrunc bs=512 seek=4 2>/dev/null
1271 # pad the output ISO to multiples of 256 KiB for partition table support
1272 siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
1273 cyls=$((siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
1274 siz=$((cyls * 16 * 32 * 512)) # size after padding
1275 dd if=/dev/zero bs=1 count=1 seek=$((siz - 1)) \
1276 of="${ISO_OUTPUT}/${ISO_NAME}" 2>/dev/null
1278 # support disabling hybrid ISO image
1279 if [ "$HYBRID_METHOD" = "disable" ] ; then\
1280 log "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1281 einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1283 elif [ "$HYBRID_METHOD" = "manifold" ] ; then
1284 # isoinfo is part of both mkisofs and genisoimage so we're good
1285 bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
1286 sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p')
1287 if ! [ -r boot/grub/core.img ] ; then
1288 ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
1289 elif [ "${bootoff:-0}" -lt 1 ] ; then
1290 ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
1292 log "Creating hybrid ISO file with manifold method"
1293 einfo "Creating hybrid ISO file with manifold method"
1294 if [ "$HYBRID_METHOD" = "grub2" ] ; then
1295 # 512 bytes: MBR, partition table, load GRUB 2
1296 echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
1298 # read only one but 2048-byte sized (scale: << 2) sector
1299 echo $bootoff $bootoff | \
1300 mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
1301 fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
1304 # use isohybrid as default
1306 if ! which isohybrid >/dev/null 2>&1 ; then
1307 bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
1309 log "Creating hybrid ISO file with isohybrid method"
1310 einfo "Creating hybrid ISO file with isohybrid method"
1311 # Notes for consideration:
1312 # "-entry 4 -type 1c"
1313 # * using 4 as the partition number is supposed to help with BIOSes
1314 # that only support USB-Zip boot
1315 # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
1316 # (hidden NTFS, IIRC), as the partition type is sometimes needed
1317 # to get the BIOS even look at the partition created by isohybrid
1318 if isohybrid --help | grep -q -- --uefi ; then
1319 einfo "Detected uefi support for isohybrid, enabling."
1320 ISOHYBRID_OPTIONS=--uefi
1323 log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
1324 isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
1329 # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
1330 case $CLASSES in *RELEASE*)
1333 if cd $ISO_OUTPUT ; then
1334 md5sum ${ISO_NAME} > ${ISO_NAME}.md5 && \
1335 touch -r ${ISO_NAME} ${ISO_NAME}.md5
1336 sha1sum ${ISO_NAME} > ${ISO_NAME}.sha1 && \
1337 touch -r ${ISO_NAME} ${ISO_NAME}.sha1
1346 if [ "$RC" = 0 ] ; then
1347 log "Finished execution of stage 'iso build' [$(date)]"
1348 einfo "Finished execution of stage 'iso build'" ; eend 0
1350 log "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
1351 eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
1357 # netboot package {{{
1358 create_netbootpackage() {
1359 local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2"
1361 if [ -f "${OUTPUT_FILE}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1362 log "Skipping stage 'netboot' as $OUTPUT_FILE exists already."
1363 ewarn "Skipping stage 'netboot' as $OUTPUT_FILE exists already." ; eend 0
1365 elif [ -n "$SKIP_NETBOOT" ] ; then
1366 log "Skipping stage 'netboot' as requested via option -Q"
1367 ewarn "Skipping stage 'netboot' as requested via option -Q" ; eend 0
1373 if ! [ -r "${CHROOT}/usr/lib/syslinux/pxelinux.0" ] ; then
1374 ewarn "File /usr/lib/syslinux/pxelinux.0 not found in build chroot." ; eend 0
1376 einfo "Install syslinux[-common] package in chroot to get a netboot package."
1381 local OUTPUTDIR="${NETBOOT}/build_tmp"
1382 local WORKING_DIR="${OUTPUTDIR}/grml_netboot_package_${GRML_NAME}_${VERSION}/tftpboot/"
1384 mkdir -p "$WORKING_DIR"
1386 cp "${CHROOT_OUTPUT}"/boot/vmlinuz-* "$WORKING_DIR"/linux26
1387 cp "${CHROOT_OUTPUT}"/boot/initrd.img-* "$WORKING_DIR"/initrd.img
1388 cp "${CHROOT_OUTPUT}"/usr/lib/syslinux/pxelinux.0 "${WORKING_DIR}/pxelinux.0"
1390 if [ -r "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" ] ; then
1391 mkdir -p "${WORKING_DIR}/pxelinux.cfg/default"
1392 cp "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" "${WORKING_DIR}/pxelinux.cfg/default"
1394 ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found." ; eend 0
1397 mkdir -p "${WORKING_DIR}/pxelinux.cfg"
1399 if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
1400 einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0
1401 rm -rf "${OUTPUTDIR}"
1403 rm -rf "${OUTPUTDIR}"
1404 eerror "Could not generate netboot package ${OUTPUT_FILE}" ; eend 1
1409 create_netbootpackage
1412 # pack artifacts {{{
1413 if [ -n "$PACK_ARTIFACTS" ]; then
1414 log "Packing artifcats"
1415 einfo "Packing artifacts"
1416 [ -f "${CHROOT_ARCHIVE}" ] && rm -r "${CHROOT_ARCHIVE}"
1417 tar -c -a -f ${CHROOT_ARCHIVE} --preserve-permissions -C "$(dirname ${CHROOT_OUTPUT})" "$(basename ${CHROOT_OUTPUT})"
1422 # log build information to database if grml-live-db is installed and enabled {{{
1424 if [ -d /usr/share/grml-live-db ] ; then
1427 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
1428 [ -n "$DPKG_DATABASE" ] || DPKG_DATABASE=/var/log/grml-live.db
1429 [ -n "$DPKG_DBSCRIPT" ] || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
1430 [ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
1432 if ! [ -x "$DPKG_DBSCRIPT" ] ; then
1433 log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
1434 eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
1438 # disable by default for now, not sure whether really everyone is using a local db file
1439 #if ! touch "$DPKG_DATABASE" ; then
1440 # eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
1444 if ! [ -r "$DPKG_LIST" ] ; then
1445 log "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
1446 ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
1448 einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
1449 log "Logging $DPKG_LIST to database $DPKG_DATABASE"
1450 log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
1453 if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
1469 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
1470 log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
1472 dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
1474 einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
1478 ## END OF FILE #################################################################
1479 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2