Lintian cleanups and release new version 0.9.39.
[grml-live.git] / grml-live
index bef4997..c0be180 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -23,7 +23,7 @@ fi
 set -e
 
 # global variables
-GRML_LIVE_VERSION='0.9.30'
+GRML_LIVE_VERSION='0.9.39'
 PN="$(basename $0)"
 CMDLINE="$0 $@"
 SOURCES_LIST_FILE='/etc/grml/fai/apt/sources.list'
@@ -123,6 +123,8 @@ else
    eerror() { echo "  [!] $*">&2 ;}
    ewarn()  { echo "  [x] $*" ;}
    eend()   { return 0 ;}
+   eindent()  { return 0 ;}
+   eoutdent() { return 0 ;}
 fi
 
 # source main configuration file:
@@ -286,22 +288,13 @@ ISO_OUTPUT="$OUTPUT/grml_isos"
 [ -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
-   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
 # }}}
 
@@ -311,31 +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"
-   [ -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"
-   [ -n "$CHROOT_OUTPUT" ]      && echo "  chroot target:     $CHROOT_OUTPUT"
-   [ -n "$BUILD_OUTPUT" ]       && echo "  build target:      $BUILD_OUTPUT"
-   [ -n "$ISO_OUTPUT" ]         && echo "  ISO target:        $ISO_OUTPUT"
-   [ -n "$GRML_NAME" ]          && echo "  grml name:         $GRML_NAME"
-   [ -n "$RELEASENAME" ]        && echo "  release name:      $RELEASENAME"
-   [ -n "$DATE" ]               && echo "  build date:        $DATE"
-   [ -n "$VERSION" ]            && echo "  grml version:      $VERSION"
-   [ -n "$SUITE" ]              && echo "  Debian suite:      $SUITE"
-   [ -n "$ARCH" ]               && echo "  Architecture:      $ARCH"
-   [ -n "$BOOT_METHOD" ]        && echo "  Boot method:       $BOOT_METHOD"
-   [ -n "$TEMPLATE_DIRECTORY" ] && echo "  Template files:    $TEMPLATE_DIRECTORY"
-   [ -n "$CHROOT_INSTALL" ]     && echo "  Install files from directory to chroot:  $CHROOT_INSTALL"
-   [ -n "$FAI_ARGS" ]           && echo "  additional arguments for FAI: $FAI_ARGS"
-   [ -n "$LOGFILE" ]            && echo "  Logging to file:   $LOGFILE"
-   [ -n "$SQUASHFS_ZLIB" ]      && echo "  Using ZLIB (instead of LZMA) compression."
-   [ -n "$SQUASHFS_OPTIONS" ]   && echo "  Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
-   [ -n "$VERBOSE" ]            && echo "  Using VERBOSE mode."
-   [ -n "$UPDATE" ]             && echo "  Executing UPDATE instead of fresh installation."
-   [ -n "$SKIP_MKSQUASHFS" ]    && echo "  Skipping creation of SQUASHFS file."
-   [ -n "$SKIP_MKISOFS" ]       && echo "  Skipping creation of ISO file."
-   [ -n "$BUILD_ONLY" ]         && echo "  Executing BUILD_ONLY instead of fresh installation or UPDATE."
-   [ -n "$BUILD_DIRTY" ]        && echo "  Executing BUILD_DIRTY to leave chroot untouched."
+   [ -n "$CHROOT_OUTPUT" ]       && echo "  Chroot target:     $CHROOT_OUTPUT"
+   [ -n "$BUILD_OUTPUT" ]        && echo "  Build target:      $BUILD_OUTPUT"
+   [ -n "$ISO_OUTPUT" ]          && echo "  ISO target:        $ISO_OUTPUT"
+   [ -n "$GRML_NAME" ]           && echo "  Grml name:         $GRML_NAME"
+   [ -n "$RELEASENAME" ]         && echo "  Release name:      $RELEASENAME"
+   [ -n "$DATE" ]                && echo "  Build date:        $DATE"
+   [ -n "$VERSION" ]             && echo "  Grml version:      $VERSION"
+   [ -n "$SUITE" ]               && echo "  Debian suite:      $SUITE"
+   [ -n "$ARCH" ]                && echo "  Architecture:      $ARCH"
+   [ -n "$BOOT_METHOD" ]         && echo "  Boot method:       $BOOT_METHOD"
+   [ -n "$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
@@ -344,7 +340,30 @@ if [ -z "$FORCE" ] ; then
    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)]"
@@ -376,7 +395,7 @@ if [ -n "$MIRROR_DIRECTORY" ] ; 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*
-# 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
@@ -387,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*
-# 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
@@ -442,7 +461,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?)."
-      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
@@ -450,7 +469,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?)."
-      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
@@ -572,6 +591,25 @@ else
 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"
@@ -595,8 +633,8 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
             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
@@ -634,30 +672,45 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; 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
-         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
-               test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
+             test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
            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 # 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
 
-      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
-      # 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."
@@ -673,32 +726,60 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
       RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
 
-      sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
-      sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/grml-version
+      if [ -r "$BUILD_OUTPUT"/GRML/grml-version ] ; then
+         sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
+         sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/grml-version
+      fi
 
       # make sure the squashfs filename is set accordingly:
       SQUASHFS_NAME="$GRML_NAME.squashfs"
 
+      if [ -n "$NO_BOOTID" ] ; then
+         log   'Skipping bootid feature as requested via $NO_BOOTID.'
+         einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
+      else
+         [ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
+         [ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
+         einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
+         log   "Generating /conf/bootid.txt with entry ${BOOTID}."
+         echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
+         eend $?
+      fi
+
       # adjust all variables in the templates with the according distribution information
       for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
                   "${BUILD_OUTPUT}"/boot/grub/* ; do
-        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}"
+        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")"
-      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}"
@@ -713,6 +794,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"
+
+         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"
@@ -786,11 +872,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
-      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
 
+      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"/
@@ -863,7 +958,7 @@ else
          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.
+      # 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...
@@ -878,7 +973,7 @@ else
          else # neither -nolzma nor -z and mksquashfs-lzma is available:
             SQUASHFS_BINARY='mksquashfs-lzma'
 
-            # backwards compability: someone has squashfs-lzma-tools >=4 installed but
+            # 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
@@ -947,7 +1042,6 @@ else
       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
 
@@ -1043,6 +1137,13 @@ else
          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
@@ -1053,10 +1154,14 @@ else
          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
@@ -1089,10 +1194,59 @@ else
 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"
-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
 # }}}