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 # avoid leaking into chroots
18 # define function getfilesize before "set -e"
19 if stat --help >/dev/null 2>&1; then
20 getfilesize='stat -c %s' # GNU stat
22 getfilesize='stat -f %z' # BSD stat
26 # disable for now since it seems to cause some problems
29 # The line following this line is patched by debian/rules.
30 GRML_LIVE_VERSION='***UNRELEASED***'
35 ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
38 # usage information {{{
42 $PN - build process script for generating a (grml based) Linux Live-ISO
44 Usage: $PN [options, see as follows]
46 -a <architecture> architecture; available values: i386 and amd64
47 -A clean build directories before and after running
48 -b build the ISO without updating the chroot via FAI
49 -B build the ISO without touching the chroot (skips cleanup)
50 -c <classe[s]> classes to be used for building the ISO via FAI
51 -C <configfile> configuration file for grml-live
52 -d <date> use specified date instead of build time as date of release
53 -D <configdir> use specified configuration directory instead of /etc/grml/fai
54 -e <iso_name> extract ISO and squashfs contents from iso_name
55 -F force execution without prompting
56 -g <grml_name> set the grml flavour name
57 -h display short usage information and exit
58 -i <iso_name> name of ISO
59 -I <src_directory> directory which provides files that should become
60 part of the chroot/ISO
61 -n skip generation of ISO
62 -N bootstrap (build chroot) only, do not create files for ISO
63 -o <output_directory> main output directory of the build process
65 -Q skip netboot package build
66 -r <release_name> release name
67 -s <suite> Debian suite; values: etch, lenny, squeeze, sid
68 -t <template_directory> place of the templates
69 -u update existing chroot instead of rebuilding it from scratch
70 -U <username> arrange output to be owned by specified username
71 -v <version_number> specify version number of the release
72 -V increase verbosity in the build process
73 -z use ZLIB instead of LZMA/XZ compression
78 $PN -c GRMLBASE,GRML_FULL,AMD64 -o /dev/shm/grml
79 $PN -c GRMLBASE,GRML_FULL,AMD64 -i grml_0.0-1.iso -v 0.0-1
80 $PN -c GRMLBASE,GRML_FULL,AMD64 -s sid -V -r 'grml-live rocks'
82 More details: man grml-live + /usr/share/doc/grml-live/grml-live.html
83 http://grml.org/grml-live/
85 Please send your bug reports and feedback to the grml-team: http://grml.org/bugs/
87 [ "$(id -u 2>/dev/null)" != 0 ] && echo "Please notice that this script requires root permissions."
90 # make sure it's possible to get usage information without being
91 # root or actually executing the script
92 if [ "$1" = '-h' -o "$1" = '--help' ] ; then
98 # some runtime checks {{{
99 # we need root permissions for the build-process:
100 if [ "$(id -u 2>/dev/null)" != 0 ] ; then
101 echo "Error: please run this script with uid 0 (root)." >&2
105 if [ -r /var/run/fai/FAI_INSTALLATION_IN_PROGRESS ] ; then
106 echo "/usr/sbin/fai already running or was aborted before.">&2
107 echo "You may remove /var/run/fai/FAI_INSTALLATION_IN_PROGRESS and try again.">&2
112 if [ -r /var/run/fai/fai_softupdate_is_running ] ; then
113 echo "/usr/sbin/fai softupdate already running or was aborted before.">&2
114 echo "You may remove /var/run/fai/fai_softupdate_is_running and try again.">&2
119 # lsb-functions and configuration stuff {{{
120 # make sure they are not set by default
131 # don't use colors/escape sequences
132 if [ -r /lib/lsb/init-functions ] ; then
133 . /lib/lsb/init-functions
134 ! log_use_fancy_output && NOCOLORS=true
137 if [ -r /etc/grml/lsb-functions ] ; then
138 . /etc/grml/lsb-functions
140 einfo() { echo " [*] $*" ;}
141 eerror() { echo " [!] $*">&2 ;}
142 ewarn() { echo " [x] $*" ;}
144 eindent() { return 0 ;}
145 eoutdent() { return 0 ;}
148 # source main configuration file:
149 LIVE_CONF=/etc/grml/grml-live.conf
153 # umount all directories {{{
155 # make sure we don't leave any mounts - FAI doesn't remove them always
156 umount $CHROOT_OUTPUT/proc/sys/fs/binfmt_misc 2>/dev/null || /bin/true
157 umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
158 umount $CHROOT_OUTPUT/run 2>/dev/null || /bin/true
159 umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true
160 umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
161 umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
163 if [ -n "$EXTRACT_ISO_NAME" ] ; then
164 umount "$EXTRACT_ISO_NAME" 2>/dev/null || /bin/true
167 # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry
168 if [ -x /usr/lib/fai/mkramdisk ] ; then
169 /usr/lib/fai/mkramdisk -u "$(readlink -f ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true
172 umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true
173 [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
179 rm -f /var/run/fai/fai_softupdate_is_running \
180 /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
181 [ -n "$CONFIGDUMP" ] && rm -f "$CONFIGDUMP"
182 [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR"
184 [ -n "$1" ] && EXIT="$1" || EXIT="1"
185 [ -n "$2" ] && eerror "$2">&2
186 if [ -n "$CLEAN_ARTIFACTS" ]; then
189 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
190 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
194 # get rid of automatically generated conffiles
195 rm -f ${GRML_FAI_CONFIG}/nfsroot.conf
196 rm -f ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf
198 if [ -n "$CHOWN_USER" ]; then
199 log "Setting ownership"
200 einfo "Setting ownership"
201 [ -n "${OUTPUT}" -a -d "${OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${OUTPUT}"
202 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${BUILD_OUTPUT}"
203 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}"
204 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}"
205 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}"
206 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && chown -R "${CHOWN_USER}:" "${NETBOOT}"
209 log "------------------------------------------------------------------------------"
212 trap bailout 1 2 3 3 6 9 14 15
216 # some important functions {{{
219 # usage: log "string to log"
220 log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; }
222 # cut string at character number int = $1
223 # usage: cut_string 5 "1234567890" will output "12345"
225 [ -n "$2" ] || return 1
226 echo "$2" | head -c "$1"; echo -ne "\n"
229 # prepend int = $1 spaces before string = $2
230 # usage: extend_string_begin 5 "123" will output " 123"
231 extend_string_begin() {
232 [ -n "$2" ] || return 1
233 local COUNT="$(echo $2 | wc -c)"
234 local FILL="$(expr $COUNT - $1)"
235 while [ "$FILL" -gt 1 ] ; do
237 local FILL=$(expr $FILL - 1)
239 while [ "$FILL" -lt 1 ] ; do
241 local FILL=$(expr $FILL + 1)
243 echo "$2" | head -c "$1"; echo -ne "\n"
246 # append int = $1 spaces to string = $2
247 # usage: extend_string_begin 5 "123" will output "123 "
248 extend_string_end() {
249 [ -n "$2" ] || return 1
250 echo -n "$2" | head -c "$1"
251 local COUNT="$(echo $2 | wc -c)"
252 local FILL="$(expr $COUNT - $1)"
253 while [ "$FILL" -gt 1 ] ; do
255 local FILL=$(expr $FILL - 1)
257 while [ "$FILL" -lt 1 ] ; do
259 local FILL=$(expr $FILL + 1)
264 # Copy addonfile $1 from either
265 # * the chroot (via $2, the system path),
266 # * or from TEMPLATE_DIRECTORY/compat (if exists),
267 # * or from the host system (again, using $2),
268 # or warn about the missing file.
271 # * We assume that the chroot always has a "good" version of
272 # the file. Also it makes sources handling easier.
273 # * On unstable, we Recommend the Debian packages containing
274 # these files. The user can override them by putting his
275 # "better" version into the chroot.
276 # * On stable, the Debian packages are probably not available,
277 # or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
278 # our grml-live-compat package installs current file versions.
280 DEST="${BUILD_OUTPUT}/boot/$3"
281 if [ ! -d "${DEST}/" ]; then
284 if [ -e "$CHROOT_OUTPUT/$2/$1" ]; then
285 log "Copying $1 from chroot"
286 cp "$CHROOT_OUTPUT/$2/$1" "${DEST}/"
289 if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
290 log "Copying $1 from grml-live-compat"
291 cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
294 if [ -e "$2/$1" ]; then
295 log "Copying $1 from system"
296 cp "$2/$1" "${DEST}/"
300 msg="Missing addon file: \"$1\""
301 ewarn "$msg" ; eend 1
302 log "copy_addon_file: $msg"
306 # command line parsing {{{
307 while getopts "a:C:c:d:D:e:g:i:I:o:r:s:t:U:v:AbBFhnNqQuVz" opt; do
310 A) CLEAN_ARTIFACTS=1 ;;
313 c) CLASSES="$OPTARG" ;;
314 C) LOCAL_CONFIG="$(readlink -f $OPTARG)" ;;
316 D) GRML_FAI_CONFIG="$(readlink -f $OPTARG)" ;;
317 e) EXTRACT_ISO_NAME="$(readlink -f $OPTARG)" ;;
318 g) GRML_NAME="$OPTARG" ;;
319 h) usage ; bailout 0 ;;
320 i) ISO_NAME="$OPTARG" ;;
321 I) CHROOT_INSTALL="$OPTARG" ;;
323 N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;;
324 o) OUTPUT="$(readlink -f $OPTARG)" ;;
325 q) SKIP_MKSQUASHFS=1 ;;
327 r) RELEASENAME="$OPTARG" ;;
328 s) SUITE="$OPTARG" ;;
329 t) TEMPLATE_DIRECTORY="$OPTARG";;
330 v) VERSION="$OPTARG" ;;
333 U) CHOWN_USER="$OPTARG" ;;
335 z) SQUASHFS_ZLIB=1 ;;
336 ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
339 shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter
342 # read local (non-packaged) configuration {{{
343 if [ -z "$LOCAL_CONFIG" ]; then
344 if [ -r "/etc/grml/grml-live.local" ]; then
345 LOCAL_CONFIG="/etc/grml/grml-live.local"
348 if [ -n "$LOCAL_CONFIG" ]; then
349 if [ -r "$LOCAL_CONFIG" ]; then
352 eerror "Could not read specified local configuration file \"$LOCAL_CONFIG\"."
355 LOCAL_CONFIG=$(readlink -f "$LOCAL_CONFIG")
360 if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
361 eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated."
362 ewarn "Please set up \${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead."
367 # assume sane defaults (if not set already) {{{
368 [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
369 [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
370 [ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_FULL,$(echo ${ARCH} | tr 'a-z' 'A-Z')"
371 [ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)"
372 [ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators'
373 [ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
374 [ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
375 [ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
376 [ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
377 [ -n "$GRML_NAME" ] || GRML_NAME='grml'
378 [ -n "$HOSTNAME" ] || HOSTNAME='grml'
379 [ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='isohybrid'
380 [ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
381 [ -n "$SQUASHFS_EXCLUDES_FILE" ] || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
382 [ -n "$SUITE" ] || SUITE='testing'
383 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
384 [ -n "$USERNAME" ] || USERNAME='grml'
385 [ -n "$VERSION" ] || VERSION='0.0.1'
387 # output specific stuff, depends on $OUTPUT (iff not set):
388 [ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live'
389 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
390 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
391 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
392 [ -n "$LOG_OUTPUT" ] || LOG_OUTPUT="$OUTPUT/grml_logs"
393 [ -n "$REPORTS" ] || REPORTS="${LOG_OUTPUT}/reports/"
394 [ -n "$NETBOOT" ] || NETBOOT="${OUTPUT}/netboot/"
397 # some misc checks before executing FAI {{{
398 [ -n "$CLASSES" ] || bailout 1 "Error: \$CLASSES unset, please set it in $LIVE_CONF or
399 specify it on the command line using the -c option."
400 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
401 specify it on the command line using the -o option."
403 # trim characters that are known to cause problems inside $GRML_NAME;
404 # for example isolinux does not like '-' inside the directory name
405 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
407 # export variables to have them available in fai scripts:
408 [ -n "$GRML_NAME" ] && export GRML_NAME="$GRML_NAME"
409 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
412 # ZERO_LOGFILE - check for backwards compatibility reasons {{{
413 # this was default behaviour until grml-live 0.9.34:
414 if [ -n "$ZERO_LOGFILE" ] ; then
415 PRESERVE_LOGFILE='' # make sure it's cleaned then
416 ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
417 ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
422 # ask user whether the setup is ok {{{
423 if [ -z "$FORCE" ] ; then
425 echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
427 echo " FAI classes: $CLASSES"
428 [ -n "$LOCAL_CONFIG" ] && echo " Configuration: $LOCAL_CONFIG"
429 [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG"
430 echo " main directory: $OUTPUT"
431 [ -n "$EXTRACT_ISO_NAME" ] && echo " Extract ISO: $EXTRACT_ISO_NAME"
432 [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT"
433 [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT"
434 [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT"
435 [ -n "$GRML_NAME" ] && echo " Grml name: $GRML_NAME"
436 [ -n "$RELEASENAME" ] && echo " Release name: $RELEASENAME"
437 [ -n "$DATE" ] && echo " Build date: $DATE"
438 [ -n "$VERSION" ] && echo " Grml version: $VERSION"
439 [ -n "$SUITE" ] && echo " Debian suite: $SUITE"
440 [ -n "$ARCH" ] && echo " Architecture: $ARCH"
441 [ -n "$BOOT_METHOD" ] && echo " Boot method: $BOOT_METHOD"
442 [ -n "$HYBRID_METHOD" ] && echo " Hybrid method: $HYBRID_METHOD"
443 [ -n "$TEMPLATE_DIRECTORY" ] && echo " Template files: $TEMPLATE_DIRECTORY"
444 [ -n "$CHROOT_INSTALL" ] && echo " Install files from directory to chroot: $CHROOT_INSTALL"
445 [ -n "$BOOTID" ] && echo " Boot identifier: $BOOTID"
446 [ -n "$NO_BOOTID" ] && echo " Skipping bootid feature."
447 [ -n "$CHOWN_USER" ] && echo " Output owner: $CHOWN_USER"
448 [ -n "$DEFAULT_BOOTOPTIONS" ] && echo " Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
449 [ -n "$FAI_ARGS" ] && echo " Additional arguments for FAI: $FAI_ARGS"
450 [ -n "$LOGFILE" ] && echo " Logging to file: $LOGFILE"
451 [ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA/XZ) compression."
452 [ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
453 [ -n "$VERBOSE" ] && echo " Using VERBOSE mode."
454 [ -n "$CLEAN_ARTIFACTS" ] && echo " Will clean output before and after running."
455 [ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation."
456 if [ -n "$BOOTSTRAP_ONLY" ] ; then
457 echo " Bootstrapping only and not building (files for) ISO."
459 [ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file."
460 [ -n "$SKIP_NETBOOT" ] && echo " Skipping creation of NETBOOT package."
461 [ -n "$SKIP_MKISOFS" ] && echo " Skipping creation of ISO file."
462 [ -n "$BUILD_ONLY" ] && echo " Executing BUILD_ONLY instead of fresh installation or UPDATE."
463 [ -n "$BUILD_DIRTY" ] && echo " Executing BUILD_DIRTY to leave chroot untouched."
466 echo -n "Is this ok for you? [y/N] "
468 if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
470 echo "Exiting as requested."
477 # clean up before start {{{
478 if [ -n "${CLEAN_ARTIFACTS}" ]; then
479 echo "Wiping old artifacts"
480 [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
481 [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}"
482 [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && rm -r "${ISO_OUTPUT}"
483 [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && rm -r "${LOG_OUTPUT}"
484 [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && rm -r "${NETBOOT}"
488 # create log file {{{
489 [ -n "$LOGFILE" ] || LOGFILE=${LOG_OUTPUT}/grml-live.log
490 mkdir -p $(dirname "${LOGFILE}")
492 chown root:adm $LOGFILE
496 # clean/zero/remove logfiles {{{
498 if [ -n "$PRESERVE_LOGFILE" ] ; then
499 echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
501 # make sure it is empty (as it is e.g. appended to grml-live-db)
505 if [ -n "$ZERO_FAI_LOGFILE" ] ; then
506 if [ -d /var/log/fai/"$HOSTNAME" ] ; then
507 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
508 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
509 rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
510 rm -f /var/log/fai/"$HOSTNAME"/last \
511 /var/log/fai/"$HOSTNAME"/last-dirinstall \
512 /var/log/fai/"$HOSTNAME"/last-softupdate
517 # source config and startup {{{
518 if [ -n "$CONFIG" ] ; then
519 if ! [ -f "$CONFIG" ] ; then
520 log "Error: $CONFIG could not be read. Exiting. [$(date)]"
521 eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
524 log "Sourcing $CONFIG"
529 start_seconds=$(cut -d . -f 1 /proc/uptime)
530 log "------------------------------------------------------------------------------"
531 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
532 log "Using local config file: $LOCAL_CONFIG"
533 log "Executed grml-live command line:"
536 einfo "Logging actions to logfile $LOGFILE"
539 # dump config variables into file, for script access {{{
542 '^(GRML_NAME|RELEASENAME|DATE|VERSION|SUITE|ARCH|DISTRI_NAME|USERNAME|HOSTNAME|APT_PROXY)=' \
546 # unpack iso/squashfs {{{
548 if [ -n "$EXTRACT_ISO_NAME" ]; then
549 log "Unpacking ISO from ${EXTRACT_ISO_NAME}"
550 einfo "Unpacking ISO from ${EXTRACT_ISO_NAME}"
551 local mountpoint=$(mktemp -d)
553 mount -o loop "${EXTRACT_ISO_NAME}" "$mountpoint" ; rc=$?
554 if [ "$rc" != 0 ]; then
557 eerror "mount failed"
562 if ls "${mountpoint}"/live/*/*.squashfs 2>/dev/null | grep -q . ; then # ISOs >=2011.12
563 log "Using ${mountpoint}/live/*/*.squashfs for unsquashfs"
564 unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*/*.squashfs ; rc=$?
565 elif ls "${mountpoint}"/live/*.squashfs 2>/dev/null | grep -q . ; then # ISOs before 2011.12
566 log "Using ${mountpoint}/live/*.squashfs for unsquashfs"
567 unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*.squashfs ; rc=$?
569 log "Error: Could not find any *.squashfs files on the ISO"
570 eerror "Error: Could not find any *.squashfs files on the ISO"
577 if [ "$rc" != 0 ]; then
578 log "unsquashfs failed"
579 eerror "unsquashfs failed"
588 # on-the-fly configuration {{{
590 # does this suck? YES!
591 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
593 unstable) SUITE='sid' ; CLASSES="DEBIAN_UNSTABLE,$CLASSES" ;;
594 *) CLASSES="DEBIAN_$(echo $SUITE | tr 'a-z' 'A-Z'),$CLASSES";;
596 export SUITE # make sure it's available in FAI scripts
598 # validate whether the specified architecture class matches the
599 # architecture (option), otherwise installation of kernel will fail
600 if echo $CLASSES | grep -qw I386 ; then
601 if ! [[ "$ARCH" == "i386" ]] ; then
602 log "Error: You specified the I386 class but are trying to build something else (AMD64?)."
603 eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
604 eerror "Tip: Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
608 elif echo $CLASSES | grep -qi amd64 ; then
609 if ! [[ "$ARCH" == "amd64" ]] ; then
610 log "Error: You specified the AMD64 class but are trying to build something else (I386?)."
611 eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
612 eerror "Tip: Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
618 # generate nfsroot configuration for FAI on the fly
619 if [ -z "$FAI_DEBOOTSTRAP" ] ; then
620 FAI_DEBOOTSTRAP="$SUITE http://cdn.debian.net/debian"
623 if [ -z "$FAI_DEBOOTSTRAP_OPTS" ] ; then
624 FAI_DEBOOTSTRAP_OPTS="--exclude=info,tasksel,tasksel-data --arch $ARCH"
627 # create backup of old (not yet automatically generated) config file
628 if [ -f "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" ] ; then
629 if ! grep -q 'This is an automatically generated file by grml-live' "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" ; then
630 ewarn "Found old ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf - moving to ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf.outdated"
631 mv "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf.outdated"
636 echo "# This is an automatically generated file by grml-live.
637 # Do NOT edit this file, your changes will be lost.
638 FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"
639 FAI_DEBOOTSTRAP_OPTS=\"$FAI_DEBOOTSTRAP_OPTS\"
640 # EOF " > "${GRML_FAI_CONFIG}/nfsroot.conf"
641 # support FAI <=3.4.8, versions >=4.0 use nfsroot.conf
642 ( cd ${GRML_FAI_CONFIG} && ln -sf nfsroot.conf make-fai-nfsroot.conf )
645 # CHROOT_OUTPUT - execute FAI {{{
646 if [ -n "$BUILD_DIRTY" ]; then
647 log "Skipping stage 'fai' as requested via option -B"
648 ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
650 [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
652 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
653 FAI_ACTION=softupdate
655 FAI_ACTION=dirinstall
658 if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
659 if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
660 log "Error: does not look like you have a working chroot. Updating/building not possible."
661 eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
667 if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
668 log "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
669 ewarn "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
671 mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
673 if [ -n "${MIRROR_DIRECTORY}" ] ; then
674 mkdir -p "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
675 mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
678 mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
679 mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
681 log "Executed FAI command line:"
682 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"
683 BUILD_ONLY="$BUILD_ONLY" BOOTSTRAP_ONLY="$BOOTSTRAP_ONLY" GRML_LIVE_CONFIG="$CONFIGDUMP" fai $VERBOSE \
684 -C "$GRML_FAI_CONFIG" -s "file:///$GRML_FAI_CONFIG/config" -c"$CLASSES" \
685 -u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
686 RC="$PIPESTATUS" # notice: bash-only
688 # provide inform fai about the ISO we build, needs to be provided
689 # *after* FAI stage, otherwise FAI skips the debootstrap stage if
690 # there is not BASEFILE (as it checks for presence of /etc) :(
691 echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
692 [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
693 [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
695 FORCE_ISO_REBUILD=true
697 if [ "$RC" != 0 ] ; then
698 log "Error: critical error while executing fai [exit code ${RC}]. Exiting."
699 eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
703 # move fai logs into grml_logs directory
704 mkdir -p "$LOG_OUTPUT"/fai/
705 cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
706 rm -rf "$CHROOT_OUTPUT"/var/log/fai
708 # store copy of autogenerated configuration file
709 cp ${GRML_FAI_CONFIG}/nfsroot.conf "$LOG_OUTPUT"/fai/
711 # copy fai package list
712 cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/
714 chown root:adm "$LOG_OUTPUT"/fai/*
715 chmod 664 "$LOG_OUTPUT"/fai/*
719 # notice: 'fai dirinstall' does not seem to exit appropriate, so:
721 CHECKLOG="$LOG_OUTPUT"/fai/
722 if [ -r "$CHECKLOG/software.log" ] ; then
723 # 1 errors during executing of commands
724 grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1
725 grep 'E: Method http has died unexpectedly!' $CHECKLOG/software.log >> $LOGFILE && ERROR=2
726 grep 'ERROR: chroot' $CHECKLOG/software.log >> $LOGFILE && ERROR=3
727 grep 'E: Failed to fetch' $CHECKLOG/software.log >> $LOGFILE && ERROR=4
728 grep 'Unable to write mmap - msync (28 No space left on device)' $CHECKLOG/software.log >> $LOGFILE && ERROR=5
731 if [ -r "$CHECKLOG/shell.log" ] ; then
732 grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=6
735 if [ -n "$ERROR" ] ; then
736 log "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
737 eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
738 eerror "Note: check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
742 log "Finished execution of stage 'fai dirinstall' [$(date)]"
743 einfo "Finished execution of stage 'fai dirinstall'"
749 # package validator {{{
750 CHECKLOG=/var/log/fai/$HOSTNAME/last
751 if [ -r "$CHECKLOG/dpkg.selections" ] ; then
752 package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}')
754 package_count="unknown"
758 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
760 # check for missing packages
761 if ! [ -s "$CHECKLOG/package_errors.log" ] ; then
762 einfo "No missing packages found, generating empty junit report."
764 cat > "${REPORT_MISSING_PACKAGES}" << EOF
765 <?xml version="1.0" encoding="UTF-8"?>
766 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="0" errors="0" skipped="0" assertions="0">
767 <testcase name="test_missing_packages" time="0" assertions="0">
777 einfo "Missing packages found, generating junit report."
779 if [ -r "$CHECKLOG/package_errors.log" ] ; then
780 package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}')
782 package_errors="unknown"
786 REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml"
788 cat > "${REPORT_MISSING_PACKAGES}" << EOF
789 <?xml version="1.0" encoding="UTF-8"?>
790 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
793 for package in $(awk '{print $1}' "${CHECKLOG}/package_errors.log") ; do
794 failure_reason="$(awk "/$package/ {print \$2}" "${CHECKLOG}/package_errors.log")"
795 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
796 <testcase name="test_missing_packages_${package}" time="0" assertions="0">
797 <failure type="${failure_reason}" message="Package ${package} is missing">
798 Package $package is missing in chroot (${failure_reason})
804 cat >> "${REPORT_MISSING_PACKAGES}" << EOF
813 if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
814 eerror "The following packages were requested for installation but could not be processed:"
815 cat "$CHECKLOG/package_errors.log"
816 eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
820 ewarn "The following packages were requested for installation but could not be processed:"
821 cat "$CHECKLOG/package_errors.log"
827 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
828 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
829 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
832 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
833 if [ -n "$BOOTSTRAP_ONLY" ] ; then
834 log "Skipping stage 'boot' as building with bootstrap only."
835 ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
837 if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
838 log "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
839 ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
842 [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
843 [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
845 # if we don't have an initrd we a) can't boot and b) there was an error
846 # during build, so check for the file:
847 INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
848 if [ -n "$INITRD" ] ; then
849 cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.img
850 find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
852 log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
853 eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
857 KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
858 if [ -n "$KERNEL_IMAGE" ] ; then
859 cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/vmlinuz
861 log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
862 eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
867 if [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootx64.efi" ] ; then
868 einfo "Moving EFI boot files into ISO path."
869 log "Moving EFI boot files into ISO path."
871 mv "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
872 mkdir -p "${BUILD_OUTPUT}/efi/boot/" || RC=$?
873 mv "${CHROOT_OUTPUT}/boot/bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi" || RC=$?
877 [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
878 if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
879 log "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
880 eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
884 # copy _required_ isolinux files
885 for file in ifcpu64.c32 isolinux.bin vesamenu.c32; do
886 copy_addon_file "${file}" /usr/lib/syslinux isolinux
889 # *always* copy files to output directory so the variables
890 # get adjusted according to the build.
891 cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
893 if [ -n "$NO_ADDONS" ] ; then
894 log "Skipping installation of boot addons as requested via \$NO_ADDONS."
895 einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
897 if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
898 log "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
899 ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
901 # copy addons from system packages or grml-live-compat
902 copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
903 copy_addon_file pci.ids /usr/share/misc addons
904 copy_addon_file memtest86+.bin /boot addons
905 for file in memdisk chain.c32 hdt.c32 mboot.c32 menu.c32; do
906 copy_addon_file "${file}" /usr/lib/syslinux addons
909 # make memtest filename FAT16/8.3 compatible
910 mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
911 "${BUILD_OUTPUT}/boot/addons/memtest"
913 # copy only files so we can handle bsd4grml on its own
914 for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
915 test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
918 if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
919 log "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
920 einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
922 if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
923 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
925 log "Missing addon file: bsd4grml"
926 ewarn "Missing addon file: bsd4grml" ; eend 0
930 fi # no "$TEMPLATE_DIRECTORY"/boot/addons
933 if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
934 mkdir -p "${BUILD_OUTPUT}/boot/grub"
936 cp -a ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
938 # generate loopback.cfg config file without depending on grub's regexp module
939 # which isn't available in Debian/squeeze
940 echo "## grub2 loopback configuration" > "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
941 echo "source /boot/grub/header.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
942 for config in "${BUILD_OUTPUT}"/boot/grub/*_default.cfg "${BUILD_OUTPUT}"/boot/grub/*_options.cfg ; do
943 [ -r "$config" ] || continue
944 echo "source ${config##$BUILD_OUTPUT}" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
946 echo "source /boot/grub/addons.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
947 echo "source /boot/grub/footer.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
949 # copy grub files from target
950 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/
951 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/
952 cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/
953 cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
954 cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
955 cp -a "${CHROOT_OUTPUT}"/boot/grub/grub.img "${BUILD_OUTPUT}"/boot/grub/
957 if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
958 log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
959 eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
963 mkdir -p "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
964 cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
966 # adjust boot splash information:
967 RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
968 RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
969 RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
971 if [ -r "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version ] ; then
972 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
973 sed -i "s/%DATE%/$DATE/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
976 # make sure the squashfs filename is set accordingly:
977 SQUASHFS_NAME="$GRML_NAME.squashfs"
979 if [ -n "$NO_BOOTID" ] ; then
980 log 'Skipping bootid feature as requested via $NO_BOOTID.'
981 einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
983 [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
984 [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
985 einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
986 log "Generating /conf/bootid.txt with entry ${BOOTID}."
987 echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
991 # adjust all variables in the templates with the according distribution information
992 for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
993 "${BUILD_OUTPUT}"/boot/grub/* ; do
994 if [ -r "${file}" ] && [ -f "${file}" ] ; then
995 sed -i "s/%ARCH%/$ARCH/g" "${file}"
996 sed -i "s/%DATE%/$DATE/g" "${file}"
997 sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g" "${file}"
998 sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g" "${file}"
999 sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g" "${file}"
1000 sed -i "s/%GRML_NAME%/$GRML_NAME/g" "${file}"
1001 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g" "${file}"
1002 sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g" "${file}"
1003 sed -i "s/%SHORT_NAME%/$SHORT_NAME/g" "${file}"
1004 sed -i "s/%VERSION%/$VERSION/g" "${file}"
1006 [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s; boot=live; boot=live $DEFAULT_BOOTOPTIONS;" "${file}"
1008 if [ -n "$NO_BOOTID" ] ; then
1009 sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
1011 sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
1016 for param in ARCH DATE DISTRI_INFO DISTRI_NAME DISTRI_SPLASH GRML_NAME SQUASHFS_NAME \
1017 RELEASE_INFO SHORT_NAME VERSION ; do
1018 for file in $(find "${BUILD_OUTPUT}" -name "*%$param%*") ; do
1019 value="$(eval echo '$'"$param")"
1020 mv ${file} ${file/\%${param}\%/$value}
1024 # adjust bootsplash accordingly but make sure the string has the according lenght
1025 SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
1026 SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
1027 for file in f4 f5 ; do
1028 if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
1029 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
1030 sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
1034 # generate addon list
1035 rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
1036 for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
1037 include_name=$(basename "$name")
1038 echo "include $include_name" >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
1041 if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
1042 log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1043 echo "include grmlmain.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1044 echo "include default.cfg" > "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1045 echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1046 echo "include grml.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1048 for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
1049 echo "include $(basename $f)" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1052 echo "include options.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1053 if [ ! -n "$NO_ADDONS" ] ; then
1054 echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1056 echo "include isoprompt.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1057 echo "include hd.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1058 echo "include hidden.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
1059 else # assume we are building a custom distribution:
1060 log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1061 einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
1062 if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1063 log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1065 einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
1069 log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1070 echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1071 [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
1075 # use old style console based isolinux method only if requested:
1076 if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
1077 log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1078 einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
1079 if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
1080 einfo "include for console.cfg already found, nothing to do."
1083 log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1084 einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1085 echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1089 log 'Using graphical boot menu.'
1090 if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
1091 log "include for vesamenu.cfg already found, nothing to do."
1093 log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1094 echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
1098 if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
1099 sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
1102 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
1103 if ! [ -r "$DPKG_LIST" ] ; then
1104 ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
1106 einfo "Storing package list information as /GRML/${GRML_NAME}/packages.txt on ISO."
1107 cp "$DPKG_LIST" "${BUILD_OUTPUT}"/GRML/"${GRML_NAME}"/packages.txt
1111 # autostart for Windows:
1112 if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
1113 cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
1116 FORCE_ISO_REBUILD=true
1117 einfo "Finished execution of stage 'boot'" ; eend 0
1121 log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
1122 eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
1126 # support installation of local files into the chroot/ISO
1127 if [ -n "$CHROOT_INSTALL" ] ; then
1128 if ! [ -d "$CHROOT_INSTALL" ] ; then
1129 log "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1130 ewarn "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
1132 log "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1133 einfo "Copying local files to chroot as requested via \$CHROOT_INSTALL"
1134 rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
1136 einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
1137 FORCE_ISO_REBUILD=true
1141 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1142 log "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
1143 ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
1144 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
1145 log "Skipping stage 'squashfs' as requested via option -q or -N"
1146 ewarn "Skipping stage 'squashfs' as requested via option -q or -N" ; eend 0
1148 mkdir -p "$BUILD_OUTPUT"/live/"${GRML_NAME}"/
1149 # make sure we don't leave (even an empty) base.tgz:
1150 [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
1152 # if unconfigured default to squashfs-tools' mksquashfs binary
1153 if [ -z "$SQUASHFS_BINARY" ] ; then
1154 SQUASHFS_BINARY='mksquashfs'
1157 if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
1158 log "Using mksquashfs binary ${SQUASHFS_BINARY}"
1159 einfo "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
1161 log "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
1162 eerror "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
1166 # use sane defaults if $SQUASHFS_OPTIONS isn't set
1167 if [ -z "$SQUASHFS_OPTIONS" ] ; then
1168 # use blocksize 256k as this gives best result with regards to time + compression
1169 SQUASHFS_OPTIONS="-b 256k"
1171 # set lzma/xz compression by default, unless -z option has been specified on command line
1172 if [ -z "$SQUASHFS_ZLIB" ] ; then
1173 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp xz"
1175 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp gzip"
1179 # support exclusion of files via exclude-file:
1180 if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
1181 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE -wildcards"
1184 # get rid of unnecessary files when building grml-small for final release:
1185 if echo "$CLASSES" | grep -q GRML_SMALL ; then
1186 SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
1190 SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
1192 # informational stuff
1193 [ -n "$SQUASHFS_OPTIONS" ] && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
1194 [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
1195 einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
1197 log "$SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/${GRML_NAME}/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS"
1199 if $SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/"${GRML_NAME}"/"${GRML_NAME}".squashfs \
1200 -noappend $SQUASHFS_OPTIONS 2>"${SQUASHFS_STDERR}" ; then
1201 echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/"${GRML_NAME}"/filesystem.module
1202 log "Finished execution of stage 'squashfs' [$(date)]"
1203 einfo "Finished execution of stage 'squashfs'" ; eend 0
1205 log "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
1206 log "$(cat $SQUASHFS_STDERR)"
1207 eerror "Error: there was a critical error executing stage 'squashfs':"
1208 cat "${SQUASHFS_STDERR}"
1213 FORCE_ISO_REBUILD=true
1216 # create md5sum file:
1217 if [ -z "$BOOTSTRAP_ONLY" ] ; then
1218 ( cd $BUILD_OUTPUT/GRML/"${GRML_NAME}" &&
1219 find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
1223 # ISO_OUTPUT - mkisofs {{{
1224 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
1225 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
1227 if [ "$BOOT_METHOD" = "isolinux" ] ; then
1228 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
1229 elif [ "$BOOT_METHOD" = "grub2" ] ; then
1230 BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
1233 # Work around http://bts.grml.org/grml/issue945
1234 if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
1235 log "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1236 ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
1237 HYBRID_METHOD='grub2'
1241 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
1242 log "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
1243 ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
1244 elif [ -n "$SKIP_MKISOFS" ] ; then
1245 log "Skipping stage 'iso build' as requested via option -n or -N"
1246 ewarn "Skipping stage 'iso build' as requested via option -n or -N" ; eend 0
1248 mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
1250 if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; then
1251 log "Forcing rebuild of ISO because files on ISO have been modified."
1252 einfo "Forcing rebuild of ISO because files on ISO have been modified."
1255 # support xorriso as well mkisofs and genisoimage
1256 if which xorriso >/dev/null 2>&1 ; then
1257 MKISOFS='xorriso -as mkisofs'
1258 elif which mkisofs >/dev/null 2>&1; then
1260 elif which genisoimage >/dev/null 2>&1; then
1261 MKISOFS='genisoimage'
1263 log "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO."
1264 eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1
1268 einfo "Using ${MKISOFS} to build ISO." ; eend 0
1269 case "${ARCH}-${MKISOFS}" in
1270 # using -eltorito-alt-boot is limited to xorriso for now
1274 if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then
1275 log "Disabling (U)EFI boot support because xorriso version is too old."
1276 ewarn "Disabling (U)EFI boot support because xorriso version is too old." ; eend 0
1278 if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then
1279 einfo "Enabling (U)EFI boot."
1280 log "Enabling (U)EFI boot."
1281 BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot"
1284 log "Disabling (U)EFI boot support because /boot/efi.img is missing."
1285 ewarn "Disabling (U)EFI boot support because /boot/efi.img is missing." ; eend 0
1294 if cd "$BUILD_OUTPUT" ; then
1295 if [ "$BOOT_METHOD" = "grub2" ]; then
1296 # make a 2048-byte bootsector for El Torito
1297 dd if=/dev/zero of=boot/grub/toriboot.bin bs=512 count=4 2>/dev/null
1298 # those are in 2048-byte sectors, so 1 16 matches 4 63 below
1299 echo 1 16 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -B 11 | \
1300 dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
1302 log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
1303 $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
1304 -l -r -J $BOOT_ARGS -no-pad \
1305 -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
1306 # both of these need core.img there, so it’s easier to write it here
1307 if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
1308 # must be <= 30720 bytes
1309 dd if=boot/grub/core.img of="${ISO_OUTPUT}/${ISO_NAME}" \
1310 conv=notrunc bs=512 seek=4 2>/dev/null
1313 # pad the output ISO to multiples of 256 KiB for partition table support
1314 siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
1315 cyls=$((siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
1316 siz=$((cyls * 16 * 32 * 512)) # size after padding
1317 dd if=/dev/zero bs=1 count=1 seek=$((siz - 1)) \
1318 of="${ISO_OUTPUT}/${ISO_NAME}" 2>/dev/null
1320 # support disabling hybrid ISO image
1321 if [ "$HYBRID_METHOD" = "disable" ] ; then
1322 log "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1323 einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
1325 elif [ "$HYBRID_METHOD" = "manifold" ] || [ "$HYBRID_METHOD" = "grub2" ] ; then
1326 # isoinfo is part of both mkisofs and genisoimage so we're good
1327 bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
1328 sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p')
1330 if ! [ -r boot/grub/core.img ] ; then
1331 log "boot/grub/core.img not found, not creating manifold boot ISO file"
1332 ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
1333 elif [ "${bootoff:-0}" -lt 1 ] ; then
1334 log "isolinux.bin not found on the ISO file, disabling manifold boot"
1335 ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
1337 if [ "$HYBRID_METHOD" = "grub2" ] ; then
1338 log "Creating hybrid ISO file with manifold/grub2 method"
1339 einfo "Creating hybrid ISO file with manifold/grub2 method"
1340 # 512 bytes: MBR, partition table, load GRUB 2
1341 echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
1343 log "Creating hybrid ISO file with manifold method"
1344 einfo "Creating hybrid ISO file with manifold method"
1345 # read only one but 2048-byte sized (scale: << 2) sector
1346 echo $bootoff $bootoff | \
1347 mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
1348 fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
1351 elif [ "$HYBRID_METHOD" = "isohybrid" ] ; then
1352 if ! which isohybrid >/dev/null 2>&1 ; then
1353 bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common"
1355 log "Creating hybrid ISO file with isohybrid method"
1356 einfo "Creating hybrid ISO file with isohybrid method"
1357 # Notes for consideration:
1358 # "-entry 4 -type 1c"
1359 # * using 4 as the partition number is supposed to help with BIOSes
1360 # that only support USB-Zip boot
1361 # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
1362 # (hidden NTFS, IIRC), as the partition type is sometimes needed
1363 # to get the BIOS even look at the partition created by isohybrid
1364 if isohybrid --help | grep -q -- --uefi ; then
1365 if echo $CLASSES | grep -qw I386 ; then
1366 log "Detected uefi support for isohybrid but 32bit systems do not support it, ignoring."
1367 einfo "Detected uefi support for isohybrid but 32bit systems do not support it, ignoring."
1369 log "Detected uefi support for isohybrid, enabling"
1370 einfo "Detected uefi support for isohybrid, enabling"
1371 ISOHYBRID_OPTIONS=--uefi
1375 log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
1376 isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
1380 bailout 12 "Unknown HYBRID_METHOD [${HYBRID_METHOD}]. Supported values: disable, isohybrid, grub2, manifold"
1383 # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
1384 case $CLASSES in *RELEASE*)
1387 if cd $ISO_OUTPUT ; then
1388 md5sum ${ISO_NAME} > ${ISO_NAME}.md5 && \
1389 touch -r ${ISO_NAME} ${ISO_NAME}.md5
1390 sha1sum ${ISO_NAME} > ${ISO_NAME}.sha1 && \
1391 touch -r ${ISO_NAME} ${ISO_NAME}.sha1
1400 if [ "$RC" = 0 ] ; then
1401 log "Finished execution of stage 'iso build' [$(date)]"
1402 einfo "Finished execution of stage 'iso build'" ; eend 0
1404 log "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
1405 eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
1411 # netboot package {{{
1412 create_netbootpackage() {
1413 local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2"
1415 if [ -f "${OUTPUT_FILE}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
1416 log "Skipping stage 'netboot' as $OUTPUT_FILE exists already."
1417 ewarn "Skipping stage 'netboot' as $OUTPUT_FILE exists already." ; eend 0
1419 elif [ -n "$SKIP_NETBOOT" ] ; then
1420 log "Skipping stage 'netboot' as requested via option -Q"
1421 ewarn "Skipping stage 'netboot' as requested via option -Q" ; eend 0
1427 if ! [ -r "${CHROOT}/usr/lib/syslinux/pxelinux.0" ] ; then
1428 ewarn "File /usr/lib/syslinux/pxelinux.0 not found in build chroot." ; eend 0
1430 einfo "Install syslinux[-common] package in chroot to get a netboot package."
1435 local OUTPUTDIR="${NETBOOT}/build_tmp"
1436 local WORKING_DIR="${OUTPUTDIR}/grml_netboot_package_${GRML_NAME}_${VERSION}/tftpboot/"
1438 mkdir -p "$WORKING_DIR"
1440 cp "${CHROOT_OUTPUT}"/boot/vmlinuz-* "$WORKING_DIR"/vmlinuz
1441 cp "${CHROOT_OUTPUT}"/boot/initrd.img-* "$WORKING_DIR"/initrd.img
1442 cp "${CHROOT_OUTPUT}"/usr/lib/syslinux/pxelinux.0 "${WORKING_DIR}/pxelinux.0"
1444 mkdir -p "${WORKING_DIR}/pxelinux.cfg"
1445 if [ -r "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" ] ; then
1446 cp "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" "${WORKING_DIR}/pxelinux.cfg/default"
1448 log "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found."
1449 ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found."
1451 log "Hint: Are you using custom templates which do not provide netboot.cfg?"
1452 ewarn "Hint: Are you using custom templates which do not provide netboot.cfg?" ; eend 0
1456 if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
1458 cd $(dirname "${OUTPUT_FILE}")
1459 sha1sum $(basename "${OUTPUT_FILE}") > "${OUTPUT_FILE}.sha1"
1461 einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0
1462 rm -rf "${OUTPUTDIR}"
1464 rm -rf "${OUTPUTDIR}"
1465 eerror "Could not generate netboot package ${OUTPUT_FILE}" ; eend 1
1470 create_netbootpackage
1473 # log build information to database if grml-live-db is installed and enabled {{{
1475 if [ -d /usr/share/grml-live-db ] ; then
1478 DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
1479 [ -n "$DPKG_DATABASE" ] || DPKG_DATABASE=/var/log/grml-live.db
1480 [ -n "$DPKG_DBSCRIPT" ] || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
1481 [ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
1483 if ! [ -x "$DPKG_DBSCRIPT" ] ; then
1484 log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
1485 eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
1489 # disable by default for now, not sure whether really everyone is using a local db file
1490 #if ! touch "$DPKG_DATABASE" ; then
1491 # eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
1495 if ! [ -r "$DPKG_LIST" ] ; then
1496 log "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
1497 ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
1499 einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
1500 log "Logging $DPKG_LIST to database $DPKG_DATABASE"
1501 log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
1504 if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
1520 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
1521 log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
1523 dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
1525 einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
1529 ## END OF FILE #################################################################
1530 # vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2