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
26 # The line following this line is patched by debian/rules.
27 GRML_LIVE_VERSION='***UNRELEASED***'
32 ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
35 # usage information {{{
39 $PN - build process script for generating a (grml based) Linux Live-ISO
41 Usage: $PN [options, see as follows]
43 -a <architecture> architecture; available values: i386 and amd64
44 -A clean build directories before and after running
45 -b build the ISO without updating the chroot via FAI
46 -B build the ISO without touching the chroot (skips cleanup)
47 -c <classe[s]> classes to be used for building the ISO via FAI
48 -C <configfile> configuration file for grml-live
49 -d <date> use specified date instead of build time as date of release
50 -D <configdir> use specified configuration directory instead of /etc/grml/fai
51 -e <iso_name> extract ISO and squashfs contents from iso_name
52 -F force execution without prompting
53 -g <grml_name> set the grml flavour name
54 -h display short usage information and exit
55 -i <iso_name> name of ISO
56 -I <src_directory> directory which provides files that should become
57 part of the chroot/ISO
58 -n skip generation of ISO
59 -N bootstrap (build chroot) only, do not create files for ISO
60 -o <output_directory> main output directory of the build process
62 -Q skip netboot package build
63 -r <release_name> release name
64 -s <suite> Debian suite; values: etch, lenny, squeeze, sid
65 -t <template_directory> place of the templates
66 -u update existing chroot instead of rebuilding it from scratch
67 -U <username> arrange output to be owned by specified username
68 -v <version_number> specify version number of the release
69 -V increase verbosity in the build process
70 -z use ZLIB instead of LZMA/XZ compression
75 $PN -c GRMLBASE,GRML_FULL,AMD64 -o /dev/shm/grml
76 $PN -c GRMLBASE,GRML_FULL,AMD64 -i grml_0.0-1.iso -v 0.0-1
77 $PN -c GRMLBASE,GRML_FULL,AMD64 -s sid -V -r 'grml-live rocks'
79 More details: man grml-live + /usr/share/doc/grml-live/grml-live.html
80 http://grml.org/grml-live/
82 Please send your bug reports and feedback to the grml-team: http://grml.org/bugs/
84 [ "$(id -u 2>/dev/null)" != 0 ] && echo "Please notice that this script requires root permissions."
87 # make sure it's possible to get usage information without being
88 # root or actually executing the script
89 if [ "$1" = '-h' -o "$1" = '--help' ] ; then
95 # some runtime checks {{{
96 # we need root permissions for the build-process:
97 if [ "$(id -u 2>/dev/null)" != 0 ] ; then
98 echo "Error: please run this script with uid 0 (root)." >&2
102 if [ -r /var/run/fai/FAI_INSTALLATION_IN_PROGRESS ] ; then
103 echo "/usr/sbin/fai already running or was aborted before.">&2
104 echo "You may remove /var/run/fai/FAI_INSTALLATION_IN_PROGRESS and try again.">&2
109 if [ -r /var/run/fai/fai_softupdate_is_running ] ; then
110 echo "/usr/sbin/fai softupdate already running or was aborted before.">&2
111 echo "You may remove /var/run/fai/fai_softupdate_is_running and try again.">&2
116 # lsb-functions and configuration stuff {{{
117 # make sure they are not set by default
128 # don't use colors/escape sequences
129 if [ -r /lib/lsb/init-functions ] ; then
130 . /lib/lsb/init-functions
131 ! log_use_fancy_output && NOCOLORS=true
134 if [ -r /etc/grml/lsb-functions ] ; then
135 . /etc/grml/lsb-functions
137 einfo() { echo " [*] $*" ;}
138 eerror() { echo " [!] $*">&2 ;}
139 ewarn() { echo " [x] $*" ;}
141 eindent() { return 0 ;}
142 eoutdent() { return 0 ;}
145 # source main configuration file:
146 LIVE_CONF=/etc/grml/grml-live.conf
150 # umount all directories {{{
152 # make sure we don't leave any mounts - FAI doesn't remove them always
153 umount $CHROOT_OUTPUT/proc/sys/fs/binfmt_misc 2>/dev/null || /bin/true
154 umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
155 umount $CHROOT_OUTPUT/run 2>/dev/null || /bin/true
156 umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true
157 umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
158 umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
160 if [ -n "$EXTRACT_ISO_NAME" ] ; then
161 umount "$EXTRACT_ISO_NAME" 2>/dev/null || /bin/true
164 # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry
165 if [ -x /usr/lib/fai/mkramdisk ] ; then
166 /usr/lib/fai/mkramdisk -u "$(readlink -f ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true
169 umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true
170 [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
176 rm -f /var/run/fai/fai_softupdate_is_running \
177 /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
178 [ -n "$CONFIGDUMP" ] && rm -f "$CONFIGDUMP"
179 [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR"
181 [ -n "$1" ] && EXIT="$1" || EXIT="1"
182 [ -n "$2" ] && eerror "$2">&2
183 if [ -n "$CLEAN_ARTIFACTS" ]; then
186 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
187 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
191 # get rid of automatically generated conffiles
192 rm -f ${GRML_FAI_CONFIG}/nfsroot.conf
193 rm -f ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf
195 if [ -n "$CHOWN_USER" ]; then
196 log "Setting ownership"
197 einfo "Setting ownership"
198 [ -n "${OUTPUT}" -a -d "${OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${OUTPUT}"
199 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${BUILD_OUTPUT}"
200 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}"
201 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}"
202 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}"
203 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && chown -R "${CHOWN_USER}:" "${NETBOOT}"
206 log "------------------------------------------------------------------------------"
209 trap bailout 1 2 3 3 6 9 14 15
213 # some important functions {{{
216 # usage: log "string to log"
217 log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; }
219 # cut string at character number int = $1
220 # usage: cut_string 5 "1234567890" will output "12345"
222 [ -n "$2" ] || return 1
223 echo "$2" | head -c "$1"; echo -ne "\n"
226 # prepend int = $1 spaces before string = $2
227 # usage: extend_string_begin 5 "123" will output " 123"
228 extend_string_begin() {
229 [ -n "$2" ] || return 1
230 local COUNT="$(echo $2 | wc -c)"
231 local FILL="$(expr $COUNT - $1)"
232 while [ "$FILL" -gt 1 ] ; do
234 local FILL=$(expr $FILL - 1)
236 while [ "$FILL" -lt 1 ] ; do
238 local FILL=$(expr $FILL + 1)
240 echo "$2" | head -c "$1"; echo -ne "\n"
243 # append int = $1 spaces to string = $2
244 # usage: extend_string_begin 5 "123" will output "123 "
245 extend_string_end() {
246 [ -n "$2" ] || return 1
247 echo -n "$2" | head -c "$1"
248 local COUNT="$(echo $2 | wc -c)"
249 local FILL="$(expr $COUNT - $1)"
250 while [ "$FILL" -gt 1 ] ; do
252 local FILL=$(expr $FILL - 1)
254 while [ "$FILL" -lt 1 ] ; do
256 local FILL=$(expr $FILL + 1)
261 # Copy addonfile $1 from either
262 # * the chroot (via $2, the system path),
263 # * or from TEMPLATE_DIRECTORY/compat (if exists),
264 # * or from the host system (again, using $2),
265 # or warn about the missing file.
268 # * We assume that the chroot always has a "good" version of
269 # the file. Also it makes sources handling easier.
270 # * On unstable, we Recommend the Debian packages containing
271 # these files. The user can override them by putting his
272 # "better" version into the chroot.
273 # * On stable, the Debian packages are probably not available,
274 # or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
275 # our grml-live-compat package installs current file versions.
277 DEST="${BUILD_OUTPUT}/boot/$3"
278 if [ ! -d "${DEST}/" ]; then
281 if [ -e "$CHROOT_OUTPUT/$2/$1" ]; then
282 log "Copying $1 from chroot"
283 cp "$CHROOT_OUTPUT/$2/$1" "${DEST}/"
286 if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
287 log "Copying $1 from grml-live-compat"
288 cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
291 if [ -e "$2/$1" ]; then
292 log "Copying $1 from system"
293 cp "$2/$1" "${DEST}/"
297 msg="Missing addon file: \"$1\""
298 ewarn "$msg" ; eend 1
299 log "copy_addon_file: $msg"
303 # command line parsing {{{
304 while getopts "a:C:c:d:D:e:g:i:I:o:r:s:t:U:v:AbBFhnNqQuVz" opt; do
307 A) CLEAN_ARTIFACTS=1 ;;
310 c) CLASSES="$OPTARG" ;;
311 C) LOCAL_CONFIG="$(readlink -f $OPTARG)" ;;
313 D) GRML_FAI_CONFIG="$(readlink -f $OPTARG)" ;;
314 e) EXTRACT_ISO_NAME="$(readlink -f $OPTARG)" ;;
315 g) GRML_NAME="$OPTARG" ;;
316 h) usage ; bailout 0 ;;
317 i) ISO_NAME="$OPTARG" ;;
318 I) CHROOT_INSTALL="$OPTARG" ;;
320 N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;;
321 o) OUTPUT="$(readlink -f $OPTARG)" ;;
322 q) SKIP_MKSQUASHFS=1 ;;
324 r) RELEASENAME="$OPTARG" ;;
325 s) SUITE="$OPTARG" ;;
326 t) TEMPLATE_DIRECTORY="$OPTARG";;
327 v) VERSION="$OPTARG" ;;
330 U) CHOWN_USER="$OPTARG" ;;
332 z) SQUASHFS_ZLIB=1 ;;
333 ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
336 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
339 # read local (non-packaged) configuration {{{
340 if [ -z "$LOCAL_CONFIG" ]; then
341 if [ -r "/etc/grml/grml-live.local" ]; then
342 LOCAL_CONFIG="/etc/grml/grml-live.local"
345 if [ -n "$LOCAL_CONFIG" ]; then
346 if [ -r "$LOCAL_CONFIG" ]; then
349 eerror "Could not read specified local configuration file \"$LOCAL_CONFIG\"."
352 LOCAL_CONFIG=$(readlink -f "$LOCAL_CONFIG")
357 if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
358 eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated."
359 ewarn "Please set up \${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead."
364 # assume sane defaults (if not set already) {{{
365 [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
366 [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
367 [ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_FULL,$(echo ${ARCH} | tr 'a-z' 'A-Z')"
368 [ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)"
369 [ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators'
370 [ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
371 [ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
372 [ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
373 [ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
374 [ -n "$GRML_NAME" ] || GRML_NAME='grml'
375 [ -n "$HOSTNAME" ] || HOSTNAME='grml'
376 [ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='isohybrid'
377 [ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
378 [ -n "$SQUASHFS_EXCLUDES_FILE" ] || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
379 [ -n "$SUITE" ] || SUITE='testing'
380 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
381 [ -n "$USERNAME" ] || USERNAME='grml'
382 [ -n "$VERSION" ] || VERSION='0.0.1'
384 # output specific stuff, depends on $OUTPUT (iff not set):
385 [ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live'
386 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
387 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
388 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
389 [ -n "$LOG_OUTPUT" ] || LOG_OUTPUT="$OUTPUT/grml_logs"
390 [ -n "$REPORTS" ] || REPORTS="${LOG_OUTPUT}/reports/"
391 [ -n "$NETBOOT" ] || NETBOOT="${OUTPUT}/netboot/"
394 # some misc checks before executing FAI {{{
395 [ -n "$CLASSES" ] || bailout 1 "Error: \$CLASSES unset, please set it in $LIVE_CONF or
396 specify it on the command line using the -c option."
397 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
398 specify it on the command line using the -o option."
400 # trim characters that are known to cause problems inside $GRML_NAME;
401 # for example isolinux does not like '-' inside the directory name
402 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
404 # export variables to have them available in fai scripts:
405 [ -n "$GRML_NAME" ] && export GRML_NAME="$GRML_NAME"
406 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
409 # ZERO_LOGFILE - check for backwards compatibility reasons {{{
410 # this was default behaviour until grml-live 0.9.34:
411 if [ -n "$ZERO_LOGFILE" ] ; then
412 PRESERVE_LOGFILE='' # make sure it's cleaned then
413 ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
414 ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
419 # ask user whether the setup is ok {{{
420 if [ -z "$FORCE" ] ; then
422 echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
424 echo " FAI classes: $CLASSES"
425 [ -n "$LOCAL_CONFIG" ] && echo " Configuration: $LOCAL_CONFIG"
426 [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG"
427 echo " main directory: $OUTPUT"
428 [ -n "$EXTRACT_ISO_NAME" ] && echo " Extract ISO: $EXTRACT_ISO_NAME"
429 [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT"
430 [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT"
431 [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT"
432 [ -n "$GRML_NAME" ] && echo " Grml name: $GRML_NAME"
433 [ -n "$RELEASENAME" ] && echo " Release name: $RELEASENAME"
434 [ -n "$DATE" ] && echo " Build date: $DATE"
435 [ -n "$VERSION" ] && echo " Grml version: $VERSION"
436 [ -n "$SUITE" ] && echo " Debian suite: $SUITE"
437 [ -n "$ARCH" ] && echo " Architecture: $ARCH"
438 [ -n "$BOOT_METHOD" ] && echo " Boot method: $BOOT_METHOD"
439 [ -n "$HYBRID_METHOD" ] && echo " Hybrid method: $HYBRID_METHOD"
440 [ -n "$TEMPLATE_DIRECTORY" ] && echo " Template files: $TEMPLATE_DIRECTORY"
441 [ -n "$CHROOT_INSTALL" ] && echo " Install files from directory to chroot: $CHROOT_INSTALL"
442 [ -n "$BOOTID" ] && echo " Boot identifier: $BOOTID"
443 [ -n "$NO_BOOTID" ] && echo " Skipping bootid feature."
444 [ -n "$CHOWN_USER" ] && echo " Output owner: $CHOWN_USER"
445 [ -n "$DEFAULT_BOOTOPTIONS" ] && echo " Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
446 [ -n "$FAI_ARGS" ] && echo " Additional arguments for FAI: $FAI_ARGS"
447 [ -n "$LOGFILE" ] && echo " Logging to file: $LOGFILE"
448 [ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA/XZ) compression."
449 [ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
450 [ -n "$VERBOSE" ] && echo " Using VERBOSE mode."
451 [ -n "$CLEAN_ARTIFACTS" ] && echo " Will clean output before and after running."
452 [ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation."
453 if [ -n "$BOOTSTRAP_ONLY" ] ; then
454 echo " Bootstrapping only and not building (files for) ISO."
456 [ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file."
457 [ -n "$SKIP_NETBOOT" ] && echo " Skipping creation of NETBOOT package."
458 [ -n "$SKIP_MKISOFS" ] && echo " Skipping creation of ISO file."
459 [ -n "$BUILD_ONLY" ] && echo " Executing BUILD_ONLY instead of fresh installation or UPDATE."
460 [ -n "$BUILD_DIRTY" ] && echo " Executing BUILD_DIRTY to leave chroot untouched."
463 echo -n "Is this ok for you? [y/N] "
465 if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
466 bailout 1 "Exiting as requested."
472 # clean up before start {{{
473 if [ -n "${CLEAN_ARTIFACTS}" ]; then
474 echo "Wiping old artifacts"
475 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
476 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
477 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && rm -r "${ISO_OUTPUT}"
478 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && rm -r "${LOG_OUTPUT}"
479 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && rm -r "${NETBOOT}"
483 # create log file {{{
484 [ -n "$LOGFILE" ] || LOGFILE=${LOG_OUTPUT}/grml-live.log
485 mkdir -p $(dirname "${LOGFILE}")
487 chown root:adm $LOGFILE
491 # clean/zero/remove logfiles {{{
493 if [ -n "$PRESERVE_LOGFILE" ] ; then
494 echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
496 # make sure it is empty (as it is e.g. appended to grml-live-db)
500 if [ -n "$ZERO_FAI_LOGFILE" ] ; then
501 if [ -d /var/log/fai/"$HOSTNAME" ] ; then
502 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
503 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
504 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
505 rm -f /var/log/fai/"$HOSTNAME"/last \
506 /var/log/fai/"$HOSTNAME"/last-dirinstall \
507 /var/log/fai/"$HOSTNAME"/last-softupdate
512 # source config and startup {{{
513 if [ -n "$CONFIG" ] ; then
514 if ! [ -f "$CONFIG" ] ; then
515 log "Error: $CONFIG could not be read. Exiting. [$(date)]"
516 eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
519 log "Sourcing $CONFIG"
524 start_seconds=$(cut -d . -f 1 /proc/uptime)
525 log "------------------------------------------------------------------------------"
526 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
527 log "Using local config file: $LOCAL_CONFIG"
528 log "Executed grml-live command line:"
531 einfo "Logging actions to logfile $LOGFILE"
534 # dump config variables into file, for script access {{{
537 '^(GRML_NAME|RELEASENAME|DATE|VERSION|SUITE|ARCH|DISTRI_NAME|USERNAME|HOSTNAME|APT_PROXY)=' \
541 # unpack iso/squashfs {{{
543 if [ -n "$EXTRACT_ISO_NAME" ]; then
544 log "Unpacking ISO from ${EXTRACT_ISO_NAME}"
545 einfo "Unpacking ISO from ${EXTRACT_ISO_NAME}"
546 local mountpoint=$(mktemp -d)
548 mount -o loop "${EXTRACT_ISO_NAME}" "$mountpoint" ; rc=$?
549 if [ "$rc" != 0 ]; then
552 eerror "mount failed"
557 if ls "${mountpoint}"/live/*/*.squashfs 2>/dev/null | grep -q . ; then # ISOs >=2011.12
558 log "Using ${mountpoint}/live/*/*.squashfs for unsquashfs"
559 unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*/*.squashfs ; rc=$?
560 elif ls "${mountpoint}"/live/*.squashfs 2>/dev/null | grep -q . ; then # ISOs before 2011.12
561 log "Using ${mountpoint}/live/*.squashfs for unsquashfs"
562 unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*.squashfs ; rc=$?
564 log "Error: Could not find any *.squashfs files on the ISO"
565 eerror "Error: Could not find any *.squashfs files on the ISO"
572 if [ "$rc" != 0 ]; then
573 log "unsquashfs failed"
574 eerror "unsquashfs failed"
583 # on-the-fly configuration {{{
585 # does this suck? YES!
586 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
588 unstable) SUITE='sid' ; CLASSES="DEBIAN_UNSTABLE,$CLASSES" ;;
589 *) CLASSES="DEBIAN_$(echo $SUITE | tr 'a-z' 'A-Z'),$CLASSES";;
591 export SUITE # make sure it's available in FAI scripts
593 # validate whether the specified architecture class matches the
594 # architecture (option), otherwise installation of kernel will fail
595 if echo $CLASSES | grep -qi i386 ; then
596 if ! [[ "$ARCH" == "i386" ]] ; then
597 log "Error: You specified the I386 class but are trying to build something else (AMD64?)."
598 eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
599 eerror "Tip: Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
603 elif echo $CLASSES | grep -qi amd64 ; then
604 if ! [[ "$ARCH" == "amd64" ]] ; then
605 log "Error: You specified the AMD64 class but are trying to build something else (I386?)."
606 eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
607 eerror "Tip: Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
613 # generate nfsroot configuration for FAI on the fly
614 if [ -z "$FAI_DEBOOTSTRAP" ] ; then
615 FAI_DEBOOTSTRAP="$SUITE http://cdn.debian.net/debian"
618 if [ -z "$FAI_DEBOOTSTRAP_OPTS" ] ; then
619 FAI_DEBOOTSTRAP_OPTS="--exclude=info,tasksel,tasksel-data --arch $ARCH"
622 # create backup of old (not yet automatically generated) config file
623 if [ -f "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" ] ; then
624 if ! grep -q 'This is an automatically generated file by grml-live' "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" ; then
625 ewarn "Found old ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf - moving to ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf.outdated"
626 mv "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf.outdated"
631 echo "# This is an automatically generated file by grml-live.
632 # Do NOT edit this file, your changes will be lost.
633 FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"
634 FAI_DEBOOTSTRAP_OPTS=\"$FAI_DEBOOTSTRAP_OPTS\"
635 # EOF " > "${GRML_FAI_CONFIG}/nfsroot.conf"
636 # support FAI <=3.4.8, versions >=4.0 use nfsroot.conf
637 ( cd ${GRML_FAI_CONFIG} && ln -sf nfsroot.conf make-fai-nfsroot.conf )
640 # CHROOT_OUTPUT - execute FAI {{{
641 if [ -n "$BUILD_DIRTY" ]; then
642 log "Skipping stage 'fai' as requested via option -B"
643 ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
645 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
647 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
648 FAI_ACTION=softupdate
650 FAI_ACTION=dirinstall
653 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
654 if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
655 log "Error: does not look like you have a working chroot. Updating/building not possible."
656 eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
662 if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
663 log "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
664 ewarn "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
666 mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
668 if [ -n "${MIRROR_DIRECTORY}" ] ; then
669 mkdir -p "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
670 mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
673 mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
674 mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
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 # provide inform fai about the ISO we build, needs to be provided
684 # *after* FAI stage, otherwise FAI skips the debootstrap stage if
685 # there is not BASEFILE (as it checks for presence of /etc) :(
686 echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
687 [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
688 [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
690 FORCE_ISO_REBUILD=true
692 if [ "$RC" != 0 ] ; then
693 log "Error: critical error while executing fai [exit code ${RC}]. Exiting."
694 eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
698 # move fai logs into grml_logs directory
699 mkdir -p "$LOG_OUTPUT"/fai/
700 cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
701 rm -rf "$CHROOT_OUTPUT"/var/log/fai
703 # store copy of autogenerated configuration file
704 cp ${GRML_FAI_CONFIG}/nfsroot.conf "$LOG_OUTPUT"/fai/
706 # copy fai package list
707 cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/
709 chown root:adm "$LOG_OUTPUT"/fai/*
710 chmod 664 "$LOG_OUTPUT"/fai/*
714 # notice: 'fai dirinstall' does not seem to exit appropriate, so:
716 CHECKLOG="$LOG_OUTPUT"/fai/
717 if [ -r "$CHECKLOG/software.log" ] ; then
718 # 1 errors during executing of commands
719 grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1
720 grep 'E: Method http has died unexpectedly!' $CHECKLOG/software.log >> $LOGFILE && ERROR=2
721 grep 'ERROR: chroot' $CHECKLOG/software.log >> $LOGFILE && ERROR=3
722 grep 'E: Failed to fetch' $CHECKLOG/software.log >> $LOGFILE && ERROR=4
723 grep 'Unable to write mmap - msync (28 No space left on device)' $CHECKLOG/software.log >> $LOGFILE && ERROR=5
726 if [ -r "$CHECKLOG/shell.log" ] ; then
727 grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=6
730 if [ -n "$ERROR" ] ; then
731 log "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
732 eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
733 eerror "Note: check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
737 log "Finished execution of stage 'fai dirinstall' [$(date)]"
738 einfo "Finished execution of stage 'fai dirinstall'"
744 # package validator {{{
745 CHECKLOG=/var/log/fai/$HOSTNAME/last
746 if [ -r "$CHECKLOG/dpkg.selections" ] ; then
747 package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}')
749 package_count="unknown"
753 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
755 # check for missing packages
756 if ! [ -s "$CHECKLOG/package_errors.log" ] ; then
757 einfo "No missing packages found, generating empty junit report."
759 cat > "${REPORT_MISSING_PACKAGES}" << EOF
760 <?xml version="1.0" encoding="UTF-8"?>
761 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="0" errors="0" skipped="0" assertions="0">
762 <testcase name="test_missing_packages" time="0" assertions="0">
772 einfo "Missing packages found, generating junit report."
774 if [ -r "$CHECKLOG/package_errors.log" ] ; then
775 package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}')
777 package_errors="unknown"
781 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
783 cat > "${REPORT_MISSING_PACKAGES}" << EOF
784 <?xml version="1.0" encoding="UTF-8"?>
785 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
788 for package in $(awk '{print $1}' "${CHECKLOG}/package_errors.log") ; do
789 failure_reason="$(awk "/$package/ {print \$2}" "${CHECKLOG}/package_errors.log")"
790 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
791 <testcase name="test_missing_packages_${package}" time="0" assertions="0">
792 <failure type="${failure_reason}" message="Package ${package} is missing">
793 Package $package is missing in chroot (${failure_reason})
799 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
808 if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
809 eerror "The following packages were requested for installation but could not be processed:"
810 cat "$CHECKLOG/package_errors.log"
811 eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
815 ewarn "The following packages were requested for installation but could not be processed:"
816 cat "$CHECKLOG/package_errors.log"
822 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
823 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
824 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
827 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
828 if [ -n "$BOOTSTRAP_ONLY" ] ; then
829 log "Skipping stage 'boot' as building with bootstrap only."
830 ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
832 if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
833 log "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
834 ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
837 [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
838 [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
840 # if we don't have an initrd we a) can't boot and b) there was an error
841 # during build, so check for the file:
842 INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
843 if [ -n "$INITRD" ] ; then
844 cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.img
845 find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
847 log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
848 eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
852 KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
853 if [ -n "$KERNEL_IMAGE" ] ; then
854 cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/vmlinuz
856 log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
857 eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
862 if [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootx64.efi" ] ; then
863 einfo "Moving EFI boot files into ISO path."
864 log "Moving EFI boot files into ISO path."
866 mv "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
867 mkdir -p "${BUILD_OUTPUT}/efi/boot/" || RC=$?
868 mv "${CHROOT_OUTPUT}/boot/bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi" || RC=$?
872 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
873 if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
874 log "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
875 eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
879 # copy _required_ isolinux files
880 for file in ifcpu64.c32 isolinux.bin vesamenu.c32; do
881 copy_addon_file "${file}" /usr/lib/syslinux isolinux
884 # *always* copy files to output directory so the variables
885 # get adjusted according to the build.
886 cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
888 if [ -n "$NO_ADDONS" ] ; then
889 log "Skipping installation of boot addons as requested via \$NO_ADDONS."
890 einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
892 if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
893 log "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
894 ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
896 # copy addons from system packages or grml-live-compat
897 copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
898 copy_addon_file pci.ids /usr/share/misc addons
899 copy_addon_file memtest86+.bin /boot addons
900 for file in memdisk chain.c32 hdt.c32 mboot.c32 menu.c32; do
901 copy_addon_file "${file}" /usr/lib/syslinux addons
904 # make memtest filename FAT16/8.3 compatible
905 mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
906 "${BUILD_OUTPUT}/boot/addons/memtest"
908 # copy only files so we can handle bsd4grml on its own
909 for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
910 test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
913 if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
914 log "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
915 einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
917 if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
918 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
920 log "Missing addon file: bsd4grml"
921 ewarn "Missing addon file: bsd4grml" ; eend 0
925 fi # no "$TEMPLATE_DIRECTORY"/boot/addons
928 if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
929 mkdir -p "${BUILD_OUTPUT}/boot/grub"
931 cp -a ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
933 # generate loopback.cfg config file without depending on grub's regexp module
934 # which isn't available in Debian/squeeze
935 echo "## grub2 loopback configuration" > "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
936 echo "source /boot/grub/header.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
937 for config in "${BUILD_OUTPUT}"/boot/grub/*_default.cfg "${BUILD_OUTPUT}"/boot/grub/*_options.cfg ; do
938 [ -r "$config" ] || continue
939 echo "source ${config##$BUILD_OUTPUT}" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
941 echo "source /boot/grub/addons.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
942 echo "source /boot/grub/footer.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
944 # copy grub files from target
945 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/
946 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/
947 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/
948 cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
949 cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
950 cp -a "${CHROOT_OUTPUT}"/boot/grub/grub.img "${BUILD_OUTPUT}"/boot/grub/
952 if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
953 log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
954 eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
958 mkdir -p "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
959 cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
961 # adjust boot splash information:
962 RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
963 RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
964 RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
966 if [ -r "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version ] ; then
967 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
968 sed -i "s/%DATE%/$DATE/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
971 # make sure the squashfs filename is set accordingly:
972 SQUASHFS_NAME="$GRML_NAME.squashfs"
974 if [ -n "$NO_BOOTID" ] ; then
975 log 'Skipping bootid feature as requested via $NO_BOOTID.'
976 einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
978 [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
979 [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
980 einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
981 log "Generating /conf/bootid.txt with entry ${BOOTID}."
982 echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
986 # adjust all variables in the templates with the according distribution information
987 for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
988 "${BUILD_OUTPUT}"/boot/grub/* ; do
989 if [ -r "${file}" ] && [ -f "${file}" ] ; then
990 sed -i "s/%ARCH%/$ARCH/g" "${file}"
991 sed -i "s/%DATE%/$DATE/g" "${file}"
992 sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g" "${file}"
993 sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g" "${file}"
994 sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g" "${file}"
995 sed -i "s/%GRML_NAME%/$GRML_NAME/g" "${file}"
996 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g" "${file}"
997 sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g" "${file}"
998 sed -i "s/%SHORT_NAME%/$SHORT_NAME/g" "${file}"
999 sed -i "s/%VERSION%/$VERSION/g" "${file}"
1001 [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s; boot=live; boot=live $DEFAULT_BOOTOPTIONS;" "${file}"
1003 if [ -n "$NO_BOOTID" ] ; then
1004 sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
1006 sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
1011 for param in ARCH DATE DISTRI_INFO DISTRI_NAME DISTRI_SPLASH GRML_NAME SQUASHFS_NAME \
1012 RELEASE_INFO SHORT_NAME VERSION ; do
1013 for file in $(find "${BUILD_OUTPUT}" -name "*%$param%*") ; do
1014 value="$(eval echo '$'"$param")"
1015 mv ${file} ${file/\%${param}\%/$value}
1019 # adjust bootsplash accordingly but make sure the string has the according lenght
1020 SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
1021 SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
1022 for file in f4 f5 ; do
1023 if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
1024 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
1025 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
1029 # generate addon list
1030 rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
1031 for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
1032 include_name=$(basename "$name")
1033 echo "include $include_name" >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
1036 if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
1037 log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1038 echo "include grmlmain.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1039 echo "include default.cfg" > "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1040 echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1041 echo "include grml.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1043 for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
1044 echo "include $(basename $f)" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1047 echo "include options.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1048 if [ ! -n "$NO_ADDONS" ] ; then
1049 echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1051 echo "include isoprompt.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1052 echo "include hd.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1053 echo "include hidden.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1054 else # assume we are building a custom distribution:
1055 log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1056 einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1057 if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1058 log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1060 einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1064 log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1065 echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1066 [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1070 # use old style console based isolinux method only if requested:
1071 if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
1072 log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1073 einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1074 if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1075 einfo "include for console.cfg already found, nothing to do."
1078 log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1079 einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1080 echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1084 log 'Using graphical boot menu.'
1085 if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
1086 log "include for vesamenu.cfg already found, nothing to do."
1088 log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1089 echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1093 if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
1094 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
1097 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
1098 if ! [ -r "$DPKG_LIST" ] ; then
1099 ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
1101 einfo "Storing package list information as /GRML/${GRML_NAME}/packages.txt on ISO."
1102 cp "$DPKG_LIST" "${BUILD_OUTPUT}"/GRML/"${GRML_NAME}"/packages.txt
1106 # autostart for Windows:
1107 if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
1108 cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
1111 FORCE_ISO_REBUILD=true
1112 einfo "Finished execution of stage 'boot'" ; eend 0
1116 log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
1117 eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
1121 # support installation of local files into the chroot/ISO
1122 if [ -n "$CHROOT_INSTALL" ] ; then
1123 if ! [ -d "$CHROOT_INSTALL" ] ; then
1124 log "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1125 ewarn "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1127 log "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1128 einfo "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1129 rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
1131 einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
1132 FORCE_ISO_REBUILD=true
1136 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1137 log "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
1138 ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
1139 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
1140 log "Skipping stage 'squashfs' as requested via option -q or -N"
1141 ewarn "Skipping stage 'squashfs' as requested via option -q or -N" ; eend 0
1143 mkdir -p "$BUILD_OUTPUT"/live/"${GRML_NAME}"/
1144 # make sure we don't leave (even an empty) base.tgz:
1145 [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
1147 # if unconfigured default to squashfs-tools' mksquashfs binary
1148 if [ -z "$SQUASHFS_BINARY" ] ; then
1149 SQUASHFS_BINARY='mksquashfs'
1152 if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
1153 log "Using mksquashfs binary ${SQUASHFS_BINARY}"
1154 einfo "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
1156 log "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
1157 eerror "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
1161 # use sane defaults if $SQUASHFS_OPTIONS isn't set
1162 if [ -z "$SQUASHFS_OPTIONS" ] ; then
1163 # use blocksize 256k as this gives best result with regards to time + compression
1164 SQUASHFS_OPTIONS="-b 256k"
1166 # set lzma/xz compression by default, unless -z option has been specified on command line
1167 if [ -z "$SQUASHFS_ZLIB" ] ; then
1168 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp xz"
1170 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp gzip"
1174 # support exclusion of files via exclude-file:
1175 if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
1176 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE -wildcards"
1179 # get rid of unnecessary files when building grml-small for final release:
1180 if echo "$CLASSES" | grep -q GRML_SMALL ; then
1181 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
1185 SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
1187 # informational stuff
1188 [ -n "$SQUASHFS_OPTIONS" ] && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
1189 [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
1190 einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
1192 log "$SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/${GRML_NAME}/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS"
1194 if $SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/"${GRML_NAME}"/"${GRML_NAME}".squashfs \
1195 -noappend $SQUASHFS_OPTIONS 2>"${SQUASHFS_STDERR}" ; then
1196 echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/"${GRML_NAME}"/filesystem.module
1197 log "Finished execution of stage 'squashfs' [$(date)]"
1198 einfo "Finished execution of stage 'squashfs'" ; eend 0
1200 log "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
1201 log "$(cat $SQUASHFS_STDERR)"
1202 eerror "Error: there was a critical error executing stage 'squashfs':"
1203 cat "${SQUASHFS_STDERR}"
1208 FORCE_ISO_REBUILD=true
1211 # create md5sum file:
1212 if [ -z "$BOOTSTRAP_ONLY" ] ; then
1213 ( cd $BUILD_OUTPUT/GRML/"${GRML_NAME}" &&
1214 find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
1218 # ISO_OUTPUT - mkisofs {{{
1219 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
1220 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
1222 if [ "$BOOT_METHOD" = "isolinux" ] ; then
1223 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
1224 elif [ "$BOOT_METHOD" = "grub2" ] ; then
1225 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
1228 # Work around http://bts.grml.org/grml/issue945
1229 if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
1230 log "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1231 ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1232 HYBRID_METHOD='grub2'
1236 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
1237 log "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
1238 ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
1239 elif [ -n "$SKIP_MKISOFS" ] ; then
1240 log "Skipping stage 'iso build' as requested via option -n or -N"
1241 ewarn "Skipping stage 'iso build' as requested via option -n or -N" ; eend 0
1243 mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
1245 if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; then
1246 log "Forcing rebuild of ISO because files on ISO have been modified."
1247 einfo "Forcing rebuild of ISO because files on ISO have been modified."
1250 # support xorriso as well mkisofs and genisoimage
1251 if which xorriso >/dev/null 2>&1 ; then
1252 MKISOFS='xorriso -as mkisofs'
1253 elif which mkisofs >/dev/null 2>&1; then
1255 elif which genisoimage >/dev/null 2>&1; then
1256 MKISOFS='genisoimage'
1258 log "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO."
1259 eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1
1263 einfo "Using ${MKISOFS} to build ISO." ; eend 0
1264 case "${ARCH}-${MKISOFS}" in
1265 # using -eltorito-alt-boot is limited to xorriso for now
1269 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
1270 log "Disabling (U)EFI boot support because xorriso version is too old."
1271 ewarn "Disabling (U)EFI boot support because xorriso version is too old." ; eend 0
1273 if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then
1274 einfo "Enabling (U)EFI boot."
1275 log "Enabling (U)EFI boot."
1276 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
1279 log "Disabling (U)EFI boot support because /boot/efi.img is missing."
1280 ewarn "Disabling (U)EFI boot support because /boot/efi.img is missing." ; eend 0
1289 if cd "$BUILD_OUTPUT" ; then
1290 if [ "$BOOT_METHOD" = "grub2" ]; then
1291 # make a 2048-byte bootsector for El Torito
1292 dd if=/dev/zero of=boot/grub/toriboot.bin bs=512 count=4 2>/dev/null
1293 # those are in 2048-byte sectors, so 1 16 matches 4 63 below
1294 echo 1 16 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -B 11 | \
1295 dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
1297 log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
1298 $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
1299 -l -r -J $BOOT_ARGS -no-pad \
1300 -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
1301 # both of these need core.img there, so it’s easier to write it here
1302 if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
1303 # must be <= 30720 bytes
1304 dd if=boot/grub/core.img of="${ISO_OUTPUT}/${ISO_NAME}" \
1305 conv=notrunc bs=512 seek=4 2>/dev/null
1308 # pad the output ISO to multiples of 256 KiB for partition table support
1309 siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
1310 cyls=$((siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
1311 siz=$((cyls * 16 * 32 * 512)) # size after padding
1312 dd if=/dev/zero bs=1 count=1 seek=$((siz - 1)) \
1313 of="${ISO_OUTPUT}/${ISO_NAME}" 2>/dev/null
1315 # support disabling hybrid ISO image
1316 if [ "$HYBRID_METHOD" = "disable" ] ; then
1317 log "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1318 einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1320 elif [ "$HYBRID_METHOD" = "manifold" ] || [ "$HYBRID_METHOD" = "grub2" ] ; then
1321 # isoinfo is part of both mkisofs and genisoimage so we're good
1322 bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
1323 sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p')
1325 if ! [ -r boot/grub/core.img ] ; then
1326 log "boot/grub/core.img not found, not creating manifold boot ISO file"
1327 ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
1328 elif [ "${bootoff:-0}" -lt 1 ] ; then
1329 log "isolinux.bin not found on the ISO file, disabling manifold boot"
1330 ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
1332 if [ "$HYBRID_METHOD" = "grub2" ] ; then
1333 log "Creating hybrid ISO file with manifold/grub2 method"
1334 einfo "Creating hybrid ISO file with manifold/grub2 method"
1335 # 512 bytes: MBR, partition table, load GRUB 2
1336 echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
1338 log "Creating hybrid ISO file with manifold method"
1339 einfo "Creating hybrid ISO file with manifold method"
1340 # read only one but 2048-byte sized (scale: << 2) sector
1341 echo $bootoff $bootoff | \
1342 mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
1343 fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
1346 elif [ "$HYBRID_METHOD" = "isohybrid" ] ; then
1347 if ! which isohybrid >/dev/null 2>&1 ; then
1348 bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
1350 log "Creating hybrid ISO file with isohybrid method"
1351 einfo "Creating hybrid ISO file with isohybrid method"
1352 # Notes for consideration:
1353 # "-entry 4 -type 1c"
1354 # * using 4 as the partition number is supposed to help with BIOSes
1355 # that only support USB-Zip boot
1356 # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
1357 # (hidden NTFS, IIRC), as the partition type is sometimes needed
1358 # to get the BIOS even look at the partition created by isohybrid
1359 if isohybrid --help | grep -q -- --uefi ; then
1360 if echo $CLASSES | grep -qw I386 ; then
1361 log "Detected uefi support for isohybrid but 32bit systems do not support it, ignoring."
1362 einfo "Detected uefi support for isohybrid but 32bit systems do not support it, ignoring."
1364 log "Detected uefi support for isohybrid, enabling"
1365 einfo "Detected uefi support for isohybrid, enabling"
1366 ISOHYBRID_OPTIONS=--uefi
1370 log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
1371 isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
1375 bailout 12 "Unknown HYBRID_METHOD [${HYBRID_METHOD}]. Supported values: disable, isohybrid, grub2, manifold"
1378 # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
1379 case $CLASSES in *RELEASE*)
1382 if cd $ISO_OUTPUT ; then
1383 md5sum ${ISO_NAME} > ${ISO_NAME}.md5 && \
1384 touch -r ${ISO_NAME} ${ISO_NAME}.md5
1385 sha1sum ${ISO_NAME} > ${ISO_NAME}.sha1 && \
1386 touch -r ${ISO_NAME} ${ISO_NAME}.sha1
1395 if [ "$RC" = 0 ] ; then
1396 log "Finished execution of stage 'iso build' [$(date)]"
1397 einfo "Finished execution of stage 'iso build'" ; eend 0
1399 log "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
1400 eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
1406 # netboot package {{{
1407 create_netbootpackage() {
1408 local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2"
1410 if [ -f "${OUTPUT_FILE}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1411 log "Skipping stage 'netboot' as $OUTPUT_FILE exists already."
1412 ewarn "Skipping stage 'netboot' as $OUTPUT_FILE exists already." ; eend 0
1414 elif [ -n "$SKIP_NETBOOT" ] ; then
1415 log "Skipping stage 'netboot' as requested via option -Q"
1416 ewarn "Skipping stage 'netboot' as requested via option -Q" ; eend 0
1422 if ! [ -r "${CHROOT}/usr/lib/syslinux/pxelinux.0" ] ; then
1423 ewarn "File /usr/lib/syslinux/pxelinux.0 not found in build chroot." ; eend 0
1425 einfo "Install syslinux[-common] package in chroot to get a netboot package."
1430 local OUTPUTDIR="${NETBOOT}/build_tmp"
1431 local WORKING_DIR="${OUTPUTDIR}/grml_netboot_package_${GRML_NAME}_${VERSION}/tftpboot/"
1433 mkdir -p "$WORKING_DIR"
1435 cp "${CHROOT_OUTPUT}"/boot/vmlinuz-* "$WORKING_DIR"/vmlinuz
1436 cp "${CHROOT_OUTPUT}"/boot/initrd.img-* "$WORKING_DIR"/initrd.img
1437 cp "${CHROOT_OUTPUT}"/usr/lib/syslinux/pxelinux.0 "${WORKING_DIR}/pxelinux.0"
1439 mkdir -p "${WORKING_DIR}/pxelinux.cfg"
1440 if [ -r "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" ] ; then
1441 cp "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" "${WORKING_DIR}/pxelinux.cfg/default"
1443 log "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found."
1444 ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found."
1446 log "Hint: Are you using custom templates which do not provide netboot.cfg?"
1447 ewarn "Hint: Are you using custom templates which do not provide netboot.cfg?" ; eend 0
1451 if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
1453 cd $(dirname "${OUTPUT_FILE}")
1454 sha1sum $(basename "${OUTPUT_FILE}") > "${OUTPUT_FILE}.sha1"
1456 einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0
1457 rm -rf "${OUTPUTDIR}"
1459 rm -rf "${OUTPUTDIR}"
1460 eerror "Could not generate netboot package ${OUTPUT_FILE}" ; eend 1
1465 create_netbootpackage
1468 # log build information to database if grml-live-db is installed and enabled {{{
1470 if [ -d /usr/share/grml-live-db ] ; then
1473 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
1474 [ -n "$DPKG_DATABASE" ] || DPKG_DATABASE=/var/log/grml-live.db
1475 [ -n "$DPKG_DBSCRIPT" ] || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
1476 [ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
1478 if ! [ -x "$DPKG_DBSCRIPT" ] ; then
1479 log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
1480 eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
1484 # disable by default for now, not sure whether really everyone is using a local db file
1485 #if ! touch "$DPKG_DATABASE" ; then
1486 # eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
1490 if ! [ -r "$DPKG_LIST" ] ; then
1491 log "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
1492 ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
1494 einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
1495 log "Logging $DPKG_LIST to database $DPKG_DATABASE"
1496 log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
1499 if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
1515 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
1516 log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
1518 dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
1520 einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
1524 ## END OF FILE #################################################################
1525 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2