Release new version 0.14.0.
[grml-live.git] / grml-live
index 5a8dffc..0c27ce1 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -23,10 +23,9 @@ fi
 set -e
 
 # global variables
 set -e
 
 # global variables
-GRML_LIVE_VERSION='0.9.28-pre1'
+GRML_LIVE_VERSION='0.14.0'
 PN="$(basename $0)"
 CMDLINE="$0 $@"
 PN="$(basename $0)"
 CMDLINE="$0 $@"
-ISO_DATE="$(date +%Y-%m-%d)"
 SOURCES_LIST_FILE='/etc/grml/fai/apt/sources.list'
 ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
 # }}}
 SOURCES_LIST_FILE='/etc/grml/fai/apt/sources.list'
 ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
 # }}}
@@ -44,6 +43,7 @@ Usage: $PN [options, see as follows]
    -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
    -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
    -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
@@ -59,8 +59,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:
 
@@ -123,6 +122,8 @@ else
    eerror() { echo "  [!] $*">&2 ;}
    ewarn()  { echo "  [x] $*" ;}
    eend()   { return 0 ;}
    eerror() { echo "  [!] $*">&2 ;}
    ewarn()  { echo "  [x] $*" ;}
    eend()   { return 0 ;}
+   eindent()  { return 0 ;}
+   eoutdent() { return 0 ;}
 fi
 
 # source main configuration file:
 fi
 
 # source main configuration file:
@@ -212,13 +213,14 @@ fi
 # }}}
 
 # command line parsing {{{
 # }}}
 
 # command line parsing {{{
-while getopts "a:C:c:g:i:I:o:r:s:t:v:bBFnquVz" opt; do
+while getopts "a:C:c:d:g:i:I:o:r:s:t:v:bBFnquVz" opt; do
   case "$opt" in
     a) ARCH="$OPTARG" ;;
     b) BUILD_ONLY=1 ;;
     B) BUILD_DIRTY=1 ;;
     c) CLASSES="$OPTARG" ;;
     C) CONFIG="$OPTARG" ;;
   case "$opt" in
     a) ARCH="$OPTARG" ;;
     b) BUILD_ONLY=1 ;;
     B) BUILD_DIRTY=1 ;;
     c) CLASSES="$OPTARG" ;;
     C) CONFIG="$OPTARG" ;;
+    d) DATE="$OPTARG" ;;
     g) GRML_NAME="$OPTARG" ;;
     i) ISO_NAME="$OPTARG" ;;
     I) CHROOT_INSTALL="$OPTARG" ;;
     g) GRML_NAME="$OPTARG" ;;
     i) ISO_NAME="$OPTARG" ;;
     I) CHROOT_INSTALL="$OPTARG" ;;
@@ -232,7 +234,7 @@ while getopts "a:C:c: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
@@ -242,9 +244,8 @@ shift $(($OPTIND - 1))  # set ARGV to the first not parsed commandline parameter
 # assume sane defaults (if not set already) {{{
 [ -n "$ARCH" ]             || ARCH="$(dpkg --print-architecture)"
 [ -n "$BOOT_METHOD" ]      || BOOT_METHOD='isolinux'
 # assume sane defaults (if not set already) {{{
 [ -n "$ARCH" ]             || ARCH="$(dpkg --print-architecture)"
 [ -n "$BOOT_METHOD" ]      || BOOT_METHOD='isolinux'
-[ -n "$BUILD_OUTPUT" ]     || BUILD_OUTPUT="$OUTPUT/grml_cd"
-[ -n "$CHROOT_OUTPUT" ]    || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
 [ -n "$CLASSES" ]          || CLASSES="GRMLBASE,GRML_MEDIUM,I386"
 [ -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 "$DISTRI_INFO" ]      || DISTRI_INFO='Grml - Live Linux for system administrators   '
 [ -n "$DISTRI_NAME" ]      || DISTRI_NAME="grml"
 [ -n "$DISTRI_SPLASH" ]    || DISTRI_SPLASH='grml.png'
@@ -252,16 +253,21 @@ shift $(($OPTIND - 1))  # set ARGV to the first not parsed commandline parameter
 [ -n "$GRML_FAI_CONFIG" ]  || GRML_FAI_CONFIG='/etc/grml/fai'
 [ -n "$GRML_NAME" ]        || GRML_NAME='grml'
 [ -n "$HOSTNAME" ]         || HOSTNAME='grml'
 [ -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 "$HYBRID_METHOD" ]    || HYBRID_METHOD='manifold'
 [ -n "$NFSROOT_CONF" ]     || NFSROOT_CONF='/etc/grml/fai/make-fai-nfsroot.conf'
 [ -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 "$RELEASENAME" ]      || RELEASENAME='grml-live rocks'
 [ -n "$SQUASHFS_EXCLUDES_FILE " ] || SQUASHFS_EXCLUDES_FILE='/etc/grml/fai/squashfs-excludes'
-[ -n "$SUITE" ]            || SUITE='lenny'
+[ -n "$SUITE" ]            || SUITE='squeeze'
 [ -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 "$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/'
+
+# 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 "$ISO_OUTPUT" ]       || ISO_OUTPUT="$OUTPUT/grml_isos"
 # }}}
 
 # some misc checks before executing FAI {{{
 # }}}
 
 # some misc checks before executing FAI {{{
@@ -270,11 +276,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 ',./;\- ')"
@@ -284,22 +285,13 @@ ISO_OUTPUT="$OUTPUT/grml_isos"
 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
 # }}}
 
 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
 # }}}
 
-# clean/zero grml-live logfile {{{
+# ZERO_LOGFILE - check for backwards compatibility reasons {{{
+# this was default behaviour until grml-live 0.9.34:
 if [ -n "$ZERO_LOGFILE" ] ; then
 if [ -n "$ZERO_LOGFILE" ] ; then
-   echo -n > $LOGFILE
-fi
-# }}}
-
-# clean/zero/remove old FAI directory {{{
-if [ -n "$ZERO_FAI_LOGFILE" ] ; then
-   if [ -d /var/log/fai/"$HOSTNAME" ] ; then
-      rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
-      rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
-      rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
-      rm -f /var/log/fai/"$HOSTNAME"/last \
-            /var/log/fai/"$HOSTNAME"/last-dirinstall \
-            /var/log/fai/"$HOSTNAME"/last-softupdate
-   fi
+   PRESERVE_LOGFILE='' # make sure it's cleaned then
+   ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
+   ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
+   eend 0
 fi
 # }}}
 
 fi
 # }}}
 
@@ -309,30 +301,35 @@ 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"
    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 "$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."
+   [ -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."
    echo
    echo -n "Is this ok for you? [y/N] "
    read a
    echo
    echo -n "Is this ok for you? [y/N] "
    read a
@@ -341,7 +338,30 @@ if [ -z "$FORCE" ] ; then
    fi
    echo
 fi
    fi
    echo
 fi
+# }}}
+
+# clean/zero/remove logfiles {{{
 
 
+if [ -n "$PRESERVE_LOGFILE" ] ; then
+   echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
+else
+   # make sure it is empty (as it is e.g. appended to grml-live-db)
+   echo -n > $LOGFILE
+fi
+
+if [ -n "$ZERO_FAI_LOGFILE" ] ; then
+   if [ -d /var/log/fai/"$HOSTNAME" ] ; then
+      rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
+      rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
+      rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
+      rm -f /var/log/fai/"$HOSTNAME"/last \
+            /var/log/fai/"$HOSTNAME"/last-dirinstall \
+            /var/log/fai/"$HOSTNAME"/last-softupdate
+   fi
+fi
+# }}}
+
+# source config and startup {{{
 if [ -n "$CONFIG" ] ; then
    if ! [ -f "$CONFIG" ] ; then
       log    "Error: $CONFIG could not be read. Exiting. [$(date)]"
 if [ -n "$CONFIG" ] ; then
    if ! [ -f "$CONFIG" ] ; then
       log    "Error: $CONFIG could not be read. Exiting. [$(date)]"
@@ -371,9 +391,9 @@ if [ -n "$MIRROR_DIRECTORY" ] ; then
    fi
    cat > "$SOURCES_LIST_FILE" << EOF
 # NOTE: This file is *NOT* meant for manual customisation! This file is
    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.
+# modified by grml-live and any changes might be overridden.
 # You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
 # You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
-# and using /etc/grml/fai/files/etc/apt instead!'
+# 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
 EOF
    echo "$MIRROR_SOURCES" >> "$SOURCES_LIST_FILE"
    if [ -n "$GRML_LIVE_SOURCES" ] ; then
@@ -382,9 +402,9 @@ EOF
 elif [ -n "$GRML_LIVE_SOURCES" ] ; then
    cat > "$SOURCES_LIST_FILE" << EOF
 # NOTE: This file is *NOT* meant for manual customisation! This file is
 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 overriden.
+# modified by grml-live and any changes might be overridden.
 # You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
 # You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
-# and using /etc/grml/fai/files/etc/apt instead!'
+# or FAI's fcopy command with /etc/grml/fai/config/files instead!
 EOF
    echo "$GRML_LIVE_SOURCES" >> "$SOURCES_LIST_FILE"
 fi
 EOF
    echo "$GRML_LIVE_SOURCES" >> "$SOURCES_LIST_FILE"
 fi
@@ -404,11 +424,12 @@ 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
 
-DIST=" etch\| stable\| lenny\| squeeze\| testing\| sid\| unstable"
+DIST=" etch\| stable\| lenny\| squeeze\| wheezy\| 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/\(^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
@@ -439,7 +460,7 @@ if echo $CLASSES | grep -qi i386 ; then
    if ! [[ "$ARCH" == "i386" ]] ; then
       log    "Error: You specified the I386 class but are trying to build something else (AMD64?)."
       eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
    if ! [[ "$ARCH" == "i386" ]] ; then
       log    "Error: You specified the I386 class but are trying to build something else (AMD64?)."
       eerror "Error: You specified the I386 class but are trying to build something else (AMD64?)."
-      eerror "Tip:   Either invoke grml-live with '-i i386' or adjust the architecture class. Exiting."
+      eerror "Tip:   Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
       eend 1
       bailout
    fi
       eend 1
       bailout
    fi
@@ -447,7 +468,7 @@ elif echo $CLASSES | grep -qi amd64 ; then
    if ! [[ "$ARCH" == "amd64" ]] ; then
       log    "Error: You specified the AMD64 class but are trying to build something else (I386?)."
       eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
    if ! [[ "$ARCH" == "amd64" ]] ; then
       log    "Error: You specified the AMD64 class but are trying to build something else (I386?)."
       eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
-      eerror "Tip:   Either invoke grml-live with '-i amd64' or adjust the architecture class. Exiting."
+      eerror "Tip:   Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
       eend 1
       bailout
    fi
       eend 1
       bailout
    fi
@@ -489,8 +510,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"
 
@@ -512,8 +533,8 @@ 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 [$ISO_DATE]"
-         echo "$GRML_NAME $VERSION Release Codename $RELEASENAME [$ISO_DATE]" > $CHROOT_OUTPUT/etc/grml_version
+         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"
          # make sure new /etc/grml_version reaches the initramfs:
          chmod 644 $CHROOT_OUTPUT/etc/grml_version
          einfo "Rebuilding initramfs"
          # make sure new /etc/grml_version reaches the initramfs:
@@ -548,7 +569,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
@@ -569,6 +590,25 @@ else
 fi # BUILD_DIRTY?
 # }}}
 
 fi # BUILD_DIRTY?
 # }}}
 
+# package validator {{{
+CHECKLOG=/var/log/fai/$HOSTNAME/last
+# package validator
+if [ -r "$CHECKLOG/package_errors.log" ] && grep -q '[a-z]' "$CHECKLOG/package_errors.log" ; 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."
+      eend 1
+      bailout 13
+   else
+      ewarn "The following packages were requested for installation but could not be processed:"
+      cat $CHECKLOG/package_errors.log
+      eend 0
+   fi
+fi
+# }}}
+
 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
 # BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
 [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
 mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
@@ -592,8 +632,8 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
             log "Installing /boot/memtest86+.bin"
             cp /boot/memtest86+.bin "$BUILD_OUTPUT"/boot/addons/memtest
          else
             log "Installing /boot/memtest86+.bin"
             cp /boot/memtest86+.bin "$BUILD_OUTPUT"/boot/addons/memtest
          else
-            ewarn "No memtest binary found, skipping."
-            log "No memtest binary found, skipping."
+            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
             eend 0
          fi
       fi
@@ -631,30 +671,45 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       cp ${TEMPLATE_DIRECTORY}/boot/isolinux/*  "$BUILD_OUTPUT"/boot/isolinux/
 
       if [ -n "$NO_ADDONS" ] ; then
       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
+         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
       else
-         if ! [ -d /usr/share/grml-live/templates/boot/addons/bsd4grml ] ; then
+         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 only files so we can handle bsd4grml on its own
            for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
            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/
+             test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
            done
 
            done
 
-           if [ -z "$NO_ADDONS_BSD4GRML" ] ; then
-              cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
+           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
            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
-      fi
 
 
-      if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
-         cp -a ${TEMPLATE_DIRECTORY}/boot/grub  "$BUILD_OUTPUT"/boot/
+         # 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
       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."
 
       if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
          log    "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
@@ -670,36 +725,64 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
       RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
 
       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%/$ISO_DATE/"                                  "$BUILD_OUTPUT"/GRML/grml-version
+      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"
 
 
       # 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
       # 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%/$ISO_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}"
+        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
       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")"
       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
+      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}"
 
       # generate addon list
       rm "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
-      for name in $(ls "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg) ; do
+      for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
         include_name=$(basename "$name")
         echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
       done
         include_name=$(basename "$name")
         echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
       done
@@ -710,6 +793,11 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
          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 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"
          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"
@@ -756,12 +844,9 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
          fi
       fi
 
          fi
       fi
 
-      # jump back to grub from bsd4grml:
-      if [ -e "$BUILD_OUTPUT"/boot/grub/stage2 ]; then
-         GRUB_LEGACY=stage2
-      else
-         GRUB_LEGACY=stage2_eltorito
-      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
       if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
          if [ -e "$BUILD_OUTPUT"/boot/grub/core.img ]; then
             GRUB_VERSION=2
@@ -786,11 +871,20 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       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
       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
+      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
 
          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"/
       # autostart for Windows:
       if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
          cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
@@ -855,79 +949,31 @@ else
    # make sure we don't leave (even an empty) base.tgz:
    [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
 
    # 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 compability 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 compability: 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
-   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 unconfigured default to squashfs-tools' mksquashfs binary
+   if [ -z "$SQUASHFS_BINARY" ] ; then
+      SQUASHFS_BINARY='mksquashfs'
    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
+   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 -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
+   # 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"
+
+     # 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:
    fi
 
    # support exclusion of files via exclude-file:
@@ -940,36 +986,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
-      package
-      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 \
 
    if $SQUASHFS_BINARY $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
-      -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB 2>"${SQUASHFS_STDERR}" ; then
+      -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
 
@@ -986,9 +1023,20 @@ 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"
+   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" = "grub" ] ; then
 elif [ "$BOOT_METHOD" = "grub" ] ; then
-   BOOT_FILE="boot/grub/stage2_eltorito"
+   BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/grub/stage2"
+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
 fi
 
 if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ]  ; then
@@ -1018,11 +1066,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}")
@@ -1043,20 +1103,36 @@ else
          else
            log "Creating hybrid ISO file with isohybrid method"
            einfo "Creating hybrid ISO file with isohybrid method"
          else
            log "Creating hybrid ISO file with isohybrid method"
            einfo "Creating hybrid ISO file with isohybrid method"
+           # Notes for consideration:
+           # "-entry 4 -type 1c"
+           # * using 4 as the partition number is supposed to help with BIOSes
+           #   that only support USB-Zip boot
+           # * using 1c (i.e. hidden FAT32 LBA), instead of the default 0x17
+           #   (hidden NTFS, IIRC), as the partition type is sometimes needed
+           #   to get the BIOS even look at the partition created by isohybrid
            isohybrid "${ISO_OUTPUT}/${ISO_NAME}"
            eend $?
          fi
       # by default use our manifold boot method:
       else
            isohybrid "${ISO_OUTPUT}/${ISO_NAME}"
            eend $?
          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"
-           echo 1 63 | \
-               mksh /usr/share/grml-live/scripts/bootgrub.mksh -A -M 1 -p 0x83 -g $cyls:16:32 | \
-               cat - boot/grub/core.img | \
-               dd conv=notrunc of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
+           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
+           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
@@ -1075,7 +1151,7 @@ else
          ;;
       esac
 
          ;;
       esac
 
-      cd $CURRENT_DIR
+      cd "$CURRENT_DIR"
    fi
 
    if [ "$RC" = 0 ] ; then
    fi
 
    if [ "$RC" = 0 ] ; then
@@ -1089,10 +1165,59 @@ else
 fi
 # }}}
 
 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
+
+  # safe defaults
+  DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
+  [ -n "$DPKG_DATABASE" ]  || DPKG_DATABASE=/var/log/grml-live.db
+  [ -n "$DPKG_DBSCRIPT" ]  || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
+  [ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
+
+  if ! [ -x "$DPKG_DBSCRIPT" ] ; then
+    log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
+    eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
+    bailout 14
+  fi
+
+  # disable by default for now, not sure whether really everyone is using a local db file
+  #if ! touch "$DPKG_DATABASE" ; then
+  #  eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
+  #  bailout 14
+  #fi
+
+  if ! [ -r "$DPKG_LIST" ] ; then
+     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"
+     log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
+     eindent
+
+     if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
+       einfo "$DB_INFO"
+       eend 0
+     else
+       eerror "$DB_INFO"
+       eend 1
+     fi
+
+     eoutdent
+  fi
+
+fi
+}
+# }}}
+
 # finalize {{{
 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
 # finalize {{{
 [ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
-einfo "Successfully finished execution of $PN [running ${SECONDS} seconds]" ; eend 0
-log "Successfully finished execution of $PN [running ${SECONDS} seconds]"
+log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
+
+dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
+
+einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
 bailout 0
 # }}}
 
 bailout 0
 # }}}