Lintian cleanups and release new version 0.9.39.
[grml-live.git] / grml-live
index 9197b3e..c0be180 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -23,11 +23,11 @@ fi
 set -e
 
 # global variables
 set -e
 
 # global variables
-GRML_LIVE_VERSION='0.9.21'
+GRML_LIVE_VERSION='0.9.39'
 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'
 SOURCES_LIST_FILE='/etc/grml/fai/apt/sources.list'
+ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
 # }}}
 
 # usage information {{{
 # }}}
 
 # usage information {{{
@@ -43,15 +43,17 @@ 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
    -F                      force execution without prompting
-   -g <grml_name>]         set the grml flavour name
+   -g <grml_name>          set the grml flavour name
    -h                      display short usage information and exit
    -i <iso_name>           name of ISO
    -I <src_directory>      directory which provides files that should become
                            part of the chroot/ISO
    -h                      display short usage information and exit
    -i <iso_name>           name of ISO
    -I <src_directory>      directory which provides files that should become
                            part of the chroot/ISO
+   -n                      skip generation of ISO
    -o <output_directory>   main output directory of the build process
    -q                      skip mksquashfs
    -o <output_directory>   main output directory of the build process
    -q                      skip mksquashfs
-   -r <release_name<       release name
+   -r <release_name>       release name
    -s <suite>              Debian suite; values: etch, lenny, squeeze, sid
    -t <template_directory> place of the templates
    -u                      update existing chroot instead of rebuilding it from scratch
    -s <suite>              Debian suite; values: etch, lenny, squeeze, sid
    -t <template_directory> place of the templates
    -u                      update existing chroot instead of rebuilding it from scratch
@@ -121,6 +123,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:
@@ -132,6 +136,7 @@ LIVE_CONF=/etc/grml/grml-live.conf
 bailout() {
   rm -f /var/run/fai/fai_softupdate_is_running \
         /var/run/fai/FAI_INSTALLATION_IN_PROGRESS
 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}"
   [ -n "$1" ] && EXIT="$1" || EXIT="1"
   [ -n "$2" ] && eerror "$2">&2
   [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
   [ -n "$1" ] && EXIT="$1" || EXIT="1"
   [ -n "$2" ] && eerror "$2">&2
@@ -209,16 +214,18 @@ fi
 # }}}
 
 # command line parsing {{{
 # }}}
 
 # command line parsing {{{
-while getopts "a:C:c:g:i:I:o:r:s:t:v:bBFuqVz" 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" ;;
+    n) SKIP_MKISOFS=1 ;;
     o) OUTPUT="$OPTARG" ;;
     q) SKIP_MKSQUASHFS=1 ;;
     r) RELEASENAME="$OPTARG" ;;
     o) OUTPUT="$OPTARG" ;;
     q) SKIP_MKSQUASHFS=1 ;;
     r) RELEASENAME="$OPTARG" ;;
@@ -241,19 +248,20 @@ shift $(($OPTIND - 1))  # set ARGV to the first not parsed commandline parameter
 [ -n "$BUILD_OUTPUT" ]     || BUILD_OUTPUT="$OUTPUT/grml_cd"
 [ -n "$CHROOT_OUTPUT" ]    || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
 [ -n "$CLASSES" ]          || CLASSES="GRMLBASE,GRML_MEDIUM,I386"
 [ -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 "$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 "$GRML_FAI_CONFIG" ]  || GRML_FAI_CONFIG='/etc/grml/fai'
 [ -n "$GRML_NAME" ]        || GRML_NAME='grml'
 [ -n "$HOSTNAME" ]         || HOSTNAME='grml'
-[ -n "$ISOLINUX_METHOD" ]  || ISOLINUX_METHOD='console'
 [ -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 "$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='stable'
+[ -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 "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
 [ -n "$USERNAME" ]         || USERNAME='grml'
 [ -n "$VERSION" ]          || VERSION='0.0.1'
@@ -273,29 +281,20 @@ 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
 
 # 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_GRML_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
+[ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
 
 # export variables to have them available in fai scripts:
 [ -n "$GRML_NAME" ]   && export GRML_NAME="$GRML_NAME"
 [ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
 # }}}
 
 
 # export variables to have them available in fai scripts:
 [ -n "$GRML_NAME" ]   && export GRML_NAME="$GRML_NAME"
 [ -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
 # }}}
 
@@ -305,29 +304,34 @@ 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 "$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 "$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) 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
@@ -336,11 +340,34 @@ 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
 if [ -n "$CONFIG" ] ; then
    if ! [ -f "$CONFIG" ] ; then
-      log "Sorry, $CONFIG could not be read. Exiting. [$(date)]"
-      eerror "Sorry, $CONFIG could not be read. Exiting."
+      log    "Error: $CONFIG could not be read. Exiting. [$(date)]"
+      eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
       bailout 1
    else
       log "Sourcing $CONFIG"
       bailout 1
    else
       log "Sourcing $CONFIG"
@@ -360,15 +387,15 @@ einfo "Logging actions to logfile $LOGFILE"
 # on-the-fly configuration {{{
 if [ -n "$MIRROR_DIRECTORY" ] ; then
    if ! [ -d "$MIRROR_DIRECTORY/debian" ] ; then
 # on-the-fly configuration {{{
 if [ -n "$MIRROR_DIRECTORY" ] ; then
    if ! [ -d "$MIRROR_DIRECTORY/debian" ] ; then
-      log "Sorry, $MIRROR_DIRECTORY/debian does not seem to exist. Exiting. [$(date)]"
-      eerror "Sorry, $MIRROR_DIRECTORY/debian does not seem to exist. Exiting."
+      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*
       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!'
+# 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
@@ -379,7 +406,7 @@ elif [ -n "$GRML_LIVE_SOURCES" ] ; then
 # 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*
 # 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!'
+# 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
@@ -432,14 +459,18 @@ done
 # architecture (option), otherwise installation of kernel will fail
 if echo $CLASSES | grep -qi i386 ; then
    if ! [[ "$ARCH" == "i386" ]] ; then
 # architecture (option), otherwise installation of kernel will fail
 if echo $CLASSES | grep -qi i386 ; then
    if ! [[ "$ARCH" == "i386" ]] ; then
-      eerror "You specified the I386 class but are trying to build something else (AMD64?)."
-      eerror "-> Either invoke grml-live with '-i i386' or adjust the architecture class. Exiting."
+      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 '-a i386' or adjust the architecture class. Exiting."
+      eend 1
       bailout
    fi
 elif echo $CLASSES | grep -qi amd64 ; then
    if ! [[ "$ARCH" == "amd64" ]] ; then
       bailout
    fi
 elif echo $CLASSES | grep -qi amd64 ; then
    if ! [[ "$ARCH" == "amd64" ]] ; then
-      eerror "You specified the AMD64 class but are trying to build something else (I386?)."
-      eerror "-> Either invoke grml-live with '-i amd64' or adjust the architecture class. Exiting."
+      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 '-a amd64' or adjust the architecture class. Exiting."
+      eend 1
       bailout
    fi
 fi
       bailout
    fi
 fi
@@ -453,7 +484,8 @@ fi
 
 # CHROOT_OUTPUT - execute FAI {{{
 if [ -n "$BUILD_DIRTY" ]; then
 
 # CHROOT_OUTPUT - execute FAI {{{
 if [ -n "$BUILD_DIRTY" ]; then
-  einfo "Skipping FAI" ; eend 0
+   log   "Skipping stage 'fai' as requested via option -B"
+   ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
 else
    [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
 
 else
    [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
 
@@ -470,8 +502,8 @@ else
    fi
 
    if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
    fi
 
    if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
-      if ! [ -r "$CHROOT_OUTPUT/etc/grml_version" ] ; then
-         log "Error: does not look like you have a working chroot. Updating/building not possible."
+      if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
+         log    "Error: does not look like you have a working chroot. Updating/building not possible."
          eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
          eend 1
          bailout 20
          eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
          eend 1
          bailout 20
@@ -479,8 +511,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 "$CHROOT_OUTPUT exists already, skipping stage 'fai dirinstall'"
-      ewarn "$CHROOT_OUTPUT exists already, skipping stage 'fai dirinstall'" ; eend 0
+      log   "Skiping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
+      ewarn "Skiping 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"
 
@@ -495,17 +527,20 @@ else
       "$HOSTNAME" $FAI_ACTION "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
       RC="$PIPESTATUS" # notice: bash-only
 
       "$HOSTNAME" $FAI_ACTION "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
       RC="$PIPESTATUS" # notice: bash-only
 
+      FORCE_ISO_REBUILD=true
+
       if [ "$RC" != 0 ] ; then
       if [ "$RC" != 0 ] ; then
-         log "Error while executing fai [exit code ${RC}]. Exiting."
-         eerror "Error while executing fai [exit code ${RC}]. Exiting." ; eend 1
+         log    "Error: critical error while executing fai [exit code ${RC}]. Exiting."
+         eerror "Error: critical error while executing fai [exit code ${RC}]. Exiting." ; eend 1
          bailout 1
       else
          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:
-         chroot $CHROOT_OUTPUT update-initramfs -u -t
+         # chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :(
+         chroot $CHROOT_OUTPUT update-initramfs -u -k all
          eend $?
       fi
 
          eend $?
       fi
 
@@ -539,9 +574,9 @@ else
       fi
 
       if [ -n "$ERROR" ] ; then
       fi
 
       if [ -n "$ERROR" ] ; then
-         log "There was an error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
-         eerror "There was an error during execution of stage 'fai dirinstall'"
-         echo "   Check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
+         log    "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
+         eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
+         eerror "Note:  check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
          eend 1
          bailout 1
       else
          eend 1
          bailout 1
       else
@@ -549,10 +584,32 @@ else
          einfo "Finished execution of stage 'fai dirinstall'"
       fi
 
          einfo "Finished execution of stage 'fai dirinstall'"
       fi
 
+      einfo "Find FAI build logs at $(readlink -f /var/log/fai/$HOSTNAME/last)"
+      log   "Find FAI build logs at $(readlink -f /var/log/fai/$HOSTNAME/last)"
+      eend 0
    fi
 fi # BUILD_DIRTY?
 # }}}
 
    fi
 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"
@@ -560,77 +617,104 @@ mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for s
 # i386:
 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
    if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
 # i386:
 if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
    if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
-      log "$BUILD_OUTPUT/boot/isolinux exists already, skipping stage 'boot'"
-      ewarn "$BUILD_OUTPUT/boot/isolinux exists already, skipping stage 'boot'" ; eend 0
+      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
    else
       # booting stuff:
       [ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
-      [ -d "$BUILD_OUTPUT"/boot/"${SHORT_GRML_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_GRML_NAME}"
+      [ -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 [ -z "$NO_ADDONS" ] ; then
          [ -d "$BUILD_OUTPUT"/boot/addons   ] || mkdir -p "$BUILD_OUTPUT"/boot/addons
-         cp /boot/memtest86+.bin "$BUILD_OUTPUT"/boot/addons/memtest
+         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
       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_GRML_NAME}"/initrd.gz
+         cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
          find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
       else
          find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
       else
-         log "No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
-         eerror "No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
+         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
          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_GRML_NAME}"/linux26
+         cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/linux26
       else
       else
-         log "No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
-         eerror "No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
+         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
          bailout 11
       fi
 
       [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
       if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
-         log "${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
-         eerror "${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
+         log    "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
+         eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
          bailout 8
       fi
 
          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
       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
 
       if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
-         log "${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
-         eerror "${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
+         log    "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
+         eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
          bailout 9
       fi
 
          bailout 9
       fi
 
@@ -642,52 +726,94 @@ 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
-
-      sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/" "$BUILD_OUTPUT"/boot/isolinux/boot.msg
-      sed -i "s/%DATE%/$ISO_DATE/"             "$BUILD_OUTPUT"/boot/isolinux/boot.msg
-
-      sed -i "s/%GRML_NAME%/$SHORT_GRML_NAME/" "$BUILD_OUTPUT"/boot/isolinux/isolinux.cfg
-      sed -i "s/%GRML_NAME%/$SHORT_GRML_NAME/" "$BUILD_OUTPUT"/boot/isolinux/syslinux.cfg
-
-      sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/" "$BUILD_OUTPUT"/boot/isolinux/boot-beep.msg
-      sed -i "s/%DATE%/$ISO_DATE/"             "$BUILD_OUTPUT"/boot/isolinux/boot-beep.msg
-
-      sed -i "s/%VERSION%/$VERSION/"           "$BUILD_OUTPUT"/boot/grub/menu.lst
-      sed -i "s/%GRML_NAME%/$SHORT_GRML_NAME/" "$BUILD_OUTPUT"/boot/grub/menu.lst
+      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
 
 
-      sed -i "s/%VERSION%/$VERSION/"           "$BUILD_OUTPUT"/boot/grub/grub.cfg
-      sed -i "s/%GRML_NAME%/$SHORT_GRML_NAME/" "$BUILD_OUTPUT"/boot/grub/grub.cfg
+      # make sure the squashfs filename is set accordingly:
+      SQUASHFS_NAME="$GRML_NAME.squashfs"
 
 
-      sed -i "s/%VERSION%/$VERSION/"           "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
-      sed -i "s/%GRML_NAME%/$GRML_NAME/"       "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
-      sed -i "s/%ARCH%/$ARCH/"                 "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
+      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
 
 
-      sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/" "$BUILD_OUTPUT"/boot/isolinux/vesamenu.cfg
-      sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/" "$BUILD_OUTPUT"/boot/isolinux/vesamenu.cfg
+      # 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
+      done
+
+      # adjust bootsplash accordingly but make sure the string has the according lenght
+      SQUASHFS_NAME="$(cut_string 20 "$SQUASHFS_NAME")"
+      SQUASHFS_NAME="$(extend_string_end 20 "$SQUASHFS_NAME")"
+      for file in f4 f5 ; do
+         if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
+            sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
+            sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
+         fi
+      done
+
+      # generate addon list
+      rm "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+      for name in $(ls "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg) ; do
+        include_name=$(basename "$name")
+        echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+      done
+
+      if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
+         log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+         echo "include grmlmain.cfg"    >  "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
+         echo "include default.cfg"     >  "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+         echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+         echo "include grml.cfg"        >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+
+         for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
+           echo "include $(basename $f)"     >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
+         done
 
 
-      # make sure the squashfs filename is set accordingly:
-      GRML_NAME_SQUASHFS="$GRML_NAME.squashfs"
-      sed -i "s/%GRML_NAME_SQUASHFS%/$GRML_NAME_SQUASHFS/" "$BUILD_OUTPUT"/boot/isolinux/isolinux.cfg
-      sed -i "s/%GRML_NAME_SQUASHFS%/$GRML_NAME_SQUASHFS/" "$BUILD_OUTPUT"/boot/isolinux/syslinux.cfg
-      sed -i "s/%GRML_NAME_SQUASHFS%/$GRML_NAME_SQUASHFS/" "$BUILD_OUTPUT"/boot/grub/menu.lst
-
-      GRML_NAME_SQUASHFS="$(cut_string 20 "$GRML_NAME_SQUASHFS")"
-      GRML_NAME_SQUASHFS="$(extend_string_end 20 "$GRML_NAME_SQUASHFS")"
-      sed -i "s/%GRML_NAME_SQUASHFS%/$GRML_NAME_SQUASHFS/" "$BUILD_OUTPUT"/boot/isolinux/f4
-      sed -i "s/%GRML_NAME_SQUASHFS%/$GRML_NAME_SQUASHFS/" "$BUILD_OUTPUT"/boot/isolinux/f5
-
-      if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] ; then
-         log "including grml.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-         echo "include grml.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
-         [ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.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."
       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."
            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"
            eend $?
         else
            log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
@@ -719,25 +845,45 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
          fi
       fi
 
          fi
       fi
 
-      # jump back to grub from bsd4grml:
+      # 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
       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
-         if [ -e "$BUILD_OUTPUT"/boot/grub/stage2 ]; then
-            GRUB_LEGACY=stage2
-         else
-            GRUB_LEGACY=stage2_eltorito
-         fi
 
 
-         # why not ed(1)?
          for file in "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 \
          for file in "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 \
-                     "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.cfg; do
-             sed -i -e "s!%GRUB_VERSION%!$GRUB_VERSION!g" \
-                    -e "s!%GRUB_LEGACY%!$GRUB_LEGACY!g" "$file"
+                     "$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
          done
+
+         sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
+      fi
+
+      if [ -e "$BUILD_OUTPUT"/boot/grub/$GRUB_LEGACY ]; then
+         sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/menu.lst
+         sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/grub.cfg
+      elif [ -e "$BUILD_OUTPUT"/boot/grub/menu.lst -a -e "$BUILD_OUTPUT"/boot/grub/grub.cfg ] ; then
+         sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/menu.lst
+         sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/grub.cfg
+      fi
+
+      DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
+      if ! [ -r "$DPKG_LIST" ] ; then
+         ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
+      else
+         einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
+         cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
+         eend $?
       fi
 
       # autostart for Windows:
       fi
 
       # autostart for Windows:
@@ -747,13 +893,13 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
 
       # windows-binaries:
       if [ -n "$NO_WINDOWS_BINARIES" ] ; then
 
       # windows-binaries:
       if [ -n "$NO_WINDOWS_BINARIES" ] ; then
-         log "Skipping download of windows binaries as requested via \$NO_WINDOWS_BINARIES."
+         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
          einfo "Skipping download of windows binaries as requested via \$NO_WINDOWS_BINARIES."
          eend 0
       else
          if [ -f "$BUILD_OUTPUT"/windows/putty.exe ] ; then
-            log "$BUILD_OUTPUT/windows exists already, skipping stage 'WINDOWS_BINARIES'"
-            ewarn "$BUILD_OUTPUT/windows exists already, skipping stage 'WINDOWS_BINARIES'" ; eend 0
+            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
          else
             if ! [ -d "$BUILD_OUTPUT"/windows ] ; then
                mkdir "$BUILD_OUTPUT"/windows
@@ -763,15 +909,19 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
                     md5sum ${file}.exe > ${file}.exe.md5
                  done )
             fi
                     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
-         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
 else
    einfo "Finished execution of stage 'boot'" ; eend 0
    fi
 else
-   log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
+   log    'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
    eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
    eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
+   bailout
 fi
 
 # support installation of local files into the chroot/ISO
 fi
 
 # support installation of local files into the chroot/ISO
@@ -785,36 +935,91 @@ if [ -n "$CHROOT_INSTALL" ] ; then
      rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
      eend $?
      einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
      rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
      eend $?
      einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
+     FORCE_ISO_REBUILD=true
   fi
 fi
 
 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
   fi
 fi
 
 if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
-   log "$BUILD_OUTPUT/live exists already, skipping stage 'squashfs'"
-   ewarn "$BUILD_OUTPUT/live exists already, skipping stage 'squashfs'" ; eend 0
+   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
 elif [ -n "$SKIP_MKSQUASHFS" ] ; then
-   log "Skipping stage 'squashfs' as requested via option -q"
+   log   "Skipping stage 'squashfs' as requested via option -q"
    ewarn "Skipping stage 'squashfs' as requested via option -q" ; 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"
 
    ewarn "Skipping stage 'squashfs' as requested via option -q" ; 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"
 
+   # $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
+   fi
+
    # make sure mksquashfs can handle the according option:
    if [ -n "$SQUASHFS_ZLIB" ] ; then
    # make sure mksquashfs can handle the according option:
    if [ -n "$SQUASHFS_ZLIB" ] ; then
-      mksquashfs --help 2>&1 | grep -q -- "$SQUASHFS_ZLIB" || SQUASHFS_ZLIB=''
+      $SQUASHFS_BINARY --help 2>&1 | grep -q -- "$SQUASHFS_ZLIB" || SQUASHFS_ZLIB=''
    fi
 
    fi
 
+   # make sure to drop the -nolzma option if it's not available:
    if echo "$SQUASHFS_OPTIONS" | grep -q -- "-nolzma" ; then
    if echo "$SQUASHFS_OPTIONS" | grep -q -- "-nolzma" ; then
-      if ! mksquashfs --help 2>&1 | grep -q -- '-nolzma' ; then
-         ewarn "mksquashfs does NOT support the nolzma option, just using default zlib mode."
+      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
 
          SQUASHFS_OPTIONS="$(echo $SQUASHFS_OPTIONS | sed 's/-nolzma//g')"
          eend 0
       fi
    fi
 
+   # make sure to drop the -lzma option if it's not available:
    if echo "$SQUASHFS_OPTIONS" | grep -q -- "-lzma" ; then
    if echo "$SQUASHFS_OPTIONS" | grep -q -- "-lzma" ; then
-      if ! mksquashfs --help 2>&1 | grep -q -- '-lzma' ; then
-         ewarn "mksquashfs does NOT support the lzma option, falling back to zlib mode."
+      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
          SQUASHFS_OPTIONS="$(echo $SQUASHFS_OPTIONS | sed 's/-lzma//g')"
          eend 0
       fi
@@ -827,25 +1032,42 @@ else
 
    # get rid of unnecessary files when building grml-small for final release:
    if echo "$CLASSES" | grep -q GRML_SMALL ; then
 
    # get rid of unnecessary files when building grml-small for final release:
    if echo "$CLASSES" | grep -q GRML_SMALL ; then
-      SQUASHFS_OPTIONS="$SQUASHFS_OUTPUT -e initrd.img* vmlinuz*"
+      SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
    fi
 
    fi
 
-   SQUASHFS_OUTPUT="$(mktemp -t grml-live.XXXXXX)"
-   log "mksquashfs $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB"
-   if mksquashfs $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
-      -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB 2>"${SQUASHFS_OUTPUT}" ; then
+   # 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
+
+   SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
+
+   [ -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"
+
+   log "$SQUASHFS_BINARY $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB"
+
+   if $SQUASHFS_BINARY $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
+      -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB 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
       echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
       log "Finished execution of stage 'squashfs' [$(date)]"
       einfo "Finished execution of stage 'squashfs'" ; eend 0
-      rm -f "${SQUASHFS_OUTPUT}"
    else
    else
-      log "There was an error executing stage 'squashfs' [$(date)]:"
-      log "$(cat $SQUASHFS_OUTPUT)"
-      eerror "There was an error executing stage 'squashfs':" ; eend 1
-      cat "${SQUASHFS_OUTPUT}"
-      rm -f "${SQUASHFS_OUTPUT}"
+      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
+      cat    "${SQUASHFS_STDERR}"
       bailout
    fi
       bailout
    fi
+
+   FORCE_ISO_REBUILD=true
 fi
 
 # create md5sum file:
 fi
 
 # create md5sum file:
@@ -860,23 +1082,31 @@ find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; >
 if [ "$BOOT_METHOD" = "isolinux" ] ; then
    BOOT_FILE="boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
 elif [ "$BOOT_METHOD" = "grub" ] ; then
 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_eltorito"
+   BOOT_FILE="boot/grub/stage2"
 fi
 
 fi
 
-if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
-   log "$ISO_OUTPUT exists already, skipping stage 'iso build'"
-   ewarn "$ISO_OUTPUT exists already, skipping stage 'iso build'" ; eend 0
+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
 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'"
 
+   if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; then
+      log   "Forcing rebuild of ISO because files on ISO have been modified."
+      einfo "Forcing rebuild of ISO because files on ISO have been modified."
+   fi
+
    # support mkisofs as well as genisoimage
    if which mkisofs >/dev/null 2>&1; then
       MKISOFS='mkisofs'
    elif which genisoimage >/dev/null 2>&1; then
       MKISOFS='genisoimage'
    else
    # support mkisofs as well as genisoimage
    if which mkisofs >/dev/null 2>&1; then
       MKISOFS='mkisofs'
    elif which genisoimage >/dev/null 2>&1; then
       MKISOFS='genisoimage'
    else
-      log "Sorry, neither mkisofs nor genisoimage available - can not create ISO."
-      eerror "Sorry, neither mkisofs nor genisoimage available - can not create ISO." ; eend 1
+      log    "Error: neither mkisofs nor genisoimage available - can not create ISO."
+      eerror "Error: neither mkisofs nor genisoimage available - can not create ISO." ; eend 1
       bailout
    fi
 
       bailout
    fi
 
@@ -897,7 +1127,7 @@ else
 
       # support disabling hybrid ISO image
       if [ "$HYBRID_METHOD" = "disable" ] ; then\
 
       # support disabling hybrid ISO image
       if [ "$HYBRID_METHOD" = "disable" ] ; then\
-         log "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
+         log   "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
          einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
          eend 0
       # use isohybrid only on request
          einfo "Skipping creation of hybrid ISO file as requested via HYBRID_METHOD=disable"
          eend 0
       # use isohybrid only on request
@@ -907,6 +1137,13 @@ 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
            isohybrid "${ISO_OUTPUT}/${ISO_NAME}"
            eend $?
          fi
@@ -917,10 +1154,14 @@ else
          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
+           (
+               # 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
            eend $?
          fi
       fi
            eend $?
          fi
       fi
@@ -943,20 +1184,69 @@ else
    fi
 
    if [ "$RC" = 0 ] ; then
    fi
 
    if [ "$RC" = 0 ] ; then
-      log "Finished execution of stage 'iso build' [$(date)]"
+      log   "Finished execution of stage 'iso build' [$(date)]"
       einfo "Finished execution of stage 'iso build'" ; eend 0
    else
       einfo "Finished execution of stage 'iso build'" ; eend 0
    else
-      log "There was an error ($RC) executing stage 'iso build' [$(date)]"
-      eerror "There was an error executing stage 'iso build'" ; eend 1
+      log    "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
+      eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
       bailout $RC
    fi
 fi
 # }}}
 
       bailout $RC
    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
 # }}}