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 -e <iso_name> extract ISO and squashfs contents from iso_name
50 -F force execution without prompting
51 -g <grml_name> set the grml flavour name
52 -h display short usage information and exit
53 -i <iso_name> name of ISO
54 -I <src_directory> directory which provides files that should become
55 part of the chroot/ISO
56 -n skip generation of ISO
57 -N bootstrap (build chroot) only, do not create files for ISO
58 -o <output_directory> main output directory of the build process
60 -Q skip netboot package build
61 -r <release_name> release name
62 -s <suite> Debian suite; values: etch, lenny, squeeze, sid
63 -t <template_directory> place of the templates
64 -T <tar_name> unpack chroot tar archive before starting
65 -u update existing chroot instead of rebuilding it from scratch
66 -U <username> arrange output to be owned by specified username
67 -v <version_number> specify version number of the release
68 -V increase verbosity in the build process
69 -z use ZLIB instead of LZMA/XZ compression
74 $PN -c GRMLBASE,GRML_FULL,AMD64 -o /dev/shm/grml
75 $PN -c GRMLBASE,GRML_FULL,AMD64 -i grml_0.0-1.iso -v 0.0-1
76 $PN -c GRMLBASE,GRML_FULL,AMD64 -s sid -V -r 'grml-live rocks'
78 More details: man grml-live + /usr/share/doc/grml-live/grml-live.html
79 http://grml.org/grml-live/
81 Please send your bug reports and feedback to the grml-team: http://grml.org/bugs/
85 # make sure it's possible to get usage information without being
86 # root or actually executing the script
87 if [ "$1" = '-h' -o "$1" = '--help' ] ; then
89 [ "$(id -u 2>/dev/null)" != 0 ] && echo "Please notice that this script requires root permissions."
94 # some runtime checks {{{
95 # we need root permissions for the build-process:
96 if [ "$(id -u 2>/dev/null)" != 0 ] ; then
97 echo "Error: please run this script with uid 0 (root)." >&2
101 if [ -r /var/run/fai/FAI_INSTALLATION_IN_PROGRESS ] ; then
102 echo "/usr/sbin/fai already running or was aborted before.">&2
103 echo "You may remove /var/run/fai/FAI_INSTALLATION_IN_PROGRESS and try again.">&2
108 if [ -r /var/run/fai/fai_softupdate_is_running ] ; then
109 echo "/usr/sbin/fai softupdate already running or was aborted before.">&2
110 echo "You may remove /var/run/fai/fai_softupdate_is_running and try again.">&2
115 # lsb-functions and configuration stuff {{{
116 # make sure they are not set by default
127 # don't use colors/escape sequences
128 if [ -r /lib/lsb/init-functions ] ; then
129 . /lib/lsb/init-functions
130 ! log_use_fancy_output && NOCOLORS=true
133 if [ -r /etc/grml/lsb-functions ] ; then
134 . /etc/grml/lsb-functions
136 einfo() { echo " [*] $*" ;}
137 eerror() { echo " [!] $*">&2 ;}
138 ewarn() { echo " [x] $*" ;}
140 eindent() { return 0 ;}
141 eoutdent() { return 0 ;}
144 # source main configuration file:
145 LIVE_CONF=/etc/grml/grml-live.conf
149 # umount all directories {{{
151 # make sure we don't leave any mounts - FAI doesn't remove them always
152 umount $CHROOT_OUTPUT/proc/sys/fs/binfmt_misc 2>/dev/null || /bin/true
153 umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
154 umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true
155 umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
156 umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
158 # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry
159 if [ -x /usr/lib/fai/mkramdisk ] ; then
160 /usr/lib/fai/mkramdisk -u "$(readlink -f ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true
163 umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true
164 [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
170 rm -f /var/run/fai/fai_softupdate_is_running \
171 /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
172 [ -n "$CONFIGDUMP" ] && rm -f "$CONFIGDUMP"
173 [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR"
175 [ -n "$1" ] && EXIT="$1" || EXIT="1"
176 [ -n "$2" ] && eerror "$2">&2
177 if [ -n "$PACK_ARTIFACTS" ]; then
180 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
181 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
184 if [ -n "$CHOWN_USER" ]; then
185 log "Setting ownership"
186 einfo "Setting ownership"
187 [ -n "${OUTPUT}" -a -d "${OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${OUTPUT}"
188 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${BUILD_OUTPUT}"
189 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}"
190 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}"
191 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}"
192 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && chown -R "${CHOWN_USER}:" "${NETBOOT}"
193 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_ARCHIVE}"
196 log "------------------------------------------------------------------------------"
199 trap bailout 1 2 3 3 6 9 14 15
203 # some important functions {{{
206 # usage: log "string to log"
207 log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; }
209 # cut string at character number int = $1
210 # usage: cut_string 5 "1234567890" will output "12345"
212 [ -n "$2" ] || return 1
213 echo "$2" | head -c "$1"; echo -ne "\n"
216 # prepend int = $1 spaces before string = $2
217 # usage: extend_string_begin 5 "123" will output " 123"
218 extend_string_begin() {
219 [ -n "$2" ] || return 1
220 local COUNT="$(echo $2 | wc -c)"
221 local FILL="$(expr $COUNT - $1)"
222 while [ "$FILL" -gt 1 ] ; do
224 local FILL=$(expr $FILL - 1)
226 while [ "$FILL" -lt 1 ] ; do
228 local FILL=$(expr $FILL + 1)
230 echo "$2" | head -c "$1"; echo -ne "\n"
233 # append int = $1 spaces to string = $2
234 # usage: extend_string_begin 5 "123" will output "123 "
235 extend_string_end() {
236 [ -n "$2" ] || return 1
237 echo -n "$2" | head -c "$1"
238 local COUNT="$(echo $2 | wc -c)"
239 local FILL="$(expr $COUNT - $1)"
240 while [ "$FILL" -gt 1 ] ; do
242 local FILL=$(expr $FILL - 1)
244 while [ "$FILL" -lt 1 ] ; do
246 local FILL=$(expr $FILL + 1)
251 # Copy addonfile $1 from either
252 # * the chroot (via $2, the system path),
253 # * or from TEMPLATE_DIRECTORY/compat (if exists),
254 # * or from the host system (again, using $2),
255 # or warn about the missing file.
258 # * We assume that the chroot always has a "good" version of
259 # the file. Also it makes sources handling easier.
260 # * On unstable, we Recommend the Debian packages containing
261 # these files. The user can override them by putting his
262 # "better" version into the chroot.
263 # * On stable, the Debian packages are probably not available,
264 # or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
265 # our grml-live-compat package installs current file versions.
267 DEST="${BUILD_OUTPUT}/boot/$3"
268 if [ ! -d "${DEST}/" ]; then
271 if [ -e "$CHROOT_OUTPUT/$2/$1" ]; then
272 log "Copying $1 from chroot"
273 cp "$CHROOT_OUTPUT/$2/$1" "${DEST}/"
276 if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
277 log "Copying $1 from grml-live-compat"
278 cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
281 if [ -e "$2/$1" ]; then
282 log "Copying $1 from system"
283 cp "$2/$1" "${DEST}/"
287 msg="Missing addon file: \"$1\""
288 ewarn "$msg" ; eend 1
289 log "copy_addon_file: $msg"
293 # command line parsing {{{
294 while getopts "a:C:c:d:D:e:g:i:I:o:r:s:t:T:U:v:AbBFnNqQuVz" opt; do
297 A) PACK_ARTIFACTS=1 ;;
300 c) CLASSES="$OPTARG" ;;
301 C) LOCAL_CONFIG="$(readlink -f $OPTARG)" ;;
303 D) GRML_FAI_CONFIG="$(readlink -f $OPTARG)" ;;
304 e) EXTRACT_ISO_NAME="$(readlink -f $OPTARG)" ;;
305 g) GRML_NAME="$OPTARG" ;;
306 i) ISO_NAME="$OPTARG" ;;
307 I) CHROOT_INSTALL="$OPTARG" ;;
309 N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;;
310 o) OUTPUT="$(readlink -f $OPTARG)" ;;
311 q) SKIP_MKSQUASHFS=1 ;;
313 r) RELEASENAME="$OPTARG" ;;
314 s) SUITE="$OPTARG" ;;
315 t) TEMPLATE_DIRECTORY="$OPTARG";;
316 T) UNPACK_CHROOT="$(readlink -f $OPTARG)" ;;
317 v) VERSION="$OPTARG" ;;
320 U) CHOWN_USER="$OPTARG" ;;
322 z) SQUASHFS_ZLIB=1 ;;
323 ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
326 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
329 # read local (non-packaged) configuration {{{
330 if [ -z "$LOCAL_CONFIG" ]; then
331 if [ -r "/etc/grml/grml-live.local" ]; then
332 LOCAL_CONFIG="/etc/grml/grml-live.local"
335 if [ -n "$LOCAL_CONFIG" ]; then
336 if [ -r "$LOCAL_CONFIG" ]; then
339 eerror "Could not read specified local configuration file \"$LOCAL_CONFIG\"."
342 LOCAL_CONFIG=$(readlink -f "$LOCAL_CONFIG")
347 if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
348 eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated."
349 ewarn "Please set up \${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead."
354 # assume sane defaults (if not set already) {{{
355 [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
356 [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
357 [ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_FULL,$(echo ${ARCH} | tr 'a-z' 'A-Z')"
358 [ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)"
359 [ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators '
360 [ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
361 [ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
362 [ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
363 [ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
364 [ -n "$GRML_NAME" ] || GRML_NAME='grml'
365 [ -n "$HOSTNAME" ] || HOSTNAME='grml'
366 [ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='manifold'
367 [ -n "$NFSROOT_CONF" ] || NFSROOT_CONF="${GRML_FAI_CONFIG}/make-fai-nfsroot.conf"
368 [ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
369 [ -n "$SQUASHFS_EXCLUDES_FILE" ] || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
370 [ -n "$SUITE" ] || SUITE='squeeze'
371 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
372 [ -n "$USERNAME" ] || USERNAME='grml'
373 [ -n "$VERSION" ] || VERSION='0.0.1'
375 # output specific stuff, depends on $OUTPUT (iff not set):
376 [ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live'
377 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
378 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
379 [ -n "$CHROOT_ARCHIVE" ] || CHROOT_ARCHIVE="$OUTPUT/$(basename $CHROOT_OUTPUT).tgz"
380 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
381 [ -n "$LOG_OUTPUT" ] || LOG_OUTPUT="$OUTPUT/grml_logs"
382 [ -n "$REPORTS" ] || REPORTS="${LOG_OUTPUT}/reports/"
383 [ -n "$NETBOOT" ] || NETBOOT="${OUTPUT}/netboot/"
386 # some misc checks before executing FAI {{{
387 [ -n "$CLASSES" ] || bailout 1 "Error: \$CLASSES unset, please set it in $LIVE_CONF or
388 specify it on the command line using the -c option."
389 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
390 specify it on the command line using the -o option."
392 # trim characters that are known to cause problems inside $GRML_NAME;
393 # for example isolinux does not like '-' inside the directory name
394 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
396 # export variables to have them available in fai scripts:
397 [ -n "$GRML_NAME" ] && export GRML_NAME="$GRML_NAME"
398 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
401 # ZERO_LOGFILE - check for backwards compatibility reasons {{{
402 # this was default behaviour until grml-live 0.9.34:
403 if [ -n "$ZERO_LOGFILE" ] ; then
404 PRESERVE_LOGFILE='' # make sure it's cleaned then
405 ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
406 ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
411 # ask user whether the setup is ok {{{
412 if [ -z "$FORCE" ] ; then
414 echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
416 echo " FAI classes: $CLASSES"
417 [ -n "$LOCAL_CONFIG" ] && echo " Configuration: $LOCAL_CONFIG"
418 [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG"
419 echo " main directory: $OUTPUT"
420 [ -n "$EXTRACT_ISO_NAME" ] && echo " Extract ISO: $EXTRACT_ISO_NAME"
421 [ -n "$UNPACK_CHROOT" ] && echo " Chroot from: $UNPACK_CHROOT"
422 [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT"
423 [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT"
424 [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT"
425 [ -n "$GRML_NAME" ] && echo " Grml name: $GRML_NAME"
426 [ -n "$RELEASENAME" ] && echo " Release name: $RELEASENAME"
427 [ -n "$DATE" ] && echo " Build date: $DATE"
428 [ -n "$VERSION" ] && echo " Grml version: $VERSION"
429 [ -n "$SUITE" ] && echo " Debian suite: $SUITE"
430 [ -n "$ARCH" ] && echo " Architecture: $ARCH"
431 [ -n "$BOOT_METHOD" ] && echo " Boot method: $BOOT_METHOD"
432 [ -n "$HYBRID_METHOD" ] && echo " Hybrid method: $HYBRID_METHOD"
433 [ -n "$TEMPLATE_DIRECTORY" ] && echo " Template files: $TEMPLATE_DIRECTORY"
434 [ -n "$CHROOT_INSTALL" ] && echo " Install files from directory to chroot: $CHROOT_INSTALL"
435 [ -n "$BOOTID" ] && echo " Boot identifier: $BOOTID"
436 [ -n "$NO_BOOTID" ] && echo " Skipping bootid feature."
437 [ -n "$CHOWN_USER" ] && echo " Output owner: $CHOWN_USER"
438 [ -n "$DEFAULT_BOOTOPTIONS" ] && echo " Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
439 [ -n "$FAI_ARGS" ] && echo " Additional arguments for FAI: $FAI_ARGS"
440 [ -n "$LOGFILE" ] && echo " Logging to file: $LOGFILE"
441 [ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA/XZ) compression."
442 [ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
443 [ -n "$VERBOSE" ] && echo " Using VERBOSE mode."
444 [ -n "$PACK_ARTIFACTS" ] && echo " Will prepare packed artifacts and ensure clean build."
445 [ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation."
446 if [ -n "$BOOTSTRAP_ONLY" ] ; then
447 echo " Bootstrapping only and not building (files for) ISO."
449 [ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file."
450 [ -n "$SKIP_NETBOOT" ] && echo " Skipping creation of NETBOOT package."
451 [ -n "$SKIP_MKISOFS" ] && echo " Skipping creation of ISO file."
452 [ -n "$BUILD_ONLY" ] && echo " Executing BUILD_ONLY instead of fresh installation or UPDATE."
453 [ -n "$BUILD_DIRTY" ] && echo " Executing BUILD_DIRTY to leave chroot untouched."
456 echo -n "Is this ok for you? [y/N] "
458 if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
459 bailout 1 "Exiting as requested."
465 # clean up before start {{{
466 if [ -n "${PACK_ARTIFACTS}" ]; then
467 echo "Wiping old artifacts"
468 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
469 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
470 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && rm -r "${ISO_OUTPUT}"
471 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && rm -r "${LOG_OUTPUT}"
472 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && rm -r "${NETBOOT}"
476 # create log file {{{
477 [ -n "$LOGFILE" ] || LOGFILE=${LOG_OUTPUT}/grml-live.log
478 mkdir -p $(dirname "${LOGFILE}")
480 chown root:adm $LOGFILE
484 # clean/zero/remove logfiles {{{
486 if [ -n "$PRESERVE_LOGFILE" ] ; then
487 echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
489 # make sure it is empty (as it is e.g. appended to grml-live-db)
493 if [ -n "$ZERO_FAI_LOGFILE" ] ; then
494 if [ -d /var/log/fai/"$HOSTNAME" ] ; then
495 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
496 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
497 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
498 rm -f /var/log/fai/"$HOSTNAME"/last \
499 /var/log/fai/"$HOSTNAME"/last-dirinstall \
500 /var/log/fai/"$HOSTNAME"/last-softupdate
505 # source config and startup {{{
506 if [ -n "$CONFIG" ] ; then
507 if ! [ -f "$CONFIG" ] ; then
508 log "Error: $CONFIG could not be read. Exiting. [$(date)]"
509 eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
512 log "Sourcing $CONFIG"
517 start_seconds=$(cut -d . -f 1 /proc/uptime)
518 log "------------------------------------------------------------------------------"
519 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
520 log "Using local config file: $LOCAL_CONFIG"
521 log "Executed grml-live command line:"
524 einfo "Logging actions to logfile $LOGFILE"
527 # dump config variables into file, for script access {{{
530 '^(GRML_NAME|RELEASENAME|DATE|VERSION|SUITE|ARCH|DISTRI_NAME|USERNAME|HOSTNAME|APT_PROXY)=' \
535 if [ -n "${UNPACK_CHROOT}" ]; then
536 log "Unpacking chroot from ${UNPACK_CHROOT}"
537 einfo "Unpacking chroot from ${UNPACK_CHROOT}"
538 [ -d "$CHROOT_OUTPUT" ] || mkdir -p "${CHROOT_OUTPUT}"
539 tar -xf "${UNPACK_CHROOT}" -C "${CHROOT_OUTPUT}/" --strip-components 1 ; RC=$?
540 if [ "$RC" != 0 ] ; then
548 # unpack iso/squashfs {{{
550 if [ -n "$EXTRACT_ISO_NAME" ]; then
551 log "Unpacking ISO from ${EXTRACT_ISO_NAME}"
552 einfo "Unpacking ISO from ${EXTRACT_ISO_NAME}"
553 local mountpoint=$(mktemp -d)
555 mount -o loop "${EXTRACT_ISO_NAME}" "$mountpoint" ; rc=$?
556 if [ "$rc" != 0 ]; then
559 eerror "mount failed"
563 unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*.squashfs ; rc=$?
566 if [ "$rc" != 0 ]; then
567 log "unsquashfs failed"
568 eerror "unsquashfs failed"
577 # cleanup CHROOT_ARCHIVE now {{{
578 if [ -n "${PACK_ARTIFACTS}" ]; then
579 # can't do this earlier, as UNPACK_CHROOT might point to CHROOT_ARCHIVE
580 [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}"
584 # on-the-fly configuration {{{
585 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
586 sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
589 # does this suck? YES!
590 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
592 unstable) SUITE='sid' ; CLASSES="DEBIAN_UNSTABLE,$CLASSES" ;;
593 *) CLASSES="DEBIAN_$(echo $SUITE | tr 'a-z' 'A-Z'),$CLASSES";;
595 export SUITE # make sure it's available in FAI scripts
597 for file in "$LIVE_CONF" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do
598 if [ -n "$file" ] ; then
599 sed "s|^FAI_DEBOOTSTRAP=\"[a-z]* |FAI_DEBOOTSTRAP=\"$SUITE |" "$file" | sponge "$file"
603 # validate whether the specified architecture class matches the
604 # architecture (option), otherwise installation of kernel will fail
605 if echo $CLASSES | grep -qi i386 ; then
606 if ! [[ "$ARCH" == "i386" ]] ; then
607 log "Error: You specified the I386 class but are trying to build something else (AMD64?)."
608 eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
609 eerror "Tip: Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
613 elif echo $CLASSES | grep -qi amd64 ; then
614 if ! [[ "$ARCH" == "amd64" ]] ; then
615 log "Error: You specified the AMD64 class but are trying to build something else (I386?)."
616 eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
617 eerror "Tip: Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
623 if grep -q -- 'FAI_DEBOOTSTRAP_OPTS.*--arch' "$NFSROOT_CONF" ; then
624 sed "s/--arch [a-z0-9]* /--arch $ARCH /" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
626 sed "s|^FAI_DEBOOTSTRAP_OPTS=\"\(.*\)|FAI_DEBOOTSTRAP_OPTS=\"--arch $ARCH \1|" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
630 # CHROOT_OUTPUT - execute FAI {{{
631 if [ -n "$BUILD_DIRTY" ]; then
632 log "Skipping stage 'fai' as requested via option -B"
633 ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
635 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
637 # provide inform fai about the ISO we build
638 [ -d "$CHROOT_OUTPUT/etc/" ] || mkdir -p "$CHROOT_OUTPUT/etc/"
639 echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
640 [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
641 [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
643 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
644 FAI_ACTION=softupdate
646 FAI_ACTION=dirinstall
649 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
650 if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
651 log "Error: does not look like you have a working chroot. Updating/building not possible."
652 eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
658 if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
659 log "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
660 ewarn "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
662 mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
664 if [ -n "${MIRROR_DIRECTORY}" ] ; then
665 mkdir -p "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
666 mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
669 mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
670 mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
672 # tell dpkg to use "unsafe io" during the build
673 [ -d "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d" ] || mkdir -p "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d"
674 echo force-unsafe-io > "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
676 log "Executed FAI command line:"
677 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"
678 BUILD_ONLY="$BUILD_ONLY" BOOTSTRAP_ONLY="$BOOTSTRAP_ONLY" GRML_LIVE_CONFIG="$CONFIGDUMP" fai $VERBOSE \
679 -C "$GRML_FAI_CONFIG" -s "file:///$GRML_FAI_CONFIG/config" -c"$CLASSES" \
680 -u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
681 RC="$PIPESTATUS" # notice: bash-only
683 rm -f "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
685 FORCE_ISO_REBUILD=true
687 if [ "$RC" != 0 ] ; then
688 log "Error: critical error while executing fai [exit code ${RC}]. Exiting."
689 eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
693 # move fai logs into grml_logs directory
694 mkdir -p "$LOG_OUTPUT"/fai/
695 cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
696 rm -rf "$CHROOT_OUTPUT"/var/log/fai
697 # copy fai package list
698 cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/
700 chown root:adm "$LOG_OUTPUT"/fai/*
701 chmod 664 "$LOG_OUTPUT"/fai/*
705 # notice: 'fai dirinstall' does not seem to exit appropriate, so:
707 CHECKLOG="$LOG_OUTPUT"/fai/
708 if [ -r "$CHECKLOG/software.log" ] ; then
709 # 1 errors during executing of commands
710 grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1
711 grep 'E: Method http has died unexpectedly!' $CHECKLOG/software.log >> $LOGFILE && ERROR=2
712 grep 'ERROR: chroot' $CHECKLOG/software.log >> $LOGFILE && ERROR=3
713 grep 'E: Failed to fetch' $CHECKLOG/software.log >> $LOGFILE && ERROR=4
714 grep 'Unable to write mmap - msync (28 No space left on device)' $CHECKLOG/software.log >> $LOGFILE && ERROR=5
717 if [ -r "$CHECKLOG/shell.log" ] ; then
718 grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=6
721 if [ -n "$ERROR" ] ; then
722 log "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
723 eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
724 eerror "Note: check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
728 log "Finished execution of stage 'fai dirinstall' [$(date)]"
729 einfo "Finished execution of stage 'fai dirinstall'"
735 # package validator {{{
736 CHECKLOG=/var/log/fai/$HOSTNAME/last
737 if [ -r "$CHECKLOG/dpkg.selections" ] ; then
738 package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}')
740 package_count="unknown"
744 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
746 # check for missing packages
747 if ! [ -s "$CHECKLOG/package_errors.log" ] ; then
748 einfo "No missing packages found, generating empty junit report."
750 cat > "${REPORT_MISSING_PACKAGES}" << EOF
751 <?xml version="1.0" encoding="UTF-8"?>
752 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="0" errors="0" skipped="0" assertions="0">
753 <testcase name="test_missing_packages" time="0" assertions="0">
763 einfo "Missing packages found, generating junit report."
765 if [ -r "$CHECKLOG/package_errors.log" ] ; then
766 package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}')
768 package_errors="unknown"
772 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
774 cat > "${REPORT_MISSING_PACKAGES}" << EOF
775 <?xml version="1.0" encoding="UTF-8"?>
776 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
779 for package in $(awk '{print $5}' "${CHECKLOG}/package_errors.log" | sed 's/\.$//') ; do
780 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
781 <testcase name="test_missing_packages_${package}" time="0" assertions="0">
782 <failure type="RuntimeError" message="Package ${package} is missing">
783 Package $package is missing in chroot
789 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
798 if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
799 eerror "The following packages were requested for installation but could not be processed:"
800 cat "$CHECKLOG/package_errors.log"
801 eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
805 ewarn "The following packages were requested for installation but could not be processed:"
806 cat "$CHECKLOG/package_errors.log"
812 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
813 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
814 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
817 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
818 if [ -n "$BOOTSTRAP_ONLY" ] ; then
819 log "Skipping stage 'boot' as building with bootstrap only."
820 ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
822 if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
823 log "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
824 ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
827 [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
828 [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
830 # if we don't have an initrd we a) can't boot and b) there was an error
831 # during build, so check for the file:
832 INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
833 if [ -n "$INITRD" ] ; then
834 cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
835 find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
837 log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
838 eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
842 KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
843 if [ -n "$KERNEL_IMAGE" ] ; then
844 cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/linux26
846 log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
847 eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
851 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
852 if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
853 log "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
854 eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
858 # copy _required_ isolinux files
859 for file in ifcpu64.c32 isolinux.bin vesamenu.c32; do
860 copy_addon_file "${file}" /usr/lib/syslinux isolinux
863 # *always* copy files to output directory so the variables
864 # get adjusted according to the build.
865 cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
867 if [ -n "$NO_ADDONS" ] ; then
868 log "Skipping installation of boot addons as requested via \$NO_ADDONS."
869 einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
871 if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
872 log "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
873 ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
875 # copy addons from system packages or grml-live-compat
876 copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
877 copy_addon_file pci.ids /usr/share/misc addons
878 copy_addon_file memtest86+.bin /boot addons
879 for file in memdisk chain.c32 hdt.c32 menu.c32; do
880 copy_addon_file "${file}" /usr/lib/syslinux addons
883 # make memtest filename FAT16/8.3 compatible
884 mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
885 "${BUILD_OUTPUT}/boot/addons/memtest"
887 # copy only files so we can handle bsd4grml on its own
888 for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
889 test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
892 if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
893 log "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
894 einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
896 if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
897 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
899 log "Missing addon file: bsd4grml"
900 ewarn "Missing addon file: bsd4grml" ; eend 0
904 fi # no "$TEMPLATE_DIRECTORY"/boot/addons
907 if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
908 mkdir -p "${BUILD_OUTPUT}/boot/grub"
910 cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
912 # copy grub files from target
913 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/
914 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/
915 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/
916 cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
917 cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
919 if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
920 log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
921 eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
925 [ -d "$BUILD_OUTPUT"/GRML ] || mkdir "$BUILD_OUTPUT"/GRML
926 cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/
928 # adjust boot splash information:
929 RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
930 RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
931 RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
933 if [ -r "$BUILD_OUTPUT"/GRML/grml-version ] ; then
934 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
935 sed -i "s/%DATE%/$DATE/" "$BUILD_OUTPUT"/GRML/grml-version
938 # make sure the squashfs filename is set accordingly:
939 SQUASHFS_NAME="$GRML_NAME.squashfs"
941 if [ -n "$NO_BOOTID" ] ; then
942 log 'Skipping bootid feature as requested via $NO_BOOTID.'
943 einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
945 [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
946 [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
947 einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
948 log "Generating /conf/bootid.txt with entry ${BOOTID}."
949 echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
953 # adjust all variables in the templates with the according distribution information
954 for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
955 "${BUILD_OUTPUT}"/boot/grub/* ; do
956 if [ -r "${file}" ] ; then
957 sed -i "s/%ARCH%/$ARCH/g" "${file}"
958 sed -i "s/%DATE%/$DATE/g" "${file}"
959 sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g" "${file}"
960 sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g" "${file}"
961 sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g" "${file}"
962 sed -i "s/%GRML_NAME%/$GRML_NAME/g" "${file}"
963 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g" "${file}"
964 sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g" "${file}"
965 sed -i "s/%SHORT_NAME%/$SHORT_NAME/g" "${file}"
966 sed -i "s/%VERSION%/$VERSION/g" "${file}"
968 [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s/ boot=live/ boot=live $DEFAULT_BOOTOPTIONS/" "${file}"
970 if [ -n "$NO_BOOTID" ] ; then
971 sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
973 sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
978 # adjust bootsplash accordingly but make sure the string has the according lenght
979 SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
980 SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
981 for file in f4 f5 ; do
982 if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
983 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
984 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
988 # generate addon list
989 rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
990 for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
991 include_name=$(basename "$name")
992 echo "include $include_name" >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
995 if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
996 log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
997 echo "include grmlmain.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
998 echo "include default.cfg" > "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
999 echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1000 echo "include grml.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1002 for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
1003 echo "include $(basename $f)" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1006 echo "include options.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1007 if [ ! -n "$NO_ADDONS" ] ; then
1008 echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1010 echo "include isoprompt.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1011 echo "include hd.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1012 echo "include hidden.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1013 else # assume we are building a custom distribution:
1014 log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1015 einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1016 if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1017 log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1019 einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1023 log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1024 echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1025 [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1029 # use old style console based isolinux method only if requested:
1030 if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
1031 log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1032 einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1033 if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1034 einfo "include for console.cfg already found, nothing to do."
1037 log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1038 einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1039 echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1043 log 'Using graphical boot menu.'
1044 if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
1045 log "include for vesamenu.cfg already found, nothing to do."
1047 log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1048 echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1052 if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
1053 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
1056 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
1057 if ! [ -r "$DPKG_LIST" ] ; then
1058 ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
1060 einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
1061 cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
1065 # autostart for Windows:
1066 if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
1067 cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
1070 FORCE_ISO_REBUILD=true
1071 einfo "Finished execution of stage 'boot'" ; eend 0
1075 log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
1076 eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
1080 # support installation of local files into the chroot/ISO
1081 if [ -n "$CHROOT_INSTALL" ] ; then
1082 if ! [ -d "$CHROOT_INSTALL" ] ; then
1083 log "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1084 ewarn "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1086 log "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1087 einfo "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1088 rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
1090 einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
1091 FORCE_ISO_REBUILD=true
1095 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1096 log "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
1097 ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
1098 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
1099 log "Skipping stage 'squashfs' as requested via option -q or -N"
1100 ewarn "Skipping stage 'squashfs' as requested via option -q or -N" ; eend 0
1102 [ -d "$BUILD_OUTPUT"/live ] || mkdir "$BUILD_OUTPUT"/live
1103 # make sure we don't leave (even an empty) base.tgz:
1104 [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
1106 # if unconfigured default to squashfs-tools' mksquashfs binary
1107 if [ -z "$SQUASHFS_BINARY" ] ; then
1108 SQUASHFS_BINARY='mksquashfs'
1111 if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
1112 log "Using mksquashfs binary ${SQUASHFS_BINARY}"
1113 einfo "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
1115 log "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
1116 eerror "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
1120 # use sane defaults if $SQUASHFS_OPTIONS isn't set
1121 if [ -z "$SQUASHFS_OPTIONS" ] ; then
1122 # use blocksize 256k as this gives best result with regards to time + compression
1123 SQUASHFS_OPTIONS="-b 256k"
1125 # set lzma/xz compression by default, unless -z option has been specified on command line
1126 if [ -z "$SQUASHFS_ZLIB" ] ; then
1127 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp xz"
1129 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp gzip"
1133 # support exclusion of files via exclude-file:
1134 if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
1135 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE -wildcards"
1138 # get rid of unnecessary files when building grml-small for final release:
1139 if echo "$CLASSES" | grep -q GRML_SMALL ; then
1140 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
1144 SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
1146 # informational stuff
1147 [ -n "$SQUASHFS_OPTIONS" ] && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
1148 [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
1149 einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
1151 log "$SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS"
1153 if $SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
1154 -noappend $SQUASHFS_OPTIONS 2>"${SQUASHFS_STDERR}" ; then
1155 echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
1156 log "Finished execution of stage 'squashfs' [$(date)]"
1157 einfo "Finished execution of stage 'squashfs'" ; eend 0
1159 log "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
1160 log "$(cat $SQUASHFS_STDERR)"
1161 eerror "Error: there was a critical error executing stage 'squashfs':"
1162 cat "${SQUASHFS_STDERR}"
1167 FORCE_ISO_REBUILD=true
1170 # create md5sum file:
1171 if [ -z "$BOOTSTRAP_ONLY" ] ; then
1172 ( cd $BUILD_OUTPUT/GRML &&
1173 find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
1177 # ISO_OUTPUT - mkisofs {{{
1178 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
1179 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
1181 if [ "$BOOT_METHOD" = "isolinux" ] ; then
1182 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
1183 elif [ "$BOOT_METHOD" = "grub2" ] ; then
1184 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
1187 # Just until http://bts.grml.org/grml/issue945 has been resolved.
1188 # HYBRID_METHOD defaults to manifold, so make sure the default works OOTB.
1189 if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
1190 log "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1191 ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1192 HYBRID_METHOD='grub2'
1196 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
1197 log "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
1198 ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
1199 elif [ -n "$SKIP_MKISOFS" ] ; then
1200 log "Skipping stage 'iso build' as requested via option -n or -N"
1201 ewarn "Skipping stage 'iso build' as requested via option -n or -N" ; eend 0
1203 mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
1205 if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; then
1206 log "Forcing rebuild of ISO because files on ISO have been modified."
1207 einfo "Forcing rebuild of ISO because files on ISO have been modified."
1210 # support xorriso as well mkisofs and genisoimage
1211 if which xorriso >/dev/null 2>&1 ; then
1212 MKISOFS='xorriso -as mkisofs'
1213 elif which mkisofs >/dev/null 2>&1; then
1215 elif which genisoimage >/dev/null 2>&1; then
1216 MKISOFS='genisoimage'
1218 log "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO."
1219 eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1
1225 # using -eltorito-alt-boot is limited to xorriso for now
1228 einfo "Using xorriso for ISO generation." ; eend 0
1231 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
1232 log "Disabling (U)EFI boot support since xorriso version is not recent enough."
1233 ewarn "Disabling (U)EFI boot support since xorriso version is not recent enough." ; eend 0
1235 log "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support."
1236 einfo "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support." ; eend 0
1238 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" ] ; then
1239 einfo "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1240 log "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO."
1241 mv "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" "${BUILD_OUTPUT}/boot/efi.img"
1245 if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" ] ; then
1246 einfo "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1247 log "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO"
1248 mkdir -p "${BUILD_OUTPUT}/efi/boot/"
1249 mv "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi"
1253 if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then
1254 einfo "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1255 log "/boot/efi.img found and amd64 architecture present, extending boot arguments."
1256 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
1268 if cd "$BUILD_OUTPUT" ; then
1269 if [ "$BOOT_METHOD" = "grub2" ]; then
1270 # make a 2048-byte bootsector for El Torito
1271 dd if=/dev/zero of=boot/grub/toriboot.bin bs=512 count=4 2>/dev/null
1272 # those are in 2048-byte sectors, so 1 16 matches 4 63 below
1273 echo 1 16 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -B 11 | \
1274 dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
1276 log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
1277 $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
1278 -l -r -J $BOOT_ARGS -no-pad \
1279 -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
1280 # both of these need core.img there, so it’s easier to write it here
1281 if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
1282 # must be <= 30720 bytes
1283 dd if=boot/grub/core.img of="${ISO_OUTPUT}/${ISO_NAME}" \
1284 conv=notrunc bs=512 seek=4 2>/dev/null
1287 # pad the output ISO to multiples of 256 KiB for partition table support
1288 siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
1289 cyls=$((siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
1290 siz=$((cyls * 16 * 32 * 512)) # size after padding
1291 dd if=/dev/zero bs=1 count=1 seek=$((siz - 1)) \
1292 of="${ISO_OUTPUT}/${ISO_NAME}" 2>/dev/null
1294 # support disabling hybrid ISO image
1295 if [ "$HYBRID_METHOD" = "disable" ] ; then\
1296 log "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1297 einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1299 elif [ "$HYBRID_METHOD" = "manifold" ] ; then
1300 # isoinfo is part of both mkisofs and genisoimage so we're good
1301 bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
1302 sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p')
1303 if ! [ -r boot/grub/core.img ] ; then
1304 ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
1305 elif [ "${bootoff:-0}" -lt 1 ] ; then
1306 ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
1308 log "Creating hybrid ISO file with manifold method"
1309 einfo "Creating hybrid ISO file with manifold method"
1310 if [ "$HYBRID_METHOD" = "grub2" ] ; then
1311 # 512 bytes: MBR, partition table, load GRUB 2
1312 echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
1314 # read only one but 2048-byte sized (scale: << 2) sector
1315 echo $bootoff $bootoff | \
1316 mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
1317 fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
1320 # use isohybrid as default
1322 if ! which isohybrid >/dev/null 2>&1 ; then
1323 bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
1325 log "Creating hybrid ISO file with isohybrid method"
1326 einfo "Creating hybrid ISO file with isohybrid method"
1327 # Notes for consideration:
1328 # "-entry 4 -type 1c"
1329 # * using 4 as the partition number is supposed to help with BIOSes
1330 # that only support USB-Zip boot
1331 # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
1332 # (hidden NTFS, IIRC), as the partition type is sometimes needed
1333 # to get the BIOS even look at the partition created by isohybrid
1334 if isohybrid --help | grep -q -- --uefi ; then
1335 einfo "Detected uefi support for isohybrid, enabling."
1336 ISOHYBRID_OPTIONS=--uefi
1339 log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
1340 isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
1345 # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
1346 case $CLASSES in *RELEASE*)
1349 if cd $ISO_OUTPUT ; then
1350 md5sum ${ISO_NAME} > ${ISO_NAME}.md5 && \
1351 touch -r ${ISO_NAME} ${ISO_NAME}.md5
1352 sha1sum ${ISO_NAME} > ${ISO_NAME}.sha1 && \
1353 touch -r ${ISO_NAME} ${ISO_NAME}.sha1
1362 if [ "$RC" = 0 ] ; then
1363 log "Finished execution of stage 'iso build' [$(date)]"
1364 einfo "Finished execution of stage 'iso build'" ; eend 0
1366 log "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
1367 eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
1373 # netboot package {{{
1374 create_netbootpackage() {
1375 local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2"
1377 if [ -f "${OUTPUT_FILE}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1378 log "Skipping stage 'netboot' as $OUTPUT_FILE exists already."
1379 ewarn "Skipping stage 'netboot' as $OUTPUT_FILE exists already." ; eend 0
1381 elif [ -n "$SKIP_NETBOOT" ] ; then
1382 log "Skipping stage 'netboot' as requested via option -Q"
1383 ewarn "Skipping stage 'netboot' as requested via option -Q" ; eend 0
1389 if ! [ -r "${CHROOT}/usr/lib/syslinux/pxelinux.0" ] ; then
1390 ewarn "File /usr/lib/syslinux/pxelinux.0 not found in build chroot." ; eend 0
1392 einfo "Install syslinux[-common] package in chroot to get a netboot package."
1397 local OUTPUTDIR="${NETBOOT}/build_tmp"
1398 local WORKING_DIR="${OUTPUTDIR}/grml_netboot_package_${GRML_NAME}_${VERSION}/tftpboot/"
1400 mkdir -p "$WORKING_DIR"
1402 cp "${CHROOT_OUTPUT}"/boot/vmlinuz-* "$WORKING_DIR"/linux26
1403 cp "${CHROOT_OUTPUT}"/boot/initrd.img-* "$WORKING_DIR"/initrd.img
1404 cp "${CHROOT_OUTPUT}"/usr/lib/syslinux/pxelinux.0 "${WORKING_DIR}/pxelinux.0"
1406 if [ -r "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" ] ; then
1407 mkdir -p "${WORKING_DIR}/pxelinux.cfg/default"
1408 cp "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" "${WORKING_DIR}/pxelinux.cfg/default"
1410 ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found." ; eend 0
1413 mkdir -p "${WORKING_DIR}/pxelinux.cfg"
1415 if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
1416 sha1sum "${OUTPUT_FILE}" > "${OUTPUT_FILE}.sha1"
1417 einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0
1418 rm -rf "${OUTPUTDIR}"
1420 rm -rf "${OUTPUTDIR}"
1421 eerror "Could not generate netboot package ${OUTPUT_FILE}" ; eend 1
1426 create_netbootpackage
1429 # pack artifacts {{{
1430 if [ -n "$PACK_ARTIFACTS" ]; then
1431 log "Packing artifcats"
1432 einfo "Packing artifacts"
1433 [ -f "${CHROOT_ARCHIVE}" ] && rm -r "${CHROOT_ARCHIVE}"
1434 tar -c -a -f ${CHROOT_ARCHIVE} --preserve-permissions -C "$(dirname ${CHROOT_OUTPUT})" "$(basename ${CHROOT_OUTPUT})"
1439 # log build information to database if grml-live-db is installed and enabled {{{
1441 if [ -d /usr/share/grml-live-db ] ; then
1444 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
1445 [ -n "$DPKG_DATABASE" ] || DPKG_DATABASE=/var/log/grml-live.db
1446 [ -n "$DPKG_DBSCRIPT" ] || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
1447 [ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
1449 if ! [ -x "$DPKG_DBSCRIPT" ] ; then
1450 log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
1451 eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
1455 # disable by default for now, not sure whether really everyone is using a local db file
1456 #if ! touch "$DPKG_DATABASE" ; then
1457 # eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
1461 if ! [ -r "$DPKG_LIST" ] ; then
1462 log "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
1463 ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
1465 einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
1466 log "Logging $DPKG_LIST to database $DPKG_DATABASE"
1467 log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
1470 if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
1486 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
1487 log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
1489 dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
1491 einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
1495 ## END OF FILE #################################################################
1496 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2