Support EFI on 32-bit systems, increase EFI image size + switch from isohybrid to...
[grml-live.git] / grml-live
index 8040739..2e7aad7 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -71,6 +71,8 @@ Usage: $PN [options, see as follows]
    -U <username>           arrange output to be owned by specified username
    -v <version_number>     specify version number of the release
    -V                      increase verbosity in the build process
+   -w <date>               wayback machine, build system using Debian archives
+                           from specified date
    -z                      use ZLIB instead of LZMA/XZ compression
 
 Usage examples:
@@ -277,12 +279,12 @@ extend_string_end() {
 # This is because:
 #   * We assume that the chroot always has a "good" version of
 #     the file. Also it makes sources handling easier.
-#   * On unstable, we Recommend the Debian packages containing
+#   * On unstable, we recommend the Debian packages containing
 #     these files. The user can override them by putting his
 #     "better" version into the chroot.
-#   * On stable, the Debian packages are probably not available,
-#     or outdated, so we look in TEMPLATE_DIRECTORY/compat first, where
-#     our grml-live-compat package installs current file versions.
+#   * With older releases the Debian packages are probably
+#     not available, so we look in TEMPLATE_DIRECTORY/compat,
+#     where a (custom) package might install current file versions.
 copy_addon_file() {
   DEST="${BUILD_OUTPUT}/boot/$3"
   if [ ! -d "${DEST}/" ]; then
@@ -294,7 +296,7 @@ copy_addon_file() {
     return $?
   fi
   if [ -e "${TEMPLATE_DIRECTORY}/compat/$3/$1" ]; then
-    log   "Copying $1 from grml-live-compat"
+    log   "Copying $1 from ${TEMPLATE_DIRECTORY}/compat"
     cp "${TEMPLATE_DIRECTORY}/compat/$3/$1" "${DEST}/"
     return $?
   fi
@@ -311,7 +313,7 @@ copy_addon_file() {
 # }}}
 
 # command line parsing {{{
-while getopts "a:C:c:d:D:e:g:i:I:o:r:s:S:t:U:v:AbBFhnNqQuVz" opt; do
+while getopts "a:C:c:d:D:e:g:i:I:o:r:s:S:t:U:v:w:AbBFhnNqQuVz" opt; do
   case "$opt" in
     a) ARCH="$OPTARG" ;;
     A) CLEAN_ARTIFACTS=1 ;;
@@ -340,6 +342,7 @@ while getopts "a:C:c:d:D:e:g:i:I:o:r:s:S:t:U:v:AbBFhnNqQuVz" opt; do
     u) UPDATE=1 ;;
     U) CHOWN_USER="$OPTARG" ;;
     V) VERBOSE="-v" ;;
+    w) export WAYBACK_DATE="$OPTARG" ;;
     z) SQUASHFS_ZLIB=1 ;;
     ?) echo "invalid option -$OPTARG" >&2; usage; bailout 1 ;;
   esac
@@ -399,7 +402,7 @@ fi
 [ -n "$VERSION" ]                 || VERSION='0.0.1'
 
 # output specific stuff, depends on $OUTPUT (iff not set):
-[ -n "$OUTPUT" ]           || OUTPUT='/grml/grml-live'
+[ -n "$OUTPUT" ]           || OUTPUT="$PWD/grml/"
 [ -n "$BUILD_OUTPUT" ]     || BUILD_OUTPUT="$OUTPUT/grml_cd"
 [ -n "$CHROOT_OUTPUT" ]    || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
 [ -n "$ISO_OUTPUT" ]       || ISO_OUTPUT="$OUTPUT/grml_isos"
@@ -631,7 +634,11 @@ fi
 
 # generate nfsroot configuration for FAI on the fly
 if [ -z "$FAI_DEBOOTSTRAP" ] ; then
-  FAI_DEBOOTSTRAP="$SUITE http://ftp.debian.org/debian"
+  if [ -n "$WAYBACK_DATE" ] ; then
+    FAI_DEBOOTSTRAP="$SUITE http://snapshot.debian.org/archive/debian/$WAYBACK_DATE/"
+  else
+    FAI_DEBOOTSTRAP="$SUITE http://ftp.debian.org/debian"
+  fi
 fi
 
 if [ -z "$FAI_DEBOOTSTRAP_OPTS" ] ; then
@@ -693,7 +700,7 @@ else
       mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
 
       log "Executed FAI command line:"
-      log "BUILD_ONLY=$BUILD_ONLY BOOTSTRAP_ONLY=$BOOTSTRAP_ONLY GRML_LIVE_CONFIG=$CONFIGDUMP fai $VERBOSE -C $GRML_FAI_CONFIG -s file:///$GRML_FAI_CONFIG/config -c$CLASSES -u $HOSTNAME $FAI_ACTION $CHROOT_OUTPUT $FAI_ARGS"
+      log "BUILD_ONLY=$BUILD_ONLY BOOTSTRAP_ONLY=$BOOTSTRAP_ONLY GRML_LIVE_CONFIG=$CONFIGDUMP WAYBACK_DATE=$WAYBACK_DATE fai $VERBOSE -C $GRML_FAI_CONFIG -s file:///$GRML_FAI_CONFIG/config -c$CLASSES -u $HOSTNAME $FAI_ACTION $CHROOT_OUTPUT $FAI_ARGS"
       BUILD_ONLY="$BUILD_ONLY" BOOTSTRAP_ONLY="$BOOTSTRAP_ONLY" GRML_LIVE_CONFIG="$CONFIGDUMP" fai $VERBOSE \
                   -C "$GRML_FAI_CONFIG" -s "file:///$GRML_FAI_CONFIG/config" -c"$CLASSES" \
                   -u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
@@ -809,7 +816,7 @@ else
 <testsuite name="grml-live-missing-packages" tests="${package_count}" time="1" failures="${package_errors}" errors="${package_errors}" skipped="0" assertions="0">
 EOF
 
-  for package in $(awk '{print $1}' "${CHECKLOG}/package_errors.log") ; do
+  for package in $(awk '{print $1}' "${CHECKLOG}/package_errors.log" | sed 's;/;\\/;') ; do
     failure_reason="$(awk "/$package/ {print \$2}" "${CHECKLOG}/package_errors.log")"
     cat >> "${REPORT_MISSING_PACKAGES}" << EOF
   <testcase name="test_missing_packages_${package}" time="0" assertions="0">
@@ -884,13 +891,23 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
 
        # EFI boot files
        if [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootx64.efi" ] ; then
-          einfo "Moving EFI boot files into ISO path."
-          log "Moving EFI boot files into ISO path."
-          RC=$0
-          mv "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
-          mkdir -p "${BUILD_OUTPUT}/efi/boot/" || RC=$?
-          mv "${CHROOT_OUTPUT}/boot/bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi" || RC=$?
-          eend $?
+         einfo "Moving 64-bit EFI boot files into ISO path."
+         log "Moving 64-bit EFI boot files into ISO path."
+         RC=$0
+         mv "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
+         mkdir -p "${BUILD_OUTPUT}/efi/boot/" || RC=$?
+         mv "${CHROOT_OUTPUT}/boot/bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi" || RC=$?
+         eend $?
+       elif [ -r "${CHROOT_OUTPUT}/boot/efi.img" -a -r "${CHROOT_OUTPUT}/boot/bootia32.efi" ] ; then
+         einfo "Moving 32-bit EFI boot files into ISO path."
+         log "Moving 32-bit EFI boot files into ISO path."
+         RC=$0
+         mv "${CHROOT_OUTPUT}/boot/efi.img" "${BUILD_OUTPUT}/boot/" || RC=$?
+         mkdir -p "${BUILD_OUTPUT}/efi/boot/" || RC=$?
+         mv "${CHROOT_OUTPUT}/boot/bootia32.efi" "${BUILD_OUTPUT}/efi/boot/bootia32.efi" || RC=$?
+         eend $?
+       else
+         ewarn "No EFI boot files found, skipping." ; eend 0
        fi
 
        [ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
@@ -903,7 +920,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
        # copy _required_ isolinux files
        if [ -d "${CHROOT_OUTPUT}/usr/lib/ISOLINUX" ] ; then
          copy_addon_file isolinux.bin /usr/lib/ISOLINUX isolinux
-         for file in /usr/lib/syslinux/modules/bios/*.c32 ; do
+         for file in ${CHROOT_OUTPUT}/usr/lib/syslinux/modules/bios/*.c32 ; do
            copy_addon_file "$(basename "$file")"  /usr/lib/syslinux/modules/bios/ isolinux
          done
        else # syslinux versions <= 3:4.05+dfsg-6+deb8u1
@@ -928,7 +945,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
             log   "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
             ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
           else
-            # copy addons from system packages or grml-live-compat
+            # copy addons from system packages or grml-live-addons
             copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
             copy_addon_file pci.ids /usr/share/misc addons
             copy_addon_file memtest86+.bin /boot addons
@@ -992,10 +1009,14 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
        cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/
        cp -a "${CHROOT_OUTPUT}"/boot/grub/grub.img "${BUILD_OUTPUT}"/boot/grub/
 
-       # copy modules for UEFI grub
+       # copy modules for UEFI grub, 64-bit
        mkdir -p "${BUILD_OUTPUT}"/boot/grub/x86_64-efi/
        cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/x86_64-efi/*.{mod,lst} "${BUILD_OUTPUT}"/boot/grub/x86_64-efi/
 
+       # copy modules for UEFI grub, 32-bit
+       mkdir -p "${BUILD_OUTPUT}"/boot/grub/i386-efi/
+       cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/i386-efi/*.{mod,lst} "${BUILD_OUTPUT}"/boot/grub/i386-efi/
+
        if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
           log    "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
           eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
@@ -1270,6 +1291,9 @@ fi
 
 if [ "$BOOT_METHOD" = "isolinux" ] ; then
    BOOT_ARGS="-no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
+   if [ "$HYBRID_METHOD" = "isohybrid" ] ; then
+     EFI_ARGS="-isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -eltorito-alt-boot -e boot/efi.img -no-emul-boot -isohybrid-gpt-basdat"
+   fi
 elif [ "$BOOT_METHOD" = "grub2" ] ; then
    BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
 fi
@@ -1343,9 +1367,9 @@ else
          echo 1 16 | mksh "${SCRIPTS_DIRECTORY}/bootgrub.mksh" -B 11 | \
             dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
       fi
-      log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS -o ${ISO_OUTPUT}/${ISO_NAME} ."
+      log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J $BOOT_ARGS $EFI_ARGS -no-pad -o ${ISO_OUTPUT}/${ISO_NAME} ."
       $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
-              -l -r -J $BOOT_ARGS -no-pad \
+              -l -r -J $BOOT_ARGS $EFI_ARGS -no-pad \
               -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
       # both of these need core.img there, so it’s easier to write it here
       if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
@@ -1393,38 +1417,12 @@ else
           eend $?
         fi
       elif [ "$HYBRID_METHOD" = "isohybrid" ] ; then
-        if ! which isohybrid >/dev/null 2>&1 ; then
-          bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common/syslinux-utils"
-        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
-          if isohybrid --help | grep -q -- --uefi ; then
-            if echo $CLASSES | grep -qw I386 ; then
-              log   "Detected uefi support for isohybrid but 32bit systems do not support it, ignoring."
-              einfo "Detected uefi support for isohybrid but 32bit systems do not support it, ignoring."
-            else
-              log   "Detected uefi support for isohybrid, enabling"
-              einfo "Detected uefi support for isohybrid, enabling"
-              ISOHYBRID_OPTIONS=--uefi
-            fi
-          fi
-
-          log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
-          isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
-          eend $?
-        fi
+        : # nothing to do, handled via $MKISOFS $EFI_ARGS already
       else
         bailout 12 "Unknown HYBRID_METHOD [${HYBRID_METHOD}]. Supported values: disable, isohybrid, grub2, manifold"
       fi
 
-      # generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
+      # generate ISO checksums if we are using class 'RELEASE':
       case $CLASSES in *RELEASE*)
          [ "$RC" = 0 ] && \
          (
@@ -1433,6 +1431,10 @@ else
              touch -r ${ISO_NAME} ${ISO_NAME}.md5
              sha1sum ${ISO_NAME} > ${ISO_NAME}.sha1 && \
              touch -r ${ISO_NAME} ${ISO_NAME}.sha1
+             sha256sum ${ISO_NAME} > ${ISO_NAME}.sha256 && \
+             touch -r ${ISO_NAME} ${ISO_NAME}.sha256
+             sha512sum ${ISO_NAME} > ${ISO_NAME}.sha512 && \
+             touch -r ${ISO_NAME} ${ISO_NAME}.sha512
            fi
          )
          ;;
@@ -1513,6 +1515,8 @@ create_netbootpackage() {
     (
       cd $(dirname "${OUTPUT_FILE}")
       sha1sum $(basename "${OUTPUT_FILE}") > "${OUTPUT_FILE}.sha1"
+      sha256sum $(basename "${OUTPUT_FILE}") > "${OUTPUT_FILE}.sha256"
+      sha512sum $(basename "${OUTPUT_FILE}") > "${OUTPUT_FILE}.sha512"
     )
     einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0
     rm -rf "${OUTPUTDIR}"