SW: Remove salvage-ntfs from GRML_FULL (unmaintained upstream).
[grml-live.git] / grml-live
index b0a8f18..2fa022a 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.25'
+GRML_LIVE_VERSION='0.9.34-pre1'
 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,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
@@ -211,13 +212,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" ;;
@@ -244,6 +246,7 @@ 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'
@@ -316,6 +319,7 @@ if [ -z "$FORCE" ] ; then
    [ -n "$ISO_OUTPUT" ]         && echo "  ISO target:        $ISO_OUTPUT"
    [ -n "$GRML_NAME" ]          && echo "  grml name:         $GRML_NAME"
    [ -n "$RELEASENAME" ]        && echo "  release name:      $RELEASENAME"
    [ -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 "$VERSION" ]            && echo "  grml version:      $VERSION"
    [ -n "$SUITE" ]              && echo "  Debian suite:      $SUITE"
    [ -n "$ARCH" ]               && echo "  Architecture:      $ARCH"
@@ -438,7 +442,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
@@ -446,7 +450,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
@@ -511,8 +515,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:
@@ -568,6 +572,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" ] ; 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"
@@ -591,8 +614,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
@@ -634,7 +657,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
          einfo "Skipping installation boot addons requested via \$NO_ADDONS."
          eend 0
       else
          einfo "Skipping installation boot addons requested via \$NO_ADDONS."
          eend 0
       else
-         if ! [ -d /usr/share/grml-live/templates/boot/addons/bsd4grml ] ; then
+         if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
            ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
          else
            # copy only files so we can handle bsd4grml on its own
            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
@@ -670,7 +693,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
 
       sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
       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/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/grml-version
 
       # 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"
@@ -679,7 +702,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       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}"
       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/%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/%DISTRI_INFO%/$DISTRI_INFO/g"      "${file}"
         sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g"      "${file}"
         sed -i "s/%DISTRI_SPLASH%/$DISTRI_SPLASH/g"  "${file}"
@@ -696,6 +719,13 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "$BUILD_OUTPUT"/boot/isolinux/f4
       sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "$BUILD_OUTPUT"/boot/isolinux/f5
 
       sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "$BUILD_OUTPUT"/boot/isolinux/f4
       sed -i "s/%SQUASHFS_NAME%/$SQUASHFS_NAME/" "$BUILD_OUTPUT"/boot/isolinux/f5
 
+      # generate addon list
+      rm "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+      for name in $(ls "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg) ; do
+        include_name=$(basename "$name")
+        echo "include $include_name"  >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
+      done
+
       if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
          log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
          echo "include grmlmain.cfg"    >  "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
       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"
@@ -748,12 +778,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
@@ -761,15 +788,20 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
             GRUB_VERSION=1
          fi
 
             GRUB_VERSION=1
          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
 
          sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
       fi
          done
 
          sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
       fi
+
       if [ -e "$BUILD_OUTPUT"/boot/grub/$GRUB_LEGACY ]; then
          sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/menu.lst
          sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/grub.cfg
       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
@@ -975,7 +1007,7 @@ 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
 
 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
@@ -1030,6 +1062,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
@@ -1040,10 +1079,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
@@ -1078,8 +1121,8 @@ 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]"
+einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
+log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
 bailout 0
 # }}}
 
 bailout 0
 # }}}