SW: add mbuffer to GRML_FULL
[grml-live.git] / grml-live
index 8d2d024..a0333e2 100755 (executable)
--- a/grml-live
+++ b/grml-live
@@ -337,6 +337,19 @@ adjust_boot_files() {
     exit 1
   fi
 
+  local release_info
+  if [ -n "${RELEASE_INFO:-}" ] ; then
+    release_info="${RELEASE_INFO}"
+  else
+    ewarn "Variable RELEASE_INFO is unset, applying fallback for usage in adjust_boot_files." ; eend 1
+    release_info="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
+  fi
+
+  # ensure this has a specific length
+  local fixed_release_info
+  fixed_release_info="$(cut_string 68 "$release_info")"
+  fixed_release_info="$(extend_string_end 68 "$fixed_release_info")"
+
   for file in "$@" ; do
     if [ -r "${file}" ] && [ -f "${file}" ] ; then
       sed -i "s/%ARCH%/$ARCH/g"                    "${file}"
@@ -346,7 +359,7 @@ adjust_boot_files() {
       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/%RELEASE_INFO%/$fixed_release_info/g" "${file}"
       sed -i "s/%SHORT_NAME%/$SHORT_NAME/g"        "${file}"
       sed -i "s/%VERSION%/$VERSION/g"              "${file}"
       if [ -n "${BOOT_FILE}" ] ; then
@@ -448,6 +461,7 @@ fi
 [ -n "$HYBRID_METHOD" ]           || HYBRID_METHOD='isohybrid'
 [ -n "$RELEASENAME" ]             || RELEASENAME='grml-live rocks'
 [ -n "$SECURE_BOOT" ]             || SECURE_BOOT='disable'
+[ -n "$SQUASHFS_BINARY" ]         || SQUASHFS_BINARY='mksquashfs'
 [ -n "$SQUASHFS_EXCLUDES_FILE" ]  || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
 [ -n "$SUITE" ]                   || SUITE='testing'
 [ -n "$TEMPLATE_DIRECTORY" ]      || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
@@ -974,7 +988,7 @@ grub_setup() {
           ;;
         *)
           log   "Secure Boot method '${SECURE_BOOT}' is unsupported."
-          error "Secure Boot method '${SECURE_BOOT}' is unsupported." ; eend 1
+          eerror "Secure Boot method '${SECURE_BOOT}' is unsupported." ; eend 1
           bailout 59
           ;;
       esac
@@ -1015,6 +1029,10 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
     mkdir -p "$BUILD_OUTPUT"/boot/isolinux
     mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
 
+    # this is a variable we're using for adjusting boot templates, not only in
+    # adjust_boot_files though, so set here
+    RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
+
     # 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)"
@@ -1132,6 +1150,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
 
         # copy addons from system packages or grml-live-addons
         copy_addon_file ipxe.lkrn /usr/lib/ipxe addons
+        copy_addon_file ipxe.efi /usr/lib/ipxe addons
         copy_addon_file pci.ids /usr/share/misc addons
         copy_addon_file memtest86+.bin /boot addons
 
@@ -1213,18 +1232,22 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
     mkdir -p "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
     cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/
 
-    # adjust boot splash information:
-    RELEASE_INFO="$GRML_NAME $VERSION - Release Codename $RELEASENAME"
-    RELEASE_INFO="$(cut_string 68 "$RELEASE_INFO")"
-    RELEASE_INFO="$(extend_string_end 68 "$RELEASE_INFO")"
-
     if [ -r "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version ] ; then
-      sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
-      sed -i "s/%DATE%/$DATE/"                                      "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
+      sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/" "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
+      sed -i "s/%DATE%/$DATE/"                 "$BUILD_OUTPUT"/GRML/"${GRML_NAME}"/grml-version
     fi
 
     # make sure the squashfs filename is set accordingly:
     SQUASHFS_NAME="$GRML_NAME.squashfs"
+    # adjust bootsplash accordingly but make sure the string has the according length
+    fixed_squashfs_name="$(cut_string 20 "$SQUASHFS_NAME")"
+    fixed_squashfs_name="$(extend_string_end 20 "$fixed_squashfs_name")"
+    for file in f4 f5 ; do
+      if [ -r "${BUILD_OUTPUT}/boot/isolinux/${file}" ] ; then
+        sed -i "s/%SQUASHFS_NAME%/${fixed_squashfs_name}/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
+        sed -i "s/%SQUASHFS_NAME%/${fixed_squashfs_name}/" "${BUILD_OUTPUT}/boot/isolinux/${file}"
+      fi
+    done
 
     # adjust all variables in the templates with the according distribution information
     adjust_boot_files "${BUILD_OUTPUT}"/boot/isolinux/*.cfg \
@@ -1239,16 +1262,6 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
       done
     done
 
-    # adjust bootsplash accordingly but make sure the string has the according length
-    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 -f "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
     for name in "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg ; do
@@ -1316,7 +1329,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
     fi
 
     if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
-      sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
+      sed -i "s/%RELEASE_INFO%/$RELEASE_INFO/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
     fi
 
     DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
@@ -1368,11 +1381,6 @@ else
    # make sure we don't leave (even an empty) base.tgz:
    [ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
 
-   # if unconfigured default to squashfs-tools' mksquashfs binary
-   if [ -z "$SQUASHFS_BINARY" ] ; then
-      SQUASHFS_BINARY='mksquashfs'
-   fi
-
    if which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
       log    "Using mksquashfs binary ${SQUASHFS_BINARY}"
       einfo  "Using mksquashfs binary ${SQUASHFS_BINARY}" ; eend 0
@@ -1384,8 +1392,8 @@ else
 
    # use sane defaults if $SQUASHFS_OPTIONS isn't set
    if [ -z "$SQUASHFS_OPTIONS" ] ; then
-     # use blocksize 256k as this gives best result with regards to time + compression
-     SQUASHFS_OPTIONS="-b 256k"
+     # use block size 1m as this gives good result with regards to time + compression
+     SQUASHFS_OPTIONS="-b 1m"
 
      # set lzma/xz compression by default, unless -z option has been specified on command line
      if [ -z "$SQUASHFS_ZLIB" ] ; then
@@ -1439,6 +1447,65 @@ if [ -z "$BOOTSTRAP_ONLY" ] ; then
 fi
 # }}}
 
+# information how the ISO was generated {{{
+# shellcheck disable=SC2034
+generate_build_info() {
+  jo -p \
+    boot_method="${BOOT_METHOD}" \
+    bootstrap_only="${BOOTSTRAP_ONLY}" \
+    build_date="${DATE}" \
+    build_dirty="${BUILD_DIRTY}" \
+    build_only="${BUILD_ONLY}" \
+    chroot_install="${CHROOT_INSTALL}" \
+    classes="${CLASSES}" \
+    clean_artifacts="${CLEAN_ARTIFACTS}" \
+    default_bootoptions="${DEFAULT_BOOTOPTIONS}" \
+    distri_info="${DISTRI_INFO}" \
+    distri_name="${DISTRI_NAME}" \
+    extract_iso_name="${EXTRACT_ISO_NAME}" \
+    fai_cmdline="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}" \
+    fai_version="$(fai --help 2>/dev/null | head -1 | awk '{print $2}' | sed 's/\.$//' || true)" \
+    grml_architecture="${ARCH}" \
+    grml_bootid="${BOOTID}" \
+    grml_build_output="${BUILD_OUTPUT}" \
+    grml_chroot_output="${CHROOT_OUTPUT}" \
+    grml_debian_version="${SUITE}" \
+    grml_iso_name="${ISO_NAME}" \
+    grml_iso_output="${ISO_OUTPUT}" \
+    grml_live_cmdline="${CMDLINE}" \
+    grml_live_config_file="${LIVE_CONF}" \
+    grml_live_scripts_directory="${SCRIPTS_DIRECTORY}" \
+    grml_live_template_directory="${TEMPLATE_DIRECTORY}" \
+    grml_live_version="${GRML_LIVE_VERSION}" \
+    grml_local_config="${LOCAL_CONFIG}" \
+    grml_name="${GRML_NAME}" \
+    grml_short_name="${SHORT_NAME}" \
+    grml_username="${USERNAME}" \
+    grml_version="${VERSION}" \
+    host_architecture="$(dpkg --print-architecture || true)" \
+    host_debian_version="$(cat /etc/debian_version 2>/dev/null || true)" \
+    host_kernel_version="$(uname -a)" \
+    hybrid_method="${HYBRID_METHOD}" \
+    mkisofs_cmdline="${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_version="$(${MKISOFS} --version 2>/dev/null | head -1 || true)" \
+    mksquashfs_cmdline="${SQUASHFS_BINARY} ${CHROOT_OUTPUT}/ ${BUILD_OUTPUT}/live/${GRML_NAME}/${GRML_NAME}.squashfs -noappend ${SQUASHFS_OPTIONS}" \
+    mksquashfs_version="$(${SQUASHFS_BINARY} -version | head -1 || true)" \
+    output_owner="${CHOWN_USER}" \
+    release_info="${RELEASE_INFO}" \
+    release_name="${RELEASENAME}" \
+    secure_boot="${SECURE_BOOT}" \
+    skip_mkisofs="${SKIP_MKISOFS}" \
+    skip_mksquashfs_="${SKIP_MKSQUASHFS}" \
+    skip_netboot="${SKIP_NETBOOT}" \
+    squashfs_name="${SQUASHFS_NAME}" \
+    template_directory="${TEMPLATE_DIRECTORY}" \
+    timestamp="$(TZ=UTC date +%s)" \
+    update_only="${UPDATE}" \
+    wayback_date="${WAYBACK_DATE}" \
+  --
+}
+# }}}
+
 # ISO_OUTPUT - mkisofs {{{
 [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
 [ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
@@ -1521,10 +1588,27 @@ else
          echo 1 16 | mksh "${SCRIPTS_DIRECTORY}/bootgrub.mksh" -B 11 | \
             dd of=boot/grub/toriboot.bin conv=notrunc 2>/dev/null
       fi
+
+      log   "Generating build information in conf/buildinfo.json"
+      einfo "Generating build information in conf/buildinfo.json"
+      mkdir -p conf/
+      generate_build_info > conf/buildinfo.json
+      eend $?
+
       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} ."
+      einfo "Generating ISO file..."
       $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
               -l -r -J $BOOT_ARGS $EFI_ARGS -no-pad \
               -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
+      eend $RC
+
+      # do not continue on errors, otherwise we might generate/overwrite the ISO with dd if=... stuff
+      if [ "$RC" != 0 ] ; then
+        log    "Error: critical error while generating ISO [exit code ${RC}]. Exiting."
+        eerror "Error: critical error while generating ISO [exit code ${RC}]. Exiting." ; eend 1
+        bailout $RC
+      fi
+
       # both of these need core.img there, so it’s easier to write it here
       if [ "$BOOT_METHOD" = "grub2" ] || [ "$HYBRID_METHOD" = "grub2" ]; then
          # must be <= 30720 bytes
@@ -1581,14 +1665,8 @@ else
          [ "$RC" = 0 ] && \
          (
            if cd $ISO_OUTPUT ; then
-             md5sum ${ISO_NAME} > ${ISO_NAME}.md5 && \
-             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
          )
          ;;
@@ -1610,7 +1688,7 @@ fi
 
 # netboot package {{{
 create_netbootpackage() {
-  local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2"
+  local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar"
 
   if [ -f "${OUTPUT_FILE}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
     log   "Skipping stage 'netboot' as $OUTPUT_FILE exists already."
@@ -1665,12 +1743,57 @@ create_netbootpackage() {
     eoutdent
   fi
 
-  if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
+  # don't include shim + grubnetx64 + grub files in i386 netboot packages,
+  # as those don't make much sense there
+  if [ "$ARCH" = amd64 ] ; then
+    if ! [ -r "${BUILD_OUTPUT}/boot/grub/netboot.cfg" ] ; then
+      log   "File ${BUILD_OUTPUT}/boot/grub/netboot.cfg not found."
+      ewarn "File ${BUILD_OUTPUT}/boot/grub/netboot.cfg not found."
+      eindent
+      log   "Hint: Are you using custom templates which do not provide grub.cfg?"
+      ewarn "Hint: Are you using custom templates which do not provide grub.cfg?" ; eend 0
+      eoutdent
+    else
+      cp "${BUILD_OUTPUT}/boot/grub/netboot.cfg" "${WORKING_DIR}/grub.cfg"
+      adjust_boot_files "${WORKING_DIR}/grub.cfg"
+
+      if [ -r "${CHROOT_OUTPUT}"/usr/lib/shim/shimx64.efi.signed ] ; then
+        log "Installing ${CHROOT_OUTPUT}/usr/lib/shim/shimx64.efi.signed as shim.efi in netboot package"
+        cp "${CHROOT_OUTPUT}"/usr/lib/shim/shimx64.efi.signed "${WORKING_DIR}"/shim.efi
+      elif [ -r "${CHROOT_OUTPUT}"/usr/lib/shim/shimx64.efi ] ; then
+        log "Installing ${CHROOT_OUTPUT}/usr/lib/shim/shimx64.efi as shim.efi in netboot package"
+        cp "${CHROOT_OUTPUT}"/usr/lib/shim/shimx64.efi "${WORKING_DIR}"/shim.efi
+      else
+        log   "No shimx64.efi for usage with PXE boot found (shim-signed not present?)"
+        ewarn "No shimx64.efi for usage with PXE boot found (shim-signed not present?)" ; eend 0
+      fi
+
+      if [ -r "${CHROOT_OUTPUT}"/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed ] ; then
+        log "Installing /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed as grubx64.efi in netboot package"
+        cp "${CHROOT_OUTPUT}"/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed "${WORKING_DIR}"/grubx64.efi
+      elif [ -r "${CHROOT_OUTPUT}"/usr/lib/grub/x86_64-efi/monolithic/grubnetx64.efi ] ; then
+        log "Installing /usr/lib/grub/x86_64-efi/monolithic/grubnetx64.efi as grubx64.efi in netboot package"
+        cp "${CHROOT_OUTPUT}"/usr/lib/grub/x86_64-efi/monolithic/grubnetx64.efi "${WORKING_DIR}"/grubx64.efi
+      else
+        log   "No grubnetx64.efi for usage with PXE boot found (grub-efi-amd64-signed not present?)"
+        ewarn "No grubnetx64.efi for usage with PXE boot found (grub-efi-amd64-signed not present?)." ; eend 0
+      fi
+
+      if [ -r "${CHROOT_OUTPUT}"/usr/share/grub/unicode.pf2 ] ; then
+        log "Installing ${CHROOT_OUTPUT}/usr/share/grub/unicode.pf2 as grub/fonts/unicode.pf2 in netboot package"
+        mkdir -p "${WORKING_DIR}"/grub/fonts/
+        cp "${CHROOT_OUTPUT}"/usr/share/grub/unicode.pf2 "${WORKING_DIR}"/grub/fonts/
+      else
+        log   "No unicode.pf2 for usage with PXE boot found (grub-common not present?)"
+        ewarn "No unicode.pf2 for usage with PXE boot found (grub-common not present?)" ; eend 0
+      fi
+    fi
+  fi
+
+  if tar -C "$OUTPUTDIR" -cf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then
     (
       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}"