make sure we don't leave any FAI ramdisks behind
[grml-live.git] / grml-live
index f0eb8d8..8ec8348 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -20,13 +20,13 @@ else
 fi
 
 # exit on any error:
 fi
 
 # exit on any error:
-set -e
+# disable for now since it seems to cause some problems
+# set -e
 
 # global variables
 
 # global variables
-GRML_LIVE_VERSION='0.10.1'
+GRML_LIVE_VERSION='0.16.1'
 PN="$(basename $0)"
 CMDLINE="$0 $@"
 PN="$(basename $0)"
 CMDLINE="$0 $@"
-SOURCES_LIST_FILE='/etc/grml/fai/apt/sources.list'
 ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
 # }}}
 
 ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
 # }}}
 
@@ -39,11 +39,13 @@ $PN - build process script for generating a (grml based) Linux Live-ISO
 Usage: $PN [options, see as follows]
 
    -a <architecture>       architecture; available values: i386 and amd64
 Usage: $PN [options, see as follows]
 
    -a <architecture>       architecture; available values: i386 and amd64
+   -A                      ensure clean build and pack artifacts
    -b                      build the ISO without updating the chroot via FAI
    -B                      build the ISO without touching the chroot (skips cleanup)
    -c <classe[s]>          classes to be used for building the ISO via FAI
    -C <configfile>         configuration file for grml-live
    -d <date>               use specified date instead of build time as date of release
    -b                      build the ISO without updating the chroot via FAI
    -B                      build the ISO without touching the chroot (skips cleanup)
    -c <classe[s]>          classes to be used for building the ISO via FAI
    -C <configfile>         configuration file for grml-live
    -d <date>               use specified date instead of build time as date of release
+   -D <configdir>          use specified configuration directory instead of /etc/grml/fai
    -F                      force execution without prompting
    -g <grml_name>          set the grml flavour name
    -h                      display short usage information and exit
    -F                      force execution without prompting
    -g <grml_name>          set the grml flavour name
    -h                      display short usage information and exit
@@ -51,24 +53,24 @@ Usage: $PN [options, see as follows]
    -I <src_directory>      directory which provides files that should become
                            part of the chroot/ISO
    -n                      skip generation of ISO
    -I <src_directory>      directory which provides files that should become
                            part of the chroot/ISO
    -n                      skip generation of ISO
+   -N                      bootstrap (build chroot) only, do not create files for ISO
    -o <output_directory>   main output directory of the build process
    -q                      skip mksquashfs
    -r <release_name>       release name
    -s <suite>              Debian suite; values: etch, lenny, squeeze, sid
    -t <template_directory> place of the templates
    -u                      update existing chroot instead of rebuilding it from scratch
    -o <output_directory>   main output directory of the build process
    -q                      skip mksquashfs
    -r <release_name>       release name
    -s <suite>              Debian suite; values: etch, lenny, squeeze, sid
    -t <template_directory> place of the templates
    -u                      update existing chroot instead of rebuilding it from scratch
+   -U <username>           arrange output to be owned by specified username
    -v <version_number>     specify version number of the release
    -V                      increase verbosity in the build process
    -v <version_number>     specify version number of the release
    -V                      increase verbosity in the build process
-   -z                      use ZLIB instead of LZMA compression (depends on
-                           squashfs-tools version)
+   -z                      use ZLIB instead of LZMA/XZ compression
 
 Usage examples:
 
     $PN
 
 Usage examples:
 
     $PN
-    $PN -c GRMLBASE,GRML_MEDIUM,I386 -o /dev/shm/grml
-    $PN -c GRMLBASE,GRML_SMALL,REMOVE_DOCS,I386 -g grml-small -v 1.0
-    $PN -c GRMLBASE,GRML_FULL,I386 -i grml_0.0-1.iso -v 0.0-1
-    $PN -c GRMLBASE,GRML_FULL,I386 -s sid -V -r 'grml-live rocks'
+    $PN -c GRMLBASE,GRML_FULL,AMD64 -o /dev/shm/grml
+    $PN -c GRMLBASE,GRML_FULL,AMD64 -i grml_0.0-1.iso -v 0.0-1
+    $PN -c GRMLBASE,GRML_FULL,AMD64 -s sid -V -r 'grml-live rocks'
 
 More details: man grml-live + /usr/share/doc/grml-live/grml-live.html
               http://grml.org/grml-live/
 
 More details: man grml-live + /usr/share/doc/grml-live/grml-live.html
               http://grml.org/grml-live/
@@ -114,8 +116,15 @@ FORCE=''
 UPDATE=''
 BUILD_ONLY=''
 BUILD_DIRTY=''
 UPDATE=''
 BUILD_ONLY=''
 BUILD_DIRTY=''
+BOOTSTRAP_ONLY=''
 HOSTNAME=''
 
 HOSTNAME=''
 
+# don't use colors/escape sequences
+if [ -r /lib/lsb/init-functions ] ; then
+  . /lib/lsb/init-functions
+  ! log_use_fancy_output && NOCOLORS=true
+fi
+
 if [ -r /etc/grml/lsb-functions ] ; then
    . /etc/grml/lsb-functions
 else
 if [ -r /etc/grml/lsb-functions ] ; then
    . /etc/grml/lsb-functions
 else
@@ -132,25 +141,55 @@ LIVE_CONF=/etc/grml/grml-live.conf
 . $LIVE_CONF
 # }}}
 
 . $LIVE_CONF
 # }}}
 
+# umount all directories {{{
+umount_all() {
+   # make sure we don't leave any mounts - FAI doesn't remove them always
+   umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
+   umount $CHROOT_OUTPUT/sys  2>/dev/null || /bin/true
+   umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
+   umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
+
+   # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry
+   if [ -x /usr/lib/fai/mkramdisk ] ; then
+     /usr/lib/fai/mkramdisk -u "$(realpath ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true
+   fi
+
+   umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true
+   [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
+}
+# }}}
+
 # clean exit {{{
 bailout() {
   rm -f /var/run/fai/fai_softupdate_is_running \
         /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
   [ -n "$SQUASHFS_STDERR" ]  && rm -rf "$SQUASHFS_STDERR"
 # clean exit {{{
 bailout() {
   rm -f /var/run/fai/fai_softupdate_is_running \
         /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
   [ -n "$SQUASHFS_STDERR" ]  && rm -rf "$SQUASHFS_STDERR"
-  [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
+  umount_all
   [ -n "$1" ] && EXIT="$1" || EXIT="1"
   [ -n "$2" ] && eerror "$2">&2
   [ -n "$1" ] && EXIT="$1" || EXIT="1"
   [ -n "$2" ] && eerror "$2">&2
+  if [ -n "$PACK_ARTIFACTS" ]; then
+    log "Cleaning up"
+    einfo "Cleaning up"
+    [ -n "${BUILD_OUTPUT}"  -a -d "${BUILD_OUTPUT}"  ] && rm -r "${BUILD_OUTPUT}"
+    [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
+    eend 0
+  fi
+  if [ -n "$CHOWN_USER" ]; then
+    log "Setting ownership"
+    einfo "Setting ownership"
+    [ -n "${OUTPUT}"         -a -d "${OUTPUT}"         ] && chown -R "${CHOWN_USER}:" "${OUTPUT}"
+    [ -n "${BUILD_OUTPUT}"   -a -d "${BUILD_OUTPUT}"   ] && chown -R "${CHOWN_USER}:" "${BUILD_OUTPUT}"
+    [ -n "${CHROOT_OUTPUT}"  -a -d "${CHROOT_OUTPUT}"  ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}"
+    [ -n "${ISO_OUTPUT}"     -a -d "${ISO_OUTPUT}"     ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}"
+    [ -n "${LOG_OUTPUT}"     -a -d "${LOG_OUTPUT}"     ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}"
+    [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_ARCHIVE}"
+    eend 0
+  fi
   log "------------------------------------------------------------------------------"
   exit "$EXIT"
 }
 trap bailout 1 2 3 3 6 9 14 15
   log "------------------------------------------------------------------------------"
   exit "$EXIT"
 }
 trap bailout 1 2 3 3 6 9 14 15
-# }}}
-
-# log file stuff {{{
-[ -n "$LOGFILE" ] || LOGFILE=/var/log/grml-live.log
-touch $LOGFILE
-chown root:adm $LOGFILE
-chmod 664 $LOGFILE
+trap umount_all EXIT
 # }}}
 
 # some important functions {{{
 # }}}
 
 # some important functions {{{
@@ -200,32 +239,80 @@ extend_string_end() {
   done
   echo -ne "\n"
 }
   done
   echo -ne "\n"
 }
+
+# Copy addonfile $1 from either
+#   * the chroot (via $2, the system path),
+#   * or from TEMPLATE_DIRECTORY/compat (if exists),
+#   * or from the host system (again, using $2),
+# or warn about the missing file.
+#
+# This is because:
+#   * We assume that the chroot always has a "good" version of
+#     the file. Also it makes sources handling easier.
+#   * On unstable, we Recommend the Debian packages containing
+#     these files. The user can override them by putting his
+#     "better" version into the chroot.
+#   * On stable, the Debian packages are probably not available,
+#     or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
+#     our grml-live-compat package installs current file versions.
+copy_addon_file() {
+  DEST="${BUILD_OUTPUT}/boot/$3"
+  if [ ! -d "${DEST}/" ]; then
+    mkdir -p "${DEST}"
+  fi
+  if [ -e "$CHROOT_OUTPUT/$2/$1" ]; then
+    log   "Copying $1 from chroot"
+    cp "$CHROOT_OUTPUT/$2/$1" "${DEST}/"
+    return $?
+  fi
+  if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
+    log   "Copying $1 from grml-live-compat"
+    cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
+    return $?
+  fi
+  if [ -e "$2/$1" ]; then
+    log   "Copying $1 from system"
+    cp "$2/$1" "${DEST}/"
+    return $?
+  fi
+
+  msg="Missing addon file: \"$1\""
+  ewarn "$msg" ; eend 1
+  log "copy_addon_file: $msg"
+}
 # }}}
 
 # read local (non-packaged) configuration {{{
 LOCAL_CONFIG=/etc/grml/grml-live.local
 if [ -r "$LOCAL_CONFIG" ] ; then
 # }}}
 
 # read local (non-packaged) configuration {{{
 LOCAL_CONFIG=/etc/grml/grml-live.local
 if [ -r "$LOCAL_CONFIG" ] ; then
-   log "Sourcing $LOCAL_CONFIG"
    . $LOCAL_CONFIG
 else
    . $LOCAL_CONFIG
 else
-   log "No $LOCAL_CONFIG found, not sourcing it"
    LOCAL_CONFIG=''
 fi
    LOCAL_CONFIG=''
 fi
+
+if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
+  eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated."
+  ewarn  "Please set up ${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead."
+  bailout 1
+fi
 # }}}
 
 # command line parsing {{{
 # }}}
 
 # command line parsing {{{
-while getopts "a:C:c:d:g:i:I:o:r:s:t:v:bBFnquVz" opt; do
+while getopts "a:C:c:d:D:g:i:I:o:r:s:t:U:v:AbBFnNquVz" opt; do
   case "$opt" in
     a) ARCH="$OPTARG" ;;
   case "$opt" in
     a) ARCH="$OPTARG" ;;
+    A) PACK_ARTIFACTS=1 ;;
     b) BUILD_ONLY=1 ;;
     B) BUILD_DIRTY=1 ;;
     c) CLASSES="$OPTARG" ;;
     C) CONFIG="$OPTARG" ;;
     d) DATE="$OPTARG" ;;
     b) BUILD_ONLY=1 ;;
     B) BUILD_DIRTY=1 ;;
     c) CLASSES="$OPTARG" ;;
     C) CONFIG="$OPTARG" ;;
     d) DATE="$OPTARG" ;;
+    D) GRML_FAI_CONFIG="$OPTARG" ;;
     g) GRML_NAME="$OPTARG" ;;
     i) ISO_NAME="$OPTARG" ;;
     I) CHROOT_INSTALL="$OPTARG" ;;
     n) SKIP_MKISOFS=1 ;;
     g) GRML_NAME="$OPTARG" ;;
     i) ISO_NAME="$OPTARG" ;;
     I) CHROOT_INSTALL="$OPTARG" ;;
     n) SKIP_MKISOFS=1 ;;
+    N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;;
     o) OUTPUT="$OPTARG" ;;
     q) SKIP_MKSQUASHFS=1 ;;
     r) RELEASENAME="$OPTARG" ;;
     o) OUTPUT="$OPTARG" ;;
     q) SKIP_MKSQUASHFS=1 ;;
     r) RELEASENAME="$OPTARG" ;;
@@ -234,8 +321,9 @@ while getopts "a:C:c:d:g:i:I:o:r:s:t:v:bBFnquVz" opt; do
     v) VERSION="$OPTARG" ;;
     F) FORCE=1 ;;
     u) UPDATE=1 ;;
     v) VERSION="$OPTARG" ;;
     F) FORCE=1 ;;
     u) UPDATE=1 ;;
+    U) CHOWN_USER="$OPTARG" ;;
     V) VERBOSE="-v" ;;
     V) VERBOSE="-v" ;;
-    z) SQUASHFS_ZLIB="-nolzma" ;;
+    z) SQUASHFS_ZLIB=1 ;;
     ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
   esac
 done
     ?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
   esac
 done
@@ -243,31 +331,33 @@ shift $(($OPTIND - 1))  # set ARGV to the first not parsed commandline parameter
 # }}}
 
 # assume sane defaults (if not set already) {{{
 # }}}
 
 # assume sane defaults (if not set already) {{{
-[ -n "$ARCH" ]             || ARCH="$(dpkg --print-architecture)"
-[ -n "$BOOT_METHOD" ]      || BOOT_METHOD='isolinux'
-[ -n "$CLASSES" ]          || CLASSES="GRMLBASE,GRML_MEDIUM,I386"
-[ -n "$DATE" ]             || DATE="$(date +%Y-%m-%d)"
-[ -n "$DISTRI_INFO" ]      || DISTRI_INFO='Grml - Live Linux for system administrators   '
-[ -n "$DISTRI_NAME" ]      || DISTRI_NAME="grml"
-[ -n "$DISTRI_SPLASH" ]    || DISTRI_SPLASH='grml.png'
-[ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
-[ -n "$GRML_FAI_CONFIG" ]  || GRML_FAI_CONFIG='/etc/grml/fai'
-[ -n "$GRML_NAME" ]        || GRML_NAME='grml'
-[ -n "$HOSTNAME" ]         || HOSTNAME='grml'
-[ -n "$NFSROOT_CONF" ]     || NFSROOT_CONF='/etc/grml/fai/make-fai-nfsroot.conf'
-[ -n "$RELEASENAME" ]      || RELEASENAME='grml-live rocks'
-[ -n "$SQUASHFS_EXCLUDES_FILE " ] || SQUASHFS_EXCLUDES_FILE='/etc/grml/fai/squashfs-excludes'
-[ -n "$SUITE" ]            || SUITE='lenny'
-[ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
-[ -n "$USERNAME" ]         || USERNAME='grml'
-[ -n "$VERSION" ]          || VERSION='0.0.1'
-[ -n "$WINDOWS_BINARIES" ] || WINDOWS_BINARIES='http://the.earth.li/~sgtatham/putty/latest/x86/'
+[ -n "$ARCH" ]                    || ARCH="$(dpkg --print-architecture)"
+[ -n "$BOOT_METHOD" ]             || BOOT_METHOD='isolinux'
+[ -n "$CLASSES" ]                 || CLASSES="GRMLBASE,GRML_MEDIUM,$(echo ${ARCH} | tr 'a-z' 'A-Z')"
+[ -n "$DATE" ]                    || DATE="$(date +%Y-%m-%d)"
+[ -n "$DISTRI_INFO" ]             || DISTRI_INFO='Grml - Live Linux for system administrators   '
+[ -n "$DISTRI_NAME" ]             || DISTRI_NAME="grml"
+[ -n "$DISTRI_SPLASH" ]           || DISTRI_SPLASH='grml.png'
+[ -n "$FORCE_ISO_REBUILD" ]       || FORCE_ISO_REBUILD="false"
+[ -n "$GRML_FAI_CONFIG" ]         || GRML_FAI_CONFIG='/etc/grml/fai'
+[ -n "$GRML_NAME" ]               || GRML_NAME='grml'
+[ -n "$HOSTNAME" ]                || HOSTNAME='grml'
+[ -n "$HYBRID_METHOD" ]           || HYBRID_METHOD='manifold'
+[ -n "$NFSROOT_CONF" ]            || NFSROOT_CONF="${GRML_FAI_CONFIG}/make-fai-nfsroot.conf"
+[ -n "$RELEASENAME" ]             || RELEASENAME='grml-live rocks'
+[ -n "$SQUASHFS_EXCLUDES_FILE" ]  || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
+[ -n "$SUITE" ]                   || SUITE='squeeze'
+[ -n "$TEMPLATE_DIRECTORY" ]      || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
+[ -n "$USERNAME" ]                || USERNAME='grml'
+[ -n "$VERSION" ]                 || VERSION='0.0.1'
 
 # output specific stuff, depends on $OUTPUT (iff not set):
 [ -n "$OUTPUT" ]           || OUTPUT='/grml/grml-live'
 [ -n "$BUILD_OUTPUT" ]     || BUILD_OUTPUT="$OUTPUT/grml_cd"
 [ -n "$CHROOT_OUTPUT" ]    || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
 
 # output specific stuff, depends on $OUTPUT (iff not set):
 [ -n "$OUTPUT" ]           || OUTPUT='/grml/grml-live'
 [ -n "$BUILD_OUTPUT" ]     || BUILD_OUTPUT="$OUTPUT/grml_cd"
 [ -n "$CHROOT_OUTPUT" ]    || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
+[ -n "$CHROOT_ARCHIVE" ]   || CHROOT_ARCHIVE="$OUTPUT/$(basename $CHROOT_OUTPUT).tgz"
 [ -n "$ISO_OUTPUT" ]       || ISO_OUTPUT="$OUTPUT/grml_isos"
 [ -n "$ISO_OUTPUT" ]       || ISO_OUTPUT="$OUTPUT/grml_isos"
+[ -n "$LOG_OUTPUT" ]       || LOG_OUTPUT="$OUTPUT/grml_logs"
 # }}}
 
 # some misc checks before executing FAI {{{
 # }}}
 
 # some misc checks before executing FAI {{{
@@ -303,6 +393,7 @@ if [ -z "$FORCE" ] ; then
    echo "  FAI classes:       $CLASSES"
    [ -r "$LOCAL_CONFIG" ]        && echo "  Local config:      /etc/grml/grml-live.local"
    [ -n "$CONFIG" ]              && echo "  Configuration:     $CONFIG"
    echo "  FAI classes:       $CLASSES"
    [ -r "$LOCAL_CONFIG" ]        && echo "  Local config:      /etc/grml/grml-live.local"
    [ -n "$CONFIG" ]              && echo "  Configuration:     $CONFIG"
+   [ -n "$GRML_FAI_CONFIG" ]     && echo "  Config directory:  $GRML_FAI_CONFIG"
    echo "  main directory:    $OUTPUT"
    [ -n "$CHROOT_OUTPUT" ]       && echo "  Chroot target:     $CHROOT_OUTPUT"
    [ -n "$BUILD_OUTPUT" ]        && echo "  Build target:      $BUILD_OUTPUT"
    echo "  main directory:    $OUTPUT"
    [ -n "$CHROOT_OUTPUT" ]       && echo "  Chroot target:     $CHROOT_OUTPUT"
    [ -n "$BUILD_OUTPUT" ]        && echo "  Build target:      $BUILD_OUTPUT"
@@ -314,21 +405,28 @@ if [ -z "$FORCE" ] ; then
    [ -n "$SUITE" ]               && echo "  Debian suite:      $SUITE"
    [ -n "$ARCH" ]                && echo "  Architecture:      $ARCH"
    [ -n "$BOOT_METHOD" ]         && echo "  Boot method:       $BOOT_METHOD"
    [ -n "$SUITE" ]               && echo "  Debian suite:      $SUITE"
    [ -n "$ARCH" ]                && echo "  Architecture:      $ARCH"
    [ -n "$BOOT_METHOD" ]         && echo "  Boot method:       $BOOT_METHOD"
+   [ -n "$HYBRID_METHOD" ]       && echo "  Hybrid method:     $HYBRID_METHOD"
    [ -n "$TEMPLATE_DIRECTORY" ]  && echo "  Template files:    $TEMPLATE_DIRECTORY"
    [ -n "$CHROOT_INSTALL" ]      && echo "  Install files from directory to chroot:  $CHROOT_INSTALL"
    [ -n "$BOOTID" ]              && echo "  Boot identifier:   $BOOTID"
    [ -n "$NO_BOOTID" ]           && echo "  Skipping bootid feature."
    [ -n "$TEMPLATE_DIRECTORY" ]  && echo "  Template files:    $TEMPLATE_DIRECTORY"
    [ -n "$CHROOT_INSTALL" ]      && echo "  Install files from directory to chroot:  $CHROOT_INSTALL"
    [ -n "$BOOTID" ]              && echo "  Boot identifier:   $BOOTID"
    [ -n "$NO_BOOTID" ]           && echo "  Skipping bootid feature."
+   [ -n "$CHOWN_USER" ]          && echo "  Output owner:      $CHOWN_USER"
    [ -n "$DEFAULT_BOOTOPTIONS" ] && echo "  Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
    [ -n "$FAI_ARGS" ]            && echo "  Additional arguments for FAI: $FAI_ARGS"
    [ -n "$LOGFILE" ]             && echo "  Logging to file:   $LOGFILE"
    [ -n "$DEFAULT_BOOTOPTIONS" ] && echo "  Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
    [ -n "$FAI_ARGS" ]            && echo "  Additional arguments for FAI: $FAI_ARGS"
    [ -n "$LOGFILE" ]             && echo "  Logging to file:   $LOGFILE"
-   [ -n "$SQUASHFS_ZLIB" ]       && echo "  Using ZLIB (instead of LZMA) compression."
+   [ -n "$SQUASHFS_ZLIB" ]       && echo "  Using ZLIB (instead of LZMA/XZ) compression."
    [ -n "$SQUASHFS_OPTIONS" ]    && echo "  Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
    [ -n "$VERBOSE" ]             && echo "  Using VERBOSE mode."
    [ -n "$SQUASHFS_OPTIONS" ]    && echo "  Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
    [ -n "$VERBOSE" ]             && echo "  Using VERBOSE mode."
+   [ -n "$PACK_ARTIFACTS" ]      && echo "  Will prepare packed artifacts and ensure clean build."
    [ -n "$UPDATE" ]              && echo "  Executing UPDATE instead of fresh installation."
    [ -n "$UPDATE" ]              && echo "  Executing UPDATE instead of fresh installation."
-   [ -n "$SKIP_MKSQUASHFS" ]     && echo "  Skipping creation of SQUASHFS file."
-   [ -n "$SKIP_MKISOFS" ]        && echo "  Skipping creation of ISO file."
-   [ -n "$BUILD_ONLY" ]          && echo "  Executing BUILD_ONLY instead of fresh installation or UPDATE."
-   [ -n "$BUILD_DIRTY" ]         && echo "  Executing BUILD_DIRTY to leave chroot untouched."
+   if [ -n "$BOOTSTRAP_ONLY" ] ; then
+     echo "  Bootstrapping only and not building (files for) ISO."
+   else
+     [ -n "$SKIP_MKSQUASHFS" ]     && echo "  Skipping creation of SQUASHFS file."
+     [ -n "$SKIP_MKISOFS" ]        && echo "  Skipping creation of ISO file."
+     [ -n "$BUILD_ONLY" ]          && echo "  Executing BUILD_ONLY instead of fresh installation or UPDATE."
+     [ -n "$BUILD_DIRTY" ]         && echo "  Executing BUILD_DIRTY to leave chroot untouched."
+   fi
    echo
    echo -n "Is this ok for you? [y/N] "
    read a
    echo
    echo -n "Is this ok for you? [y/N] "
    read a
@@ -339,6 +437,25 @@ if [ -z "$FORCE" ] ; then
 fi
 # }}}
 
 fi
 # }}}
 
+# clean up before start {{{
+if [ -n "${PACK_ARTIFACTS}" ]; then
+  echo "Wiping old artifacts"
+  [ -n "${CHROOT_OUTPUT}"  -a -d "${CHROOT_OUTPUT}"  ] && rm -r "${CHROOT_OUTPUT}"
+  [ -n "${BUILD_OUTPUT}"   -a -d "${BUILD_OUTPUT}"   ] && rm -r "${BUILD_OUTPUT}"
+  [ -n "${ISO_OUTPUT}"     -a -d "${ISO_OUTPUT}"     ] && rm -r "${ISO_OUTPUT}"
+  [ -n "${LOG_OUTPUT}"     -a -d "${LOG_OUTPUT}"     ] && rm -r "${LOG_OUTPUT}"
+  [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}"
+fi
+# }}}
+
+# create log file {{{
+[ -n "$LOGFILE" ] || LOGFILE=${LOG_OUTPUT}/grml-live.log
+mkdir -p $(dirname "${LOGFILE}")
+touch $LOGFILE
+chown root:adm $LOGFILE
+chmod 664 $LOGFILE
+# }}}
+
 # clean/zero/remove logfiles {{{
 
 if [ -n "$PRESERVE_LOGFILE" ] ; then
 # clean/zero/remove logfiles {{{
 
 if [ -n "$PRESERVE_LOGFILE" ] ; then
@@ -375,6 +492,9 @@ fi
 start_seconds=$(cut -d . -f 1 /proc/uptime)
 log "------------------------------------------------------------------------------"
 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
 start_seconds=$(cut -d . -f 1 /proc/uptime)
 log "------------------------------------------------------------------------------"
 log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
+if [ -n "$LOCAL_CONFIG" ]; then
+  log "Using local config file: $LOCAL_CONFIG"
+fi
 log "Executed grml-live command line:"
 log "$CMDLINE"
 
 log "Executed grml-live command line:"
 log "$CMDLINE"
 
@@ -382,69 +502,17 @@ einfo "Logging actions to logfile $LOGFILE"
 # }}}
 
 # on-the-fly configuration {{{
 # }}}
 
 # on-the-fly configuration {{{
-if [ -n "$MIRROR_DIRECTORY" ] ; then
-   if ! [ -d "$MIRROR_DIRECTORY/debian" ] ; then
-      log    "Error: $MIRROR_DIRECTORY/debian does not seem to exist. Exiting. [$(date)]"
-      eerror "Error: $MIRROR_DIRECTORY/debian does not seem to exist. Exiting." ; eend 1
-      bailout 1
-   fi
-   cat > "$SOURCES_LIST_FILE" << EOF
-# NOTE: This file is *NOT* meant for manual customisation! This file is
-# modified by grml-live and any changes might be overridden.
-# You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
-# or FAI's fcopy command with /etc/grml/fai/config/files instead!
-EOF
-   echo "$MIRROR_SOURCES" >> "$SOURCES_LIST_FILE"
-   if [ -n "$GRML_LIVE_SOURCES" ] ; then
-      echo "$GRML_LIVE_SOURCES" >> "$SOURCES_LIST_FILE"
-   fi
-elif [ -n "$GRML_LIVE_SOURCES" ] ; then
-   cat > "$SOURCES_LIST_FILE" << EOF
-# NOTE: This file is *NOT* meant for manual customisation! This file is
-# modified by grml-live and any changes might be overridden.
-# You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
-# or FAI's fcopy command with /etc/grml/fai/config/files instead!
-EOF
-   echo "$GRML_LIVE_SOURCES" >> "$SOURCES_LIST_FILE"
-fi
-
 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
-   sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
+  sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
 fi
 
 # does this suck? YES!
 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
 case $SUITE in
 fi
 
 # does this suck? YES!
 # /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
 case $SUITE in
-   unstable) SUITE='sid' ;;
-   # make sure that we *NEVER* write any broken suite name to sources.list,
-   # otherwise we won't be able to adjust it one next (correct) execution
-   stable)   ;;
-   testing)  ;;
-   etch)     ;;
-   lenny)    ;;
-   squeeze)  ;;
-   sid)      ;;
-   *) echo "Sorry, $SUITE is not a valid Debian suite, exiting.">&2; bailout 1 ;;
+   unstable) SUITE='sid' ; CLASSES="DEBIAN_UNSTABLE,$CLASSES" ;;
+   *) CLASSES="DEBIAN_$(echo $SUITE | tr 'a-z' 'A-Z'),$CLASSES";;
 esac
 esac
-
-DIST=" etch\| stable\| lenny\| squeeze\| testing\| sid\| unstable"
-sed "s/\(^deb .\+\)\([ \t]*\)\($DIST\)\([ \t]*\)\(main \)/\1 \2$SUITE\4\5/" "$SOURCES_LIST_FILE" | sponge "$SOURCES_LIST_FILE"
-for file in "$LIVE_CONF" "$CONFIG" "$LOCAL_CONFIG" ; do
-    if [ -n "$file" ] ; then
-       sed "s/^SUITE=.*/SUITE=\"$SUITE\"/" $file | sponge $file
-       sed "s/\(^deb .\+\)\([ \t]*\)\($DIST\)\([ \t]*\)\(main \)/\1 \2$SUITE\4\5/" "$file" | sponge "$file"
-    fi
-done
-
-# notice: activate grml-live pool only if we are building against unstable:
-if grep -qe unstable -qe sid "$SOURCES_LIST_FILE" ; then
-   grep -q 'grml-live.*main' "$SOURCES_LIST_FILE" || \
-   grep grml-stable "$SOURCES_LIST_FILE" | \
-        sed 's/grml-stable/grml-live/' >> "$SOURCES_LIST_FILE"
-else
-   grep -q 'grml-live.*main' "$SOURCES_LIST_FILE" && \
-   sed 's/.*grml-live.*/# removed grml-live repository/' "$SOURCES_LIST_FILE" | sponge "$SOURCES_LIST_FILE"
-fi
+export SUITE # make sure it's available in FAI scripts
 
 for file in "$LIVE_CONF" "$CONFIG" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do
     if [ -n "$file" ] ; then
 
 for file in "$LIVE_CONF" "$CONFIG" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do
     if [ -n "$file" ] ; then
@@ -508,8 +576,8 @@ else
    fi
 
    if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
    fi
 
    if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
-      log   "Skiping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
-      ewarn "Skiping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
+      log   "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
+      ewarn "Skipping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
    else
       mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
 
    else
       mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
 
@@ -518,12 +586,22 @@ else
          mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
       fi
 
          mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
       fi
 
+      mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
+      mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
+
+      # tell dpkg to use "unsafe io" during the build
+      [ -d "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d" ] || mkdir -p "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d"
+      echo force-unsafe-io > "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
+
       log "Executed FAI command line:"
       log "Executed FAI command line:"
-      log "BUILD_ONLY=$BUILD_ONLY fai $VERBOSE -C $GRML_FAI_CONFIG -c$CLASSES -u $HOSTNAME $FAI_ACTION $CHROOT_OUTPUT $FAI_ARGS"
-      BUILD_ONLY="$BUILD_ONLY" fai $VERBOSE -C "$GRML_FAI_CONFIG" -c"$CLASSES" -u \
-      "$HOSTNAME" $FAI_ACTION "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
+      log "BUILD_ONLY=$BUILD_ONLY BOOTSTRAP_ONLY=$BOOTSTRAP_ONLY fai $VERBOSE -C $GRML_FAI_CONFIG -s file:///$GRML_FAI_CONFIG/config -c$CLASSES -u $HOSTNAME $FAI_ACTION $CHROOT_OUTPUT $FAI_ARGS"
+      BUILD_ONLY="$BUILD_ONLY" BOOTSTRAP_ONLY="$BOOTSTRAP_ONLY" fai $VERBOSE \
+                  -C "$GRML_FAI_CONFIG" -s "file:///$GRML_FAI_CONFIG/config" -c"$CLASSES" \
+                  -u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
       RC="$PIPESTATUS" # notice: bash-only
 
       RC="$PIPESTATUS" # notice: bash-only
 
+      rm -f "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
+
       FORCE_ISO_REBUILD=true
 
       if [ "$RC" != 0 ] ; then
       FORCE_ISO_REBUILD=true
 
       if [ "$RC" != 0 ] ; then
@@ -531,28 +609,36 @@ else
          eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
          bailout 1
       else
          eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
          bailout 1
       else
-         log "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
+         einfo "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
+         log   "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]"
          echo "$GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]" > $CHROOT_OUTPUT/etc/grml_version
          chmod 644 $CHROOT_OUTPUT/etc/grml_version
          einfo "Rebuilding initramfs"
          echo "$GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]" > $CHROOT_OUTPUT/etc/grml_version
          chmod 644 $CHROOT_OUTPUT/etc/grml_version
          einfo "Rebuilding initramfs"
-         # make sure new /etc/grml_version reaches the initramfs:
+         # make sure new /etc/grml_version reaches initramfs, iterate over all
+         # present kernel versions (note: we can't really handle more than one
+         # kernel version anyway right now)
          # chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :(
          # chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :(
-         chroot $CHROOT_OUTPUT update-initramfs -u -k all
+         for initrd in "$(basename $CHROOT_OUTPUT/boot/vmlinuz-*)" ; do
+           if ! chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -c ; then
+             einfo "Creating fresh initrd did not work, trying update instead:"
+             log   "Creating fresh initrd did not work, trying update instead:"
+             chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -u
+           fi
+         done
          eend $?
       fi
 
          eend $?
       fi
 
-      # Remove all FAI logs from chroot if class RELEASE is used:
-      if [ -f "$CHROOT_OUTPUT"/etc/grml_fai_release ] ; then
-         rm -rf "$CHROOT_OUTPUT"/var/log/fai/*
-      fi
+      # move fai logs into grml_logs directory
+      mkdir -p "$LOG_OUTPUT"/fai/
+      cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
+      chown root:adm "$LOG_OUTPUT"/fai/*
+      chmod 664 "$LOG_OUTPUT"/fai/*
+      rm -rf "$CHROOT_OUTPUT"/var/log/fai
 
 
-      # make sure we don't leave any mounts - FAI doesn't remove them always
-      umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true
-      umount $CHROOT_OUTPUT/sys  2>/dev/null || /bin/true
-      umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
-      umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
+      # Remove all FAI logs from chroot if class RELEASE is used:
+      rm -f "$CHROOT_OUTPUT"/var/log/install_packages.list
 
 
-      [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
+      umount_all
 
       # notice: 'fai dirinstall' does not seem to exit appropriate, so:
       ERROR=''
 
       # notice: 'fai dirinstall' does not seem to exit appropriate, so:
       ERROR=''
@@ -567,7 +653,7 @@ else
       fi
 
       if [ -r "$CHECKLOG/shell.log" ] ; then
       fi
 
       if [ -r "$CHECKLOG/shell.log" ] ; then
-         grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=2
+         grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=6
       fi
 
       if [ -n "$ERROR" ] ; then
       fi
 
       if [ -n "$ERROR" ] ; then
@@ -611,310 +697,279 @@ fi
 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
 
 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
 
-# i386:
+# prepare ISO
 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
-   if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
-      log   "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
-      ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
-   else
-      # booting stuff:
-      [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
-      [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
-
-      if [ -z "$NO_ADDONS" ] ; then
-         [ -d "$BUILD_OUTPUT"/boot/addons   ] || mkdir -p "$BUILD_OUTPUT"/boot/addons
-         if [ -r "$TEMPLATE_DIRECTORY"/boot/addons/memtest ] ; then
-            log "Installing $TEMPLATE_DIRECTORY/boot/addons/memtest"
-            cp "$TEMPLATE_DIRECTORY"/boot/addons/memtest "$BUILD_OUTPUT"/boot/addons/memtest
-         elif [ -r /boot/memtest86+.bin ] ; then
-            log "Installing /boot/memtest86+.bin"
-            cp /boot/memtest86+.bin "$BUILD_OUTPUT"/boot/addons/memtest
-         else
-            ewarn "No memtest binary found (either install package grml-live-addons or memtest86+), skipping."
-            log "No memtest binary found (either install package grml-live-addons or memtest86+), skipping."
-            eend 0
-         fi
-      fi
-
-      # if we don't have an initrd we a) can't boot and b) there was an error
-      # during build, so check for the file:
-      INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
-      if [ -n "$INITRD" ] ; then
-         cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
-         find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
-      else
-         log    "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
-         eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
-         bailout 10
-      fi
-
-      KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
-      if [ -n "$KERNEL_IMAGE" ] ; then
-         cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/linux26
-      else
-         log    "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
-         eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
-         bailout 11
-      fi
-
-      [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
-      if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
-         log    "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
-         eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
-         bailout 8
-      fi
-
-      # *always* copy files to output directory so the variables
-      # get adjusted according to the build
-      cp ${TEMPLATE_DIRECTORY}/boot/isolinux/*  "$BUILD_OUTPUT"/boot/isolinux/
+  if [ -n "$BOOTSTRAP_ONLY" ] ; then
+     log   "Skipping stage 'boot' as building with bootstrap only."
+     ewarn "Skipping stage 'boot' as building with bootstrap only." ; eend 0
+  else
+    if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
+       log   "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
+       ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
+    else
+       # booting stuff:
+       [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
+       [ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
+
+       # if we don't have an initrd we a) can't boot and b) there was an error
+       # during build, so check for the file:
+       INITRD="$(ls $CHROOT_OUTPUT/boot/initrd* 2>/dev/null| grep -v '.bak$' | sort -r | head -1)"
+       if [ -n "$INITRD" ] ; then
+          cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
+          find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
+       else
+          log    "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
+          eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
+          bailout 10
+       fi
+
+       KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
+       if [ -n "$KERNEL_IMAGE" ] ; then
+          cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/linux26
+       else
+          log    "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
+          eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
+          bailout 11
+       fi
+
+       [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
+       if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
+          log    "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
+          eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
+          bailout 8
+       fi
+
+       # copy _required_ isolinux files
+       for file in ifcpu64.c32 isolinux.bin vesamenu.c32; do
+         copy_addon_file "${file}" /usr/lib/syslinux isolinux
+       done
+
+       # *always* copy files to output directory so the variables
+       # get adjusted according to the build.
+       cp ${TEMPLATE_DIRECTORY}/boot/isolinux/*  "$BUILD_OUTPUT"/boot/isolinux/
+
+       if [ -n "$NO_ADDONS" ] ; then
+          log   "Skipping installation of boot addons as requested via \$NO_ADDONS."
+          einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
+       else
+          if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
+            log   "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
+            ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
+          else
+            # copy addons from system packages or grml-live-compat
+            copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
+            copy_addon_file pci.ids /usr/share/misc addons
+            copy_addon_file memtest86+.bin /boot addons
+            for file in memdisk chain.c32 hdt.c32 menu.c32; do
+              copy_addon_file "${file}" /usr/lib/syslinux addons
+            done
+
+            # make memtest filename FAT16/8.3 compatible
+            mv "${BUILD_OUTPUT}/boot/addons/memtest86+.bin" \
+              "${BUILD_OUTPUT}/boot/addons/memtest"
+
+            # copy only files so we can handle bsd4grml on its own
+            for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
+              test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
+            done
+
+            if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
+               log   "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
+               einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
+            else
+               if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
+                 cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
+               else
+                 log   "Missing addon file: bsd4grml"
+                 ewarn "Missing addon file: bsd4grml" ; eend 0
+               fi
+            fi
 
 
-      if [ -n "$NO_ADDONS" ] ; then
-         log   "Skipping installation of boot addons as requested via \$NO_ADDONS."
-         einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
-      else
-         if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
-           log   "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
-           ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
+          fi # no "$TEMPLATE_DIRECTORY"/boot/addons
+       fi # NO_ADDONS
+
+       if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
+         mkdir -p "${BUILD_OUTPUT}/boot/grub"
+       fi
+       cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
+
+       if [ -e ${TEMPLATE_DIRECTORY}/compat/grub/linux.mod ]; then
+         cp "${TEMPLATE_DIRECTORY}"/compat/grub/* "${BUILD_OUTPUT}"/boot/grub/
+       else
+         if ! which "grub-mkimage" >/dev/null 2>&1 ; then
+           log   "grub-mkimage not found, skipping Grub step therefore." ; eend 0
+           ewarn "grub-mkimage not found, skipping Grub step therefore."
+           ewarn "Please install grub-pc-bin or grub-common >= 1.98+20100804-14." ; eend 0
+         elif ! grub-mkimage --help | grep -q -- --format ; then
+           log   "grub-mkimage does not support --format=i386-pc, skipping Grub step therefore." ; eend 0
+           ewarn "grub-mkimage does not support --format=i386-pc, skipping Grub step therefore."
+           ewarn "Please install grub-common >= 1.98+20100804-14 or grub-pc-bin." ; eend 0
          else
          else
-           # copy only files so we can handle bsd4grml on its own
-           for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
-             test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
-           done
-
-           if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
-              log   "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
-              einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
+           # copy system grub files if grml-live-compat is not installed
+           cp -a /usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/
+           cp -a /usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/
+           cp -a /usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/
+           cp -a /usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/
+           grub-mkimage -d /usr/lib/grub/*-pc -o \
+             "${BUILD_OUTPUT}/boot/grub/core.img" biosdisk iso9660 --format=i386-pc
+         fi
+       fi
+
+       if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
+          log    "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
+          eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
+          bailout 9
+       fi
+
+       [ -d "$BUILD_OUTPUT"/GRML ] || mkdir "$BUILD_OUTPUT"/GRML
+       cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/
+
+       # adjust boot splash information:
+       RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
+       RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
+       RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
+
+       if [ -r "$BUILD_OUTPUT"/GRML/grml-version ] ; then
+          sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
+          sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/grml-version
+       fi
+
+       # make sure the squashfs filename is set accordingly:
+       SQUASHFS_NAME="$GRML_NAME.squashfs"
+
+       if [ -n "$NO_BOOTID" ] ; then
+          log   'Skipping bootid feature as requested via $NO_BOOTID.'
+          einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
+       else
+          [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
+          [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
+          einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
+          log   "Generating /conf/bootid.txt with entry ${BOOTID}."
+          echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
+          eend $?
+       fi
+
+       # adjust all variables in the templates with the according distribution information
+       for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
+                   "${BUILD_OUTPUT}"/boot/grub/* ; do
+         if [ -r "${file}" ] ; then
+           sed -i "s/%ARCH%/$ARCH/g"                    "${file}"
+           sed -i "s/%DATE%/$DATE/g"                    "${file}"
+           sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g"      "${file}"
+           sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g"      "${file}"
+           sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g"  "${file}"
+           sed -i "s/%GRML_NAME%/$GRML_NAME/g"          "${file}"
+           sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g"  "${file}"
+           sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g"    "${file}"
+           sed -i "s/%SHORT_NAME%/$SHORT_NAME/g"        "${file}"
+           sed -i "s/%VERSION%/$VERSION/g"              "${file}"
+
+           [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s/ boot=live/ boot=live $DEFAULT_BOOTOPTIONS/"  "${file}"
+
+           if [ -n "$NO_BOOTID" ] ; then
+              sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
            else
            else
-              if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
-                cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
-              else
-                log   "bsd4grml addon not found, skipping therefore."
-                ewarn "bsd4grml addon not found, skipping therefore." ; eend 0
-              fi
+              sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
            fi
            fi
-
-         fi # no "$TEMPLATE_DIRECTORY"/boot/addons
-      fi # NO_ADDONS
-
-      if ! [ -d ${TEMPLATE_DIRECTORY}/boot/grub ] ; then
-         log   "grub templates do not exist, skipping therefore."
-         ewarn "grub templates do not exist, skipping therefore." ; eend 0
-      else
-         if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
-            cp -a ${TEMPLATE_DIRECTORY}/boot/grub  "$BUILD_OUTPUT"/boot/
          fi
          fi
-
-         # make sure we have recent template files available, otherwise updating
-         # the strings like $GRML_NAME and $VERSION might be out of date
-         cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
-      fi
-
-      if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
-         log    "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
-         eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
-         bailout 9
-      fi
-
-      [ -d "$BUILD_OUTPUT"/GRML ] || mkdir "$BUILD_OUTPUT"/GRML
-      cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/
-
-      # adjust boot splash information:
-      RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
-      RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
-      RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
-
-      if [ -r "$BUILD_OUTPUT"/GRML/grml-version ] ; then
-         sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
-         sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/grml-version
-      fi
-
-      # make sure the squashfs filename is set accordingly:
-      SQUASHFS_NAME="$GRML_NAME.squashfs"
-
-      if [ -n "$NO_BOOTID" ] ; then
-         log   'Skipping bootid feature as requested via $NO_BOOTID.'
-         einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
-      else
-         [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
-         [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
-         einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
-         log   "Generating /conf/bootid.txt with entry ${BOOTID}."
-         echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
-         eend $?
-      fi
-
-      # adjust all variables in the templates with the according distribution information
-      for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
-                  "${BUILD_OUTPUT}"/boot/grub/* ; do
-        if [ -r "${file}" ] ; then
-          sed -i "s/%ARCH%/$ARCH/g"                    "${file}"
-          sed -i "s/%DATE%/$DATE/g"                    "${file}"
-          sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g"      "${file}"
-          sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g"      "${file}"
-          sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g"  "${file}"
-          sed -i "s/%GRML_NAME%/$GRML_NAME/g"          "${file}"
-          sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/g"  "${file}"
-          sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/g"    "${file}"
-          sed -i "s/%SHORT_NAME%/$SHORT_NAME/g"        "${file}"
-          sed -i "s/%VERSION%/$VERSION/g"              "${file}"
-
-          [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s/ boot=live/ boot=live $DEFAULT_BOOTOPTIONS/"  "${file}"
-
-          if [ -n "$NO_BOOTID" ] ; then
-             sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
-          else
-             sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
+       done
+
+       # adjust bootsplash accordingly but make sure the string has the according lenght
+       SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
+       SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
+       for file in f4 f5 ; do
+          if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
+             sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
+             sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
           fi
           fi
-        fi
-      done
-
-      # adjust bootsplash accordingly but make sure the string has the according lenght
-      SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
-      SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
-      for file in f4 f5 ; do
-         if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
-            sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
-            sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
-         fi
-      done
-
-      # generate addon list
-      rm "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
-      for name in $(ls "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg) ; do
-        include_name=$(basename "$name")
-        echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
-      done
-
-      if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
-         log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-         echo "include grmlmain.cfg"    >  "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-         echo "include default.cfg"     >  "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-         echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-         echo "include grml.cfg"        >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-
-         for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
-           echo "include $(basename $f)"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-         done
-
-         echo "include options.cfg"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-         if [ ! -n "$NO_ADDONS" ] ; then
-           echo "include addons.cfg"    >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-         fi
-         echo "include isoprompt.cfg"   >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-         echo "include hd.cfg"          >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-         echo "include hidden.cfg"      >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
-      else # assume we are building a custom distribution:
-         log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
-         einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
-         if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
-           log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
-           eindent
-           einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
-           eoutdent
-           eend $?
-        else
-           log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-           echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-           [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-         fi
-      fi
-
-      # use old style console based isolinux method only if requested:
-      if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
-         log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
-         einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
-         if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
-           einfo "include for console.cfg already foud, nothing to do."
-           eend 0
-         else
-           log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-           einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-           echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-           eend $?
-         fi
-      else
-         log 'Using graphical boot menu.'
-         if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
-           log "include for vesamenu.cfg already foud, nothing to do."
-         else
-           log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-           echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
-         fi
-      fi
-
-      # jump back to grub from bsd4grml (/boot/grub/stage2):
-      GRUB_LEGACY=stage2
-
-      if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
-         if [ -e "$BUILD_OUTPUT"/boot/grub/core.img ]; then
-            GRUB_VERSION=2
-         else
-            GRUB_VERSION=1
-         fi
-
-         for file in "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 \
-                     "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.cfg \
-                     "$BUILD_OUTPUT"/boot/isolinux/*.cfg \
-                     "$BUILD_OUTPUT"/boot/grub/grub.cfg \
-                     "$BUILD_OUTPUT"/boot/grub/menu.lst ; do
-             if [ -e "$file" ] ; then
-               sed -i -e "s!%GRUB_VERSION%!$GRUB_VERSION!g" \
-                      -e "s!%GRUB_LEGACY%!$GRUB_LEGACY!g" "$file"
-             fi
-         done
-
-         sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
-      fi
-
-      if [ -e "$BUILD_OUTPUT"/boot/grub/$GRUB_LEGACY ]; then
-         sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/menu.lst
-         sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/grub.cfg
-      elif [ -e "$BUILD_OUTPUT"/boot/grub/menu.lst -a -e "$BUILD_OUTPUT"/boot/grub/grub.cfg ] ; then
-         sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/menu.lst
-         sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/grub.cfg
-      fi
-
-      DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
-      if ! [ -r "$DPKG_LIST" ] ; then
-         ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
-      else
-         einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
-         cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
-         eend $?
-      fi
-
-      # autostart for Windows:
-      if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
-         cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
-      fi
-
-      # windows-binaries:
-      if [ -n "$NO_WINDOWS_BINARIES" ] ; then
-         log   "Skipping download of windows binaries as requested via \$NO_WINDOWS_BINARIES."
-         einfo "Skipping download of windows binaries as requested via \$NO_WINDOWS_BINARIES."
-         eend 0
-      else
-         if [ -f "$BUILD_OUTPUT"/windows/putty.exe ] ; then
-            log   "Skipping stage 'WINDOWS_BINARIES' as $BUILD_OUTPUT/windows exists already."
-            ewarn "Skipping stage 'WINDOWS_BINARIES' as $BUILD_OUTPUT/windows exists already." ; eend 0
+       done
+
+       # generate addon list
+       rm -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+       for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
+         include_name=$(basename "$name")
+         echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+       done
+
+       if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
+          log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+          echo "include grmlmain.cfg"    >  "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+          echo "include default.cfg"     >  "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+          echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+          echo "include grml.cfg"        >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+
+          for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
+            echo "include $(basename $f)"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+          done
+
+          echo "include options.cfg"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+          if [ ! -n "$NO_ADDONS" ] ; then
+            echo "include addons.cfg"    >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+          fi
+          echo "include isoprompt.cfg"   >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+          echo "include hd.cfg"          >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+          echo "include hidden.cfg"      >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+       else # assume we are building a custom distribution:
+          log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
+          einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
+          if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
+            log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
+            eindent
+            einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
+            eoutdent
+            eend $?
          else
          else
-            if ! [ -d "$BUILD_OUTPUT"/windows ] ; then
-               mkdir "$BUILD_OUTPUT"/windows
-               ( cd "$BUILD_OUTPUT"/windows
-                 for file in pageant plink pscp psftp putty puttygen ; do
-                    wget -O ${file}.exe ${WINDOWS_BINARIES}/${file}.exe
-                    md5sum ${file}.exe > ${file}.exe.md5
-                 done )
-            fi
-
-            log "Finished execution of stage 'WINDOWS_BINARIES' [$(date)]"
-            einfo "Finished execution of stage 'WINDOWS_BINARIES'" ; eend 0
-         fi
-      fi
-
-   FORCE_ISO_REBUILD=true
-   einfo "Finished execution of stage 'boot'" ; eend 0
-   fi
+            log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+            echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+            [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+          fi
+       fi
+
+       # use old style console based isolinux method only if requested:
+       if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
+          log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
+          einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
+          if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
+            einfo "include for console.cfg already found, nothing to do."
+            eend 0
+          else
+            log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+            einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+            echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+            eend $?
+          fi
+       else
+          log 'Using graphical boot menu.'
+          if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
+            log "include for vesamenu.cfg already found, nothing to do."
+          else
+            log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+            echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
+          fi
+       fi
+
+       if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
+          sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
+       fi
+
+       DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
+       if ! [ -r "$DPKG_LIST" ] ; then
+          ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
+       else
+          einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
+          cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
+          eend $?
+       fi
+
+       # autostart for Windows:
+       if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
+          cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
+       fi
+
+    FORCE_ISO_REBUILD=true
+    einfo "Finished execution of stage 'boot'" ; eend 0
+    fi
+  fi # BOOTSTRAP_ONLY
 else
    log    'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
    eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
 else
    log    'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
    eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
@@ -940,91 +995,43 @@ if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD
    log   "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
    ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
    log   "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
    ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
-   log   "Skipping stage 'squashfs' as requested via option -q"
-   ewarn "Skipping stage 'squashfs' as requested via option -q" ; eend 0
+   log   "Skipping stage 'squashfs' as requested via option -q or -N"
+   ewarn "Skipping stage 'squashfs' as requested via option -q or -N" ; eend 0
 else
    [ -d "$BUILD_OUTPUT"/live ] || mkdir "$BUILD_OUTPUT"/live
    # make sure we don't leave (even an empty) base.tgz:
    [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
 
 else
    [ -d "$BUILD_OUTPUT"/live ] || mkdir "$BUILD_OUTPUT"/live
    # make sure we don't leave (even an empty) base.tgz:
    [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
 
-   # $SQUASHFS_BINARY is specified in the configuration:
-   if [ -n "$SQUASHFS_BINARY" ] ; then
-      if ! which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
-         log    "Error: specified mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
-         eerror "Error: specified mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
-         bailout
-      fi
-   else # no $SQUASHFS_BINARY configured, let's find the according binary:
-      # Note: this is ALL for backward compatibility and yes: it's serious PITA.
-      # We'll definitely drop this once people build >2.6.28-grml* only and
-      # the squashfs-tools vs. squashfs-lzma-tools + zlib vs. lzma situation
-      # is settling...
-
-      # assume the safe default if mksquashfs-lzma isn't present:
-      if ! which mksquashfs-lzma >/dev/null 2>&1 ; then
-         SQUASHFS_BINARY='mksquashfs'
-      else # mksquashfs-lzma is available since squashfs-lzma-tools 4.0:
-         # if the user wants to use zlib then don't use mksquashfs-lzma:
-         if echo "$SQUASHFS_OPTIONS" | grep -q -- "-nolzma" || [ -n "$SQUASHFS_ZLIB" ] ; then
-            SQUASHFS_BINARY='mksquashfs'
-         else # neither -nolzma nor -z and mksquashfs-lzma is available:
-            SQUASHFS_BINARY='mksquashfs-lzma'
-
-            # backwards compatibility: someone has squashfs-lzma-tools >=4 installed but
-            # 1) doesn't use -nolzma in $SQUASHFS_OPTIONS or the grml-live's -z option *and*
-            # 2) builds against kernel version <=2.6.28-grml[64]
-            if ls $CHROOT_OUTPUT/boot/vmlinuz* >/dev/null 2>&1 ; then
-               KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
-
-               case $KERNEL_IMAGE in
-                  *vmlinuz-2.6.28-grml*|*vmlinuz-2.6.26-grml*|*vmlinuz-2.6.23-grml*)
-                  log   "You seem to be building a system with squashfs file format 3 using squashfs-lzma-tools >=4."
-                  ewarn "You seem to be building a system with squashfs file format 3 using squashfs-lzma-tools >=4."
-                  ewarn "|-> Consider installing squashfs-lzma-tools 3.3-1 for support of file format version 3."
-                  ewarn "|-> Trying the mksquashfs binary instead of mksquashfs-lzma (though this might fail)."
-                  ewarn "\`-> Visit http://grml.org/grml-live/#current_state for further details if building fails."
-                  eend 0
-                  SQUASHFS_BINARY='mksquashfs'
-                  ;;
-               esac
-            fi
-
-            # if we still want to use mksquashfs-lzma then let's choose
-            # blocksize 256k as this gives best result with regards to time + comopression
-            [[ "$SQUASHFS_BINARY" == "mksquashfs-lzma" ]] && SQUASHFS_OPTIONS="-b 256k -lzma"
-         fi
-
-      fi
+   # if unconfigured default to squashfs-tools' mksquashfs binary
+   if [ -z "$SQUASHFS_BINARY" ] ; then
+      SQUASHFS_BINARY='mksquashfs'
    fi
 
    fi
 
-   # make sure mksquashfs can handle the according option:
-   if [ -n "$SQUASHFS_ZLIB" ] ; then
-      $SQUASHFS_BINARY --help 2>&1 | grep -q -- "$SQUASHFS_ZLIB" || SQUASHFS_ZLIB=''
+   if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
+      log    "Using mksquashfs binary ${SQUASHFS_BINARY}"
+      einfo  "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
+   else
+      log    "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
+      eerror "Error: mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
+      bailout
    fi
 
    fi
 
-   # make sure to drop the -nolzma option if it's not available:
-   if echo "$SQUASHFS_OPTIONS" | grep -q -- "-nolzma" ; then
-      if ! $SQUASHFS_BINARY --help 2>&1 | grep -q -- '-nolzma' ; then
-         log   "The $SQUASHFS_BINARY binary does NOT support the nolzma option, dropping it and using default mode."
-         ewarn "The $SQUASHFS_BINARY binary does NOT support the nolzma option, dropping it and using default mode."
-         SQUASHFS_OPTIONS="$(echo $SQUASHFS_OPTIONS | sed 's/-nolzma//g')"
-         eend 0
-      fi
-   fi
+   # use sane defaults if $SQUASHFS_OPTIONS isn't set
+   if [ -z "$SQUASHFS_OPTIONS" ] ; then
+     # use blocksize 256k as this gives best result with regards to time + compression
+     SQUASHFS_OPTIONS="-b 256k"
 
 
-   # make sure to drop the -lzma option if it's not available:
-   if echo "$SQUASHFS_OPTIONS" | grep -q -- "-lzma" ; then
-      if ! $SQUASHFS_BINARY --help 2>&1 | grep -q -- '-lzma' ; then
-         log   "The $SQUASHFS_BINARY binary does NOT support the lzma option, dropping it and using default mode."
-         ewarn "The $SQUASHFS_BINARY binary does NOT support the lzma option, dropping it and using default mode."
-         SQUASHFS_OPTIONS="$(echo $SQUASHFS_OPTIONS | sed 's/-lzma//g')"
-         eend 0
-      fi
+     # set lzma/xz compression by default, unless -z option has been specified on command line
+     if [ -z "$SQUASHFS_ZLIB" ] ; then
+        SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp xz"
+     else
+        SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -comp gzip"
+     fi
    fi
 
    # support exclusion of files via exclude-file:
    if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
    fi
 
    # support exclusion of files via exclude-file:
    if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
-      SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE"
+      SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE -wildcards"
    fi
 
    # get rid of unnecessary files when building grml-small for final release:
    fi
 
    # get rid of unnecessary files when building grml-small for final release:
@@ -1032,35 +1039,27 @@ else
       SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
    fi
 
       SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
    fi
 
-   # check whether we have the according binary available:
-   if ! which $SQUASHFS_BINARY >/dev/null 2>&1 ; then
-      log    "Error: mksquashfs binary (${SQUASHFS_BINARY}) could not be found. Exiting."
-      eerror "Error: mksquashfs binary (${SQUASHFS_BINARY}) could not be found. Exiting."
-      eerror "|-> Make sure to install either squashfs-tools and/or squashfs-lzma-tools."
-      eerror "\`-> Visit http://grml.org/grml-live/#current_state for further details."
-      eend 1
-      bailout
-   fi
-
+   # log stuff
    SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
 
    SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
 
+   # informational stuff
    [ -n "$SQUASHFS_OPTIONS" ]  && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
    [ -n "$SQUASHFS_OPTIONS" ]  && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
-   [ -n "$SQUASHFS_ZLIB" ]     && SQUASHFS_INFO_MSG="$SQUASHFS_INFO_MSG $SQUASHFS_ZLIB"
    [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
    einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
 
    [ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
    einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
 
-   log "$SQUASHFS_BINARY $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB"
+   log "$SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS"
 
 
-   if $SQUASHFS_BINARY $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
-      -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB 2>"${SQUASHFS_STDERR}" ; then
+   if $SQUASHFS_BINARY $CHROOT_OUTPUT/ $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
+      -noappend $SQUASHFS_OPTIONS 2>"${SQUASHFS_STDERR}" ; then
       echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
       log "Finished execution of stage 'squashfs' [$(date)]"
       einfo "Finished execution of stage 'squashfs'" ; eend 0
    else
       log    "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
       log    "$(cat $SQUASHFS_STDERR)"
       echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
       log "Finished execution of stage 'squashfs' [$(date)]"
       einfo "Finished execution of stage 'squashfs'" ; eend 0
    else
       log    "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
       log    "$(cat $SQUASHFS_STDERR)"
-      eerror "Error: there was a critical error executing stage 'squashfs':" ; eend 1
+      eerror "Error: there was a critical error executing stage 'squashfs':"
       cat    "${SQUASHFS_STDERR}"
       cat    "${SQUASHFS_STDERR}"
+      eend 1
       bailout
    fi
 
       bailout
    fi
 
@@ -1068,8 +1067,10 @@ else
 fi
 
 # create md5sum file:
 fi
 
 # create md5sum file:
-( cd $BUILD_OUTPUT/GRML &&
-find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
+if [ -z "$BOOTSTRAP_ONLY" ] ; then
+  ( cd $BUILD_OUTPUT/GRML &&
+  find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
+fi
 # }}}
 
 # ISO_OUTPUT - mkisofs {{{
 # }}}
 
 # ISO_OUTPUT - mkisofs {{{
@@ -1077,17 +1078,26 @@ find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; >
 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
 
 if [ "$BOOT_METHOD" = "isolinux" ] ; then
 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
 
 if [ "$BOOT_METHOD" = "isolinux" ] ; then
-   BOOT_FILE="boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
-elif [ "$BOOT_METHOD" = "grub" ] ; then
-   BOOT_FILE="boot/grub/stage2"
+   BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
+elif [ "$BOOT_METHOD" = "grub2" ] ; then
+   BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
+fi
+
+# Just until http://bts.grml.org/grml/issue945 has been resolved.
+# HYBRID_METHOD defaults to manifold, so make sure the default works OOTB.
+if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
+  log   "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
+  ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
+  HYBRID_METHOD='grub2'
+  eend 0
 fi
 
 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ]  ; then
    log   "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
    ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
 elif [ -n "$SKIP_MKISOFS" ] ; then
 fi
 
 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ]  ; then
    log   "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
    ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
 elif [ -n "$SKIP_MKISOFS" ] ; then
-   log   "Skipping stage 'iso build' as requested via option -n"
-   ewarn "Skipping stage 'iso build' as requested via option -n" ; eend 0
+   log   "Skipping stage 'iso build' as requested via option -n or -N"
+   ewarn "Skipping stage 'iso build' as requested via option -n or -N" ; eend 0
 else
    mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
 
 else
    mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
 
@@ -1109,11 +1119,23 @@ else
 
    CURRENT_DIR=$(pwd)
    if cd "$BUILD_OUTPUT" ; then
 
    CURRENT_DIR=$(pwd)
    if cd "$BUILD_OUTPUT" ; then
-      log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J -no-emul-boot -boot-load-size 4 -boot-info-table -b $BOOT_FILE -o ${ISO_OUTPUT}/${ISO_NAME} ."
+      if [ "$BOOT_METHOD" = "grub2" ]; then
+         # make a 2048-byte bootsector for El Torito
+         dd if=/dev/zero of=boot/grub/toriboot.bin bs=512 count=4 2>/dev/null
+         # those are in 2048-byte sectors, so 1 16 matches 4 63 below
+         echo 1 16 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -B 11 | \
+            dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
+      fi
+      log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
       "$MKISOFS" -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
       "$MKISOFS" -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
-              -l -r -J -no-emul-boot -boot-load-size 4 -boot-info-table    \
-              -b $BOOT_FILE -no-pad \
+              -l -r -J $BOOT_ARGS -no-pad \
               -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
               -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
+      # both of these need core.img there, so it’s easier to write it here
+      if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
+         # must be <= 30720 bytes
+         dd if=boot/grub/core.img of="${ISO_OUTPUT}/${ISO_NAME}" \
+           conv=notrunc bs=512 seek=4 2>/dev/null
+      fi
 
       # pad the output ISO to multiples of 256 KiB for partition table support
       siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
 
       # pad the output ISO to multiples of 256 KiB for partition table support
       siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
@@ -1146,19 +1168,24 @@ else
          fi
       # by default use our manifold boot method:
       else
          fi
       # by default use our manifold boot method:
       else
+         # isoinfo is part of both mkisofs and genisoimage so we're good
+         bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \
+           sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN;1 *$/s//\1/p')
          if ! [ -r boot/grub/core.img ] ; then
            ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
          if ! [ -r boot/grub/core.img ] ; then
            ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
+         elif [ "${bootoff:-0}" -lt 1 ] ; then
+           ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
          else
            log "Creating hybrid ISO file with manifold method"
            einfo "Creating hybrid ISO file with manifold method"
          else
            log "Creating hybrid ISO file with manifold method"
            einfo "Creating hybrid ISO file with manifold method"
-           (
+           if [ "$HYBRID_METHOD" = "grub2" ] ; then
                # 512 bytes: MBR, partition table, load GRUB 2
                echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
                # 512 bytes: MBR, partition table, load GRUB 2
                echo 4 63 | mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 4:0x96 -g $cyls:16:32
-               # pad to a whole of 2048 bytes (one CD sector)
-               dd if=/dev/zero bs=512 count=3 2>/dev/null
-               # append GRUB 2 (must be <=30720 bytes)
-               cat boot/grub/core.img
-           ) | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
+           else
+              # read only one but 2048-byte sized (scale: << 2) sector
+              echo $bootoff $bootoff | \
+                 mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
+           fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
            eend $?
          fi
       fi
            eend $?
          fi
       fi
@@ -1177,7 +1204,7 @@ else
          ;;
       esac
 
          ;;
       esac
 
-      cd $CURRENT_DIR
+      cd "$CURRENT_DIR"
    fi
 
    if [ "$RC" = 0 ] ; then
    fi
 
    if [ "$RC" = 0 ] ; then
@@ -1191,6 +1218,16 @@ else
 fi
 # }}}
 
 fi
 # }}}
 
+# pack artifacts {{{
+if [ -n "$PACK_ARTIFACTS" ]; then
+  log "Packing artifcats"
+  einfo "Packing artifacts"
+  [ -f "${CHROOT_ARCHIVE}" ] && rm -r "${CHROOT_ARCHIVE}"
+  tar -c -a -f ${CHROOT_ARCHIVE} --preserve-permissions -C "$(dirname ${CHROOT_OUTPUT})" "$(basename ${CHROOT_OUTPUT})"
+  eend 0
+fi
+# }}}
+
 # log build information to database if grml-live-db is installed and enabled {{{
 dpkg_to_db() {
 if [ -d /usr/share/grml-live-db ] ; then
 # log build information to database if grml-live-db is installed and enabled {{{
 dpkg_to_db() {
 if [ -d /usr/share/grml-live-db ] ; then
@@ -1248,4 +1285,4 @@ bailout 0
 # }}}
 
 ## END OF FILE #################################################################
 # }}}
 
 ## END OF FILE #################################################################
-# vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=3
+# vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=2