Use ipxe.lkrn from ipxe package
[grml-live.git] / grml-live
index 39f49f9..44fcea6 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.9.34'
+GRML_LIVE_VERSION='0.15.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'
 # }}}
 
@@ -44,6 +44,7 @@ Usage: $PN [options, see as follows]
    -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
    -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,6 +52,7 @@ 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
    -o <output_directory>   main output directory of the build process
    -q                      skip mksquashfs
    -r <release_name>       release name
@@ -59,8 +61,7 @@ Usage: $PN [options, see as follows]
    -u                      update existing chroot instead of rebuilding it from scratch
    -v <version_number>     specify version number of the release
    -V                      increase verbosity in the build process
    -u                      update existing chroot instead of rebuilding it from scratch
    -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:
 
 
 Usage examples:
 
@@ -114,6 +115,7 @@ FORCE=''
 UPDATE=''
 BUILD_ONLY=''
 BUILD_DIRTY=''
 UPDATE=''
 BUILD_ONLY=''
 BUILD_DIRTY=''
+BOOTSTRAP_ONLY=''
 HOSTNAME=''
 
 if [ -r /etc/grml/lsb-functions ] ; then
 HOSTNAME=''
 
 if [ -r /etc/grml/lsb-functions ] ; then
@@ -132,18 +134,30 @@ 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
+   [ -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
   log "------------------------------------------------------------------------------"
   exit "$EXIT"
 }
 trap bailout 1 2 3 3 6 9 14 15
   [ -n "$1" ] && EXIT="$1" || EXIT="1"
   [ -n "$2" ] && eerror "$2">&2
   log "------------------------------------------------------------------------------"
   exit "$EXIT"
 }
 trap bailout 1 2 3 3 6 9 14 15
+trap umount_all EXIT
 # }}}
 
 # log file stuff {{{
 # }}}
 
 # log file stuff {{{
@@ -214,7 +228,7 @@ 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:v:bBFnNquVz" opt; do
   case "$opt" in
     a) ARCH="$OPTARG" ;;
     b) BUILD_ONLY=1 ;;
   case "$opt" in
     a) ARCH="$OPTARG" ;;
     b) BUILD_ONLY=1 ;;
@@ -222,10 +236,12 @@ while getopts "a:C:c:d:g:i:I:o:r:s:t:v:bBFnquVz" opt; do
     c) CLASSES="$OPTARG" ;;
     C) CONFIG="$OPTARG" ;;
     d) DATE="$OPTARG" ;;
     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" ;;
@@ -235,7 +251,7 @@ while getopts "a:C:c:d:g:i:I:o:r:s:t:v:bBFnquVz" opt; do
     F) FORCE=1 ;;
     u) UPDATE=1 ;;
     V) VERBOSE="-v" ;;
     F) FORCE=1 ;;
     u) UPDATE=1 ;;
     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,29 +259,32 @@ 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 "$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 "$HYBRID_METHOD" ]           || HYBRID_METHOD='manifold'
+[ -n "$NFSROOT_CONF" ]            || NFSROOT_CONF="${GRML_FAI_CONFIG}/make-fai-nfsroot.conf"
+[ -n "$RELEASENAME" ]             || RELEASENAME='grml-live rocks'
+[ -n "$SOURCES_LIST_OUTPUT" ]     || SOURCES_LIST_OUTPUT="${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list/GRML_LIVE_SOURCES_LIST"
+[ -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"
 [ -n "$BUILD_OUTPUT" ]     || BUILD_OUTPUT="$OUTPUT/grml_cd"
 [ -n "$CHROOT_OUTPUT" ]    || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
-[ -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 "$ISO_OUTPUT" ]       || ISO_OUTPUT="$OUTPUT/grml_isos"
 [ -n "$ISO_OUTPUT" ]       || ISO_OUTPUT="$OUTPUT/grml_isos"
-[ -n "$NFSROOT_CONF" ]     || NFSROOT_CONF='/etc/grml/fai/make-fai-nfsroot.conf'
-[ -n "$OUTPUT" ]           || OUTPUT='/grml/grml-live'
-[ -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/'
 # }}}
 
 # some misc checks before executing FAI {{{
 # }}}
 
 # some misc checks before executing FAI {{{
@@ -274,11 +293,6 @@ specify it on the command line using the -c option."
 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
 specify it on the command line using the -o option."
 
 [ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
 specify it on the command line using the -o option."
 
-# set subdirectories according to $OUTPUT:
-CHROOT_OUTPUT="$OUTPUT/grml_chroot"
-BUILD_OUTPUT="$OUTPUT/grml_cd"
-ISO_OUTPUT="$OUTPUT/grml_isos"
-
 # trim characters that are known to cause problems inside $GRML_NAME;
 # for example isolinux does not like '-' inside the directory name
 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
 # trim characters that are known to cause problems inside $GRML_NAME;
 # for example isolinux does not like '-' inside the directory name
 [ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
@@ -304,31 +318,40 @@ if [ -z "$FORCE" ] ; then
    echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
    echo
    echo "  FAI classes:       $CLASSES"
    echo "${PN} [${GRML_LIVE_VERSION}]: check your configuration (or use -F to force execution):"
    echo
    echo "  FAI classes:       $CLASSES"
-   [ -r "$LOCAL_CONFIG" ]       && echo "  local config:      /etc/grml/grml-live.local"
-   [ -n "$CONFIG" ]             && echo "  configuration:     $CONFIG"
+   [ -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"
    echo "  main directory:    $OUTPUT"
-   [ -n "$CHROOT_OUTPUT" ]      && echo "  chroot target:     $CHROOT_OUTPUT"
-   [ -n "$BUILD_OUTPUT" ]       && echo "  build target:      $BUILD_OUTPUT"
-   [ -n "$ISO_OUTPUT" ]         && echo "  ISO target:        $ISO_OUTPUT"
-   [ -n "$GRML_NAME" ]          && echo "  grml name:         $GRML_NAME"
-   [ -n "$RELEASENAME" ]        && echo "  release name:      $RELEASENAME"
-   [ -n "$DATE" ]               && echo "  build date:        $DATE"
-   [ -n "$VERSION" ]            && echo "  grml version:      $VERSION"
-   [ -n "$SUITE" ]              && echo "  Debian suite:      $SUITE"
-   [ -n "$ARCH" ]               && echo "  Architecture:      $ARCH"
-   [ -n "$BOOT_METHOD" ]        && echo "  Boot method:       $BOOT_METHOD"
-   [ -n "$TEMPLATE_DIRECTORY" ] && echo "  Template files:    $TEMPLATE_DIRECTORY"
-   [ -n "$CHROOT_INSTALL" ]     && echo "  Install files from directory to chroot:  $CHROOT_INSTALL"
-   [ -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_OPTIONS" ]   && echo "  Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
-   [ -n "$VERBOSE" ]            && echo "  Using VERBOSE mode."
-   [ -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."
+   [ -n "$CHROOT_OUTPUT" ]       && echo "  Chroot target:     $CHROOT_OUTPUT"
+   [ -n "$BUILD_OUTPUT" ]        && echo "  Build target:      $BUILD_OUTPUT"
+   [ -n "$ISO_OUTPUT" ]          && echo "  ISO target:        $ISO_OUTPUT"
+   [ -n "$GRML_NAME" ]           && echo "  Grml name:         $GRML_NAME"
+   [ -n "$RELEASENAME" ]         && echo "  Release name:      $RELEASENAME"
+   [ -n "$DATE" ]                && echo "  Build date:        $DATE"
+   [ -n "$VERSION" ]             && echo "  Grml version:      $VERSION"
+   [ -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 "$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/XZ) compression."
+   [ -n "$SQUASHFS_OPTIONS" ]    && echo "  Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
+   [ -n "$VERBOSE" ]             && echo "  Using VERBOSE mode."
+   [ -n "$UPDATE" ]              && echo "  Executing UPDATE instead of fresh installation."
+   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
@@ -382,34 +405,25 @@ 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 overriden.
-# You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
-# and using /etc/grml/fai/files/etc/apt 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
+mkdir -p "$(dirname $SOURCES_LIST_OUTPUT)" # might not be present in -D config space
+
+cat > "$SOURCES_LIST_OUTPUT" << EOF
 # NOTE: This file is *NOT* meant for manual customisation! This file is
 # NOTE: This file is *NOT* meant for manual customisation! This file is
-# modified by grml-live and any changes might be overriden.
-# You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
-# and using /etc/grml/fai/files/etc/apt instead!'
+# installed temporarily only by grml-live and will be overriden in the
+# installation and configuration process then.
 EOF
 EOF
-   echo "$GRML_LIVE_SOURCES" >> "$SOURCES_LIST_FILE"
+
+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
+  echo "$MIRROR_SOURCES" >> "$SOURCES_LIST_OUTPUT"
 fi
 
 if [ -n "$FAI_DEBOOTSTRAP" ] ; then
 fi
 
 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!
 fi
 
 # does this suck? YES!
@@ -423,27 +437,35 @@ case $SUITE in
    etch)     ;;
    lenny)    ;;
    squeeze)  ;;
    etch)     ;;
    lenny)    ;;
    squeeze)  ;;
+   wheezy)   ;;
    sid)      ;;
    *) echo "Sorry, $SUITE is not a valid Debian suite, exiting.">&2; bailout 1 ;;
 esac
    sid)      ;;
    *) echo "Sorry, $SUITE is not a valid Debian suite, exiting.">&2; bailout 1 ;;
 esac
+export SUITE # make sure it's available in FAI scripts
+
+if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then
+  DIST=" etch\| stable\| lenny\| squeeze\| wheezy\| testing\| sid\| unstable"
+  echo "# generated based on \$GRML_LIVE_SOURCES by grml-live
+$GRML_LIVE_SOURCES" | \
+    sed -e "s/\(^deb .\+\)\([ \t]*\)\($DIST\)\([ \t]*\)\(main \)/\1 \2$SUITE\4\5/;
+            s/\(^deb-src .\+\)\([ \t]*\)\($DIST\)\([ \t]*\)\(main \)/\1 \2$SUITE\4\5/" >> "$SOURCES_LIST_OUTPUT"
+else
+  cat >> "$SOURCES_LIST_OUTPUT" << EOF
+# generated by grml-live
+deb http://deb.grml.org/            grml-stable  main
+deb http://deb.grml.org/            grml-testing main
+deb http://cdn.debian.net/debian $SUITE  main contrib non-free
+EOF
+fi
 
 
-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"
+# notice: activate grml-live pool when building against unstable or testing:
+if grep -qwe unstable -qwe sid -qwe testing -qwe wheezy "$SOURCES_LIST_OUTPUT" ; then
+   grep -q 'grml-live.*main' "$SOURCES_LIST_OUTPUT" || \
+   grep grml-stable "$SOURCES_LIST_OUTPUT" | \
+        sed 's/grml-stable/grml-live/' >> "$SOURCES_LIST_OUTPUT"
 else
 else
-   grep -q 'grml-live.*main' "$SOURCES_LIST_FILE" && \
-   sed 's/.*grml-live.*/# removed grml-live repository/' "$SOURCES_LIST_FILE" | sponge "$SOURCES_LIST_FILE"
+   grep -q 'grml-live.*main' "$SOURCES_LIST_OUTPUT" && \
+   sed -i 's/.*grml-live.*main/# removed grml-live repository/' "$SOURCES_LIST_OUTPUT"
 fi
 
 for file in "$LIVE_CONF" "$CONFIG" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do
 fi
 
 for file in "$LIVE_CONF" "$CONFIG" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do
@@ -508,8 +530,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 +540,19 @@ else
          mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
       fi
 
          mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
       fi
 
+      # 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 +560,32 @@ 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
 
       # 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/*
          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/*
+         rm -f "$CHROOT_OUTPUT"/var/log/install_packages.list
       fi
 
       fi
 
-      # 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
-
-      [ -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 +600,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
@@ -593,7 +626,7 @@ CHECKLOG=/var/log/fai/$HOSTNAME/last
 # package validator
 if [ -r "$CHECKLOG/package_errors.log" ] && grep -q '[a-z]' "$CHECKLOG/package_errors.log" ; then
 
 # package validator
 if [ -r "$CHECKLOG/package_errors.log" ] && grep -q '[a-z]' "$CHECKLOG/package_errors.log" ; then
 
-   if [ -n "$EXIT_ON_MISSING_PACKAGES" ] ; then
+   if [ -n "$EXIT_ON_MISSING_PACKAGES" -a -z "$BUILD_DIRTY" ] ; then
       eerror "The following packages were requested for installation but could not be processed:"
       cat $CHECKLOG/package_errors.log
       eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
       eerror "The following packages were requested for installation but could not be processed:"
       cat $CHECKLOG/package_errors.log
       eerror "... exiting as requested via \$EXIT_ON_MISSING_PACKAGES."
@@ -611,253 +644,272 @@ 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 "$NO_ADDONS" ] ; then
-         log "Skipping installation boot addons requested via \$NO_ADDONS."
-         einfo "Skipping installation boot addons requested via \$NO_ADDONS."
-         eend 0
-      else
-         if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
-           ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
-         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 "$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 [ -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 "$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 Depended packages
+            cp -a /usr/lib/ipxe/ipxe.lkrn "${TEMPLATE_DIRECTORY}/boot/addons/"
+
+            # 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   "bsd4grml addon not found, skipping therefore."
+                 ewarn "bsd4grml addon not found, skipping therefore." ; eend 0
+               fi
+            fi
 
 
-           if [ -z "$NO_ADDONS_BSD4GRML" ] ; then
-              cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
+          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
+            mkdir -p "${BUILD_OUTPUT}/boot/grub"
+            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"
+            /usr/bin/grub-mkimage -d /usr/lib/grub/*-pc -o \
+              "${BUILD_OUTPUT}/boot/grub/core.img" biosdisk iso9660 --format=i386-pc
+          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
            fi
          fi
            fi
          fi
-      fi
-
-      if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
-         cp -a ${TEMPLATE_DIRECTORY}/boot/grub  "$BUILD_OUTPUT"/boot/
-      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/
-
-      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")"
-
-      sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
-      sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/grml-version
-
-      # make sure the squashfs filename is set accordingly:
-      SQUASHFS_NAME="$GRML_NAME.squashfs"
-
-      # 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
-        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}"
-      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")"
-      sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "$BUILD_OUTPUT"/boot/isolinux/f4
-      sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "$BUILD_OUTPUT"/boot/isolinux/f5
-
-      # 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"
-         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."
+       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 -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
-           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
-      else
-         sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/menu.lst
-         sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/grub.cfg
-      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
-         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
@@ -883,91 +935,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:
@@ -975,35 +979,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
 
@@ -1011,8 +1007,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 {{{
@@ -1020,17 +1018,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'"
 
@@ -1052,11 +1059,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}")
@@ -1089,19 +1108,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
@@ -1120,7 +1144,7 @@ else
          ;;
       esac
 
          ;;
       esac
 
-      cd $CURRENT_DIR
+      cd "$CURRENT_DIR"
    fi
 
    if [ "$RC" = 0 ] ; then
    fi
 
    if [ "$RC" = 0 ] ; then
@@ -1157,9 +1181,8 @@ if [ -d /usr/share/grml-live-db ] ; then
   #fi
 
   if ! [ -r "$DPKG_LIST" ] ; then
   #fi
 
   if ! [ -r "$DPKG_LIST" ] ; then
-     log "Error reading $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT"
-     eerror "Error reading $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT" ; eend 1
-     bailout 14
+     log   "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
+     ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
   else
      einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
      log "Logging $DPKG_LIST to database $DPKG_DATABASE"
   else
      einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
      log "Logging $DPKG_LIST to database $DPKG_DATABASE"
@@ -1192,4 +1215,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