X-Git-Url: http://git.grml.org/?p=grml-live.git;a=blobdiff_plain;f=grml-live;h=020e48335531896f1d30c13606aabf30fabeef53;hp=73ee61b607a7fbfe263f6d63f472c1d6439ef55e;hb=d501c11085b6c048bf9f4bd186f5ac8d267b9ff6;hpb=769010633b88c8d6e5912fc02f46a6582f9598b7 diff --git a/grml-live b/grml-live index 73ee61b..020e483 100755 --- a/grml-live +++ b/grml-live @@ -23,8 +23,10 @@ fi # disable for now since it seems to cause some problems # set -e +# The line following this line is patched by debian/rules. +GRML_LIVE_VERSION='***UNRELEASED***' + # global variables -GRML_LIVE_VERSION='0.16.1' PN="$(basename $0)" CMDLINE="$0 $@" ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg' @@ -39,13 +41,14 @@ $PN - build process script for generating a (grml based) Linux Live-ISO Usage: $PN [options, see as follows] -a architecture; available values: i386 and amd64 - -A ensure clean build and pack artifacts + -A clean build directories before and after running -b build the ISO without updating the chroot via FAI -B build the ISO without touching the chroot (skips cleanup) -c classes to be used for building the ISO via FAI -C configuration file for grml-live -d use specified date instead of build time as date of release -D use specified configuration directory instead of /etc/grml/fai + -e extract ISO and squashfs contents from iso_name -F force execution without prompting -g set the grml flavour name -h display short usage information and exit @@ -56,6 +59,7 @@ Usage: $PN [options, see as follows] -N bootstrap (build chroot) only, do not create files for ISO -o main output directory of the build process -q skip mksquashfs + -Q skip netboot package build -r release name -s Debian suite; values: etch, lenny, squeeze, sid -t place of the templates @@ -118,6 +122,8 @@ BUILD_ONLY='' BUILD_DIRTY='' BOOTSTRAP_ONLY='' HOSTNAME='' +USERNAME='' +CONFIGDUMP='' # don't use colors/escape sequences if [ -r /lib/lsb/init-functions ] ; then @@ -144,6 +150,7 @@ LIVE_CONF=/etc/grml/grml-live.conf # umount all directories {{{ umount_all() { # make sure we don't leave any mounts - FAI doesn't remove them always + umount $CHROOT_OUTPUT/proc/sys/fs/binfmt_misc 2>/dev/null || /bin/true umount $CHROOT_OUTPUT/proc 2>/dev/null || /bin/true umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true @@ -163,11 +170,12 @@ umount_all() { bailout() { rm -f /var/run/fai/fai_softupdate_is_running \ /var/run/fai/FAI_INSTALLATION_IN_PROGRESS + [ -n "$CONFIGDUMP" ] && rm -f "$CONFIGDUMP" [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR" umount_all [ -n "$1" ] && EXIT="$1" || EXIT="1" [ -n "$2" ] && eerror "$2">&2 - if [ -n "$PACK_ARTIFACTS" ]; then + if [ -n "$CLEAN_ARTIFACTS" ]; then log "Cleaning up" einfo "Cleaning up" [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}" @@ -182,7 +190,7 @@ bailout() { [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_OUTPUT}" [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${ISO_OUTPUT}" [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && chown -R "${CHOWN_USER}:" "${LOG_OUTPUT}" - [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && chown -R "${CHOWN_USER}:" "${CHROOT_ARCHIVE}" + [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && chown -R "${CHOWN_USER}:" "${NETBOOT}" eend 0 fi log "------------------------------------------------------------------------------" @@ -282,39 +290,26 @@ copy_addon_file() { } # }}} -# read local (non-packaged) configuration {{{ -LOCAL_CONFIG=/etc/grml/grml-live.local -if [ -r "$LOCAL_CONFIG" ] ; then - . $LOCAL_CONFIG -else - LOCAL_CONFIG='' -fi - -if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then - eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated." - ewarn "Please set up ${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead." - bailout 1 -fi -# }}} - # command line parsing {{{ -while getopts "a:C:c:d:D:g:i:I:o:r:s:t:U:v:AbBFnNquVz" opt; do +while getopts "a:C:c:d:D:e:g:i:I:o:r:s:t:U:v:AbBFnNqQuVz" opt; do case "$opt" in a) ARCH="$OPTARG" ;; - A) PACK_ARTIFACTS=1 ;; + A) CLEAN_ARTIFACTS=1 ;; b) BUILD_ONLY=1 ;; B) BUILD_DIRTY=1 ;; c) CLASSES="$OPTARG" ;; - C) CONFIG="$OPTARG" ;; + C) LOCAL_CONFIG="$(readlink -f $OPTARG)" ;; d) DATE="$OPTARG" ;; - D) GRML_FAI_CONFIG="$OPTARG" ;; + D) GRML_FAI_CONFIG="$(readlink -f $OPTARG)" ;; + e) EXTRACT_ISO_NAME="$(readlink -f $OPTARG)" ;; g) GRML_NAME="$OPTARG" ;; i) ISO_NAME="$OPTARG" ;; I) CHROOT_INSTALL="$OPTARG" ;; n) SKIP_MKISOFS=1 ;; N) BOOTSTRAP_ONLY=1; SKIP_MKISOFS=1; SKIP_MKSQUASHFS=1 ;; - o) OUTPUT="$OPTARG" ;; + o) OUTPUT="$(readlink -f $OPTARG)" ;; q) SKIP_MKSQUASHFS=1 ;; + Q) SKIP_NETBOOT=1 ;; r) RELEASENAME="$OPTARG" ;; s) SUITE="$OPTARG" ;; t) TEMPLATE_DIRECTORY="$OPTARG";; @@ -330,6 +325,31 @@ done shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter # }}} +# read local (non-packaged) configuration {{{ +if [ -z "$LOCAL_CONFIG" ]; then + if [ -r "/etc/grml/grml-live.local" ]; then + LOCAL_CONFIG="/etc/grml/grml-live.local" + fi +fi +if [ -n "$LOCAL_CONFIG" ]; then + if [ -r "$LOCAL_CONFIG" ]; then + . $LOCAL_CONFIG + else + eerror "Could not read specified local configuration file \"$LOCAL_CONFIG\"." + bailout 1 + fi + LOCAL_CONFIG=$(readlink -f "$LOCAL_CONFIG") +else + LOCAL_CONFIG='' +fi + +if [ -n "${GRML_LIVE_SOURCES:-}" ] ; then + eerror "Config variable \$GRML_LIVE_SOURCES is set. This variable has been deprecated." + ewarn "Please set up \${GRML_FAI_CONFIG}/config/files/etc/apt/sources.list.d/* instead." + bailout 1 +fi +# }}} + # assume sane defaults (if not set already) {{{ [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)" [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux' @@ -355,9 +375,10 @@ shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter [ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live' [ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd" [ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot" -[ -n "$CHROOT_ARCHIVE" ] || CHROOT_ARCHIVE="$OUTPUT/$(basename $CHROOT_OUTPUT).tgz" [ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos" [ -n "$LOG_OUTPUT" ] || LOG_OUTPUT="$OUTPUT/grml_logs" +[ -n "$REPORTS" ] || REPORTS="${LOG_OUTPUT}/reports/" +[ -n "$NETBOOT" ] || NETBOOT="${OUTPUT}/netboot/" # }}} # some misc checks before executing FAI {{{ @@ -391,10 +412,10 @@ 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" + [ -n "$LOCAL_CONFIG" ] && echo " Configuration: $LOCAL_CONFIG" [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG" echo " main directory: $OUTPUT" + [ -n "$EXTRACT_ISO_NAME" ] && echo " Extract ISO: $EXTRACT_ISO_NAME" [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT" [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT" [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT" @@ -417,12 +438,13 @@ if [ -z "$FORCE" ] ; then [ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA/XZ) compression." [ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}" [ -n "$VERBOSE" ] && echo " Using VERBOSE mode." - [ -n "$PACK_ARTIFACTS" ] && echo " Will prepare packed artifacts and ensure clean build." + [ -n "$CLEAN_ARTIFACTS" ] && echo " Will clean output before and after running." [ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation." if [ -n "$BOOTSTRAP_ONLY" ] ; then echo " Bootstrapping only and not building (files for) ISO." else [ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file." + [ -n "$SKIP_NETBOOT" ] && echo " Skipping creation of NETBOOT package." [ -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." @@ -438,13 +460,13 @@ fi # }}} # clean up before start {{{ -if [ -n "${PACK_ARTIFACTS}" ]; then +if [ -n "${CLEAN_ARTIFACTS}" ]; then echo "Wiping old artifacts" [ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}" [ -n "${BUILD_OUTPUT}" -a -d "${BUILD_OUTPUT}" ] && rm -r "${BUILD_OUTPUT}" [ -n "${ISO_OUTPUT}" -a -d "${ISO_OUTPUT}" ] && rm -r "${ISO_OUTPUT}" [ -n "${LOG_OUTPUT}" -a -d "${LOG_OUTPUT}" ] && rm -r "${LOG_OUTPUT}" - [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}" + [ -n "${NETBOOT}" -a -d "${NETBOOT}" ] && rm -r "${NETBOOT}" fi # }}} @@ -492,15 +514,49 @@ fi start_seconds=$(cut -d . -f 1 /proc/uptime) log "------------------------------------------------------------------------------" log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)" -if [ -n "$LOCAL_CONFIG" ]; then - log "Using local config file: $LOCAL_CONFIG" -fi +log "Using local config file: $LOCAL_CONFIG" log "Executed grml-live command line:" log "$CMDLINE" einfo "Logging actions to logfile $LOGFILE" # }}} +# dump config variables into file, for script access {{{ +CONFIGDUMP=$(mktemp) +set | egrep \ + '^(GRML_NAME|RELEASENAME|DATE|VERSION|SUITE|ARCH|DISTRI_NAME|USERNAME|HOSTNAME|APT_PROXY)=' \ + > ${CONFIGDUMP} +# }}} + +# unpack iso/squashfs {{{ +extract_iso() { +if [ -n "$EXTRACT_ISO_NAME" ]; then + log "Unpacking ISO from ${EXTRACT_ISO_NAME}" + einfo "Unpacking ISO from ${EXTRACT_ISO_NAME}" + local mountpoint=$(mktemp -d) + local rc=0 + mount -o loop "${EXTRACT_ISO_NAME}" "$mountpoint" ; rc=$? + if [ "$rc" != 0 ]; then + rmdir "$mountpoint" + log "mount failed" + eerror "mount failed" + eend 1 + bailout 1 + fi + unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*.squashfs ; rc=$? + umount "$mountpoint" + rmdir "$mountpoint" + if [ "$rc" != 0 ]; then + log "unsquashfs failed" + eerror "unsquashfs failed" + eend 1 + bailout 1 + fi +fi +} +extract_iso +# }}} + # on-the-fly configuration {{{ if [ -n "$FAI_DEBOOTSTRAP" ] ; then sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF" @@ -514,7 +570,7 @@ case $SUITE in esac export SUITE # make sure it's available in FAI scripts -for file in "$LIVE_CONF" "$CONFIG" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do +for file in "$LIVE_CONF" "$LOCAL_CONFIG" "$NFSROOT_CONF" ; do if [ -n "$file" ] ; then sed "s|^FAI_DEBOOTSTRAP=\"[a-z]* |FAI_DEBOOTSTRAP=\"$SUITE |" "$file" | sponge "$file" fi @@ -594,8 +650,8 @@ else echo force-unsafe-io > "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io" log "Executed FAI command line:" - log "BUILD_ONLY=$BUILD_ONLY BOOTSTRAP_ONLY=$BOOTSTRAP_ONLY 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" fai $VERBOSE \ + 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" + 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 RC="$PIPESTATUS" # notice: bash-only @@ -608,24 +664,6 @@ else 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 - einfo "Setting /etc/grml_version to $GRML_NAME $VERSION Release Codename $RELEASENAME [$DATE]" - 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 initramfs, iterate over all - # present kernel versions (note: we can't really handle more than one - # kernel version anyway right now) - # chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :( - for initrd in "$(basename $CHROOT_OUTPUT/boot/vmlinuz-*)" ; do - if ! chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -c ; then - einfo "Creating fresh initrd did not work, trying update instead:" - log "Creating fresh initrd did not work, trying update instead:" - chroot $CHROOT_OUTPUT update-initramfs -k "${initrd##vmlinuz-}" -u - fi - done - eend $? fi # move fai logs into grml_logs directory @@ -672,20 +710,78 @@ 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 [ -r "$CHECKLOG/dpkg.selections" ] ; then + package_count=$(wc -l "$CHECKLOG/dpkg.selections" | awk '{print $1}') +else + package_count="unknown" +fi - 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 +mkdir -p "$REPORTS" +REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml" + +# check for missing packages +if ! [ -s "$CHECKLOG/package_errors.log" ] ; then + einfo "No missing packages found, generating empty junit report." + + cat > "${REPORT_MISSING_PACKAGES}" << EOF + + + + + + + + + +EOF + eend 0 +else + einfo "Missing packages found, generating junit report." + + if [ -r "$CHECKLOG/package_errors.log" ] ; then + package_errors=$(wc -l "$CHECKLOG/package_errors.log" | awk '{print $1}') + else + package_errors="unknown" + fi + + mkdir -p "$REPORTS" + REPORT_MISSING_PACKAGES="${REPORTS}/TEST-MissingPackages.xml" + + cat > "${REPORT_MISSING_PACKAGES}" << EOF + + +EOF + + for package in $(awk '{print $5}' "${CHECKLOG}/package_errors.log" | sed 's/\.$//') ; do + cat >> "${REPORT_MISSING_PACKAGES}" << EOF + + +Package $package is missing in chroot + + +EOF + done + + cat >> "${REPORT_MISSING_PACKAGES}" << EOF + + + + + +EOF + eend 0 + + 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 # }}} @@ -711,7 +807,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then # 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_NAME}"/initrd.gz + cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.img find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \; else log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" @@ -721,7 +817,7 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then 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_NAME}"/linux26 + cp "$KERNEL_IMAGE" "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/vmlinuz else log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1 @@ -787,29 +883,14 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then mkdir -p "${BUILD_OUTPUT}/boot/grub" fi - cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/ + cp -a ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/ - if [ -e ${TEMPLATE_DIRECTORY}/compat/grub/linux.mod ]; then - cp "${TEMPLATE_DIRECTORY}"/compat/grub/* "${BUILD_OUTPUT}"/boot/grub/ - else - if ! which "grub-mkimage" >/dev/null 2>&1 ; then - log "grub-mkimage not found, skipping Grub step therefore." ; eend 0 - ewarn "grub-mkimage not found, skipping Grub step therefore." - ewarn "Please install grub-pc-bin or grub-common >= 1.98+20100804-14." ; eend 0 - elif ! grub-mkimage --help | grep -q -- --format ; then - log "grub-mkimage does not support --format=i386-pc, skipping Grub step therefore." ; eend 0 - ewarn "grub-mkimage does not support --format=i386-pc, skipping Grub step therefore." - ewarn "Please install grub-common >= 1.98+20100804-14 or grub-pc-bin." ; eend 0 - else - # copy system grub files if grml-live-compat is not installed - cp -a /usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/ - cp -a /usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/ - cp -a /usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/ - cp -a /usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/ - grub-mkimage -d /usr/lib/grub/*-pc -o \ - "${BUILD_OUTPUT}/boot/grub/core.img" biosdisk iso9660 --format=i386-pc - fi - fi + # copy grub files from target + cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.mod "${BUILD_OUTPUT}"/boot/grub/ + cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.o "${BUILD_OUTPUT}"/boot/grub/ + cp -a "${CHROOT_OUTPUT}"/usr/lib/grub/*-pc/*.lst "${BUILD_OUTPUT}"/boot/grub/ + cp -a "${CHROOT_OUTPUT}"/usr/share/grub/ascii.pf2 "${BUILD_OUTPUT}"/boot/grub/ + cp -a "${CHROOT_OUTPUT}"/boot/grub/core.img "${BUILD_OUTPUT}"/boot/grub/ if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." @@ -870,6 +951,14 @@ if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then fi done + for param in ARCH DATE DISTRI_INFO DISTRI_NAME DISTRI_SPLASH GRML_NAME SQUASHFS_NAME \ + RELEASE_INFO SHORT_NAME VERSION ; do + for file in $(find "${BUILD_OUTPUT}" -name "*%$param%*") ; do + value="$(eval echo '$'"$param")" + mv ${file} ${file/\%${param}\%/$value} + done + 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")" @@ -1102,17 +1191,63 @@ else 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 + # support xorriso as well mkisofs and genisoimage + if which xorriso >/dev/null 2>&1 ; then + MKISOFS='xorriso -as mkisofs' + elif which mkisofs >/dev/null 2>&1; then MKISOFS='mkisofs' elif which genisoimage >/dev/null 2>&1; then MKISOFS='genisoimage' else - log "Error: neither mkisofs nor genisoimage available - can not create ISO." - eerror "Error: neither mkisofs nor genisoimage available - can not create ISO." ; eend 1 + log "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." + eerror "Error: neither xorriso nor mkisofs nor genisoimage available - can not create ISO." ; eend 1 bailout fi + case "$ARCH" in + amd64) + # using -eltorito-alt-boot is limited to xorriso for now + case "$MKISOFS" in + xorriso*) + einfo "Using xorriso for ISO generation." ; eend 0 + eindent + + if ! dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-1 ; then + log "Disabling (U)EFI boot support since xorriso version is not recent enough." + ewarn "Disabling (U)EFI boot support since xorriso version is not recent enough." ; eend 0 + else + log "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support." + einfo "xorriso with -eltorito-alt-boot present, enabling (U)EFI boot support." ; eend 0 + + if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" ] ; then + einfo "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO." + log "Found /var/lib/grml_live_efi.img - moving to /boot/efi.img for ISO." + mv "${CHROOT_OUTPUT}/var/lib/grml_live_efi.img" "${BUILD_OUTPUT}/boot/efi.img" + eend $? + fi + + if [ -r "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" ] ; then + einfo "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO" + log "Found /var/lib/grml_live_bootx64.efi - moving to /efi/boot/bootx64.efi for ISO" + mkdir -p "${BUILD_OUTPUT}/efi/boot/" + mv "${CHROOT_OUTPUT}/var/lib/grml_live_bootx64.efi" "${BUILD_OUTPUT}/efi/boot/bootx64.efi" + eend $? + fi + + if [ -r "${BUILD_OUTPUT}"/boot/efi.img ] ; then + einfo "/boot/efi.img found and amd64 architecture present, extending boot arguments." + log "/boot/efi.img found and amd64 architecture present, extending boot arguments." + BOOT_ARGS="$BOOT_ARGS -boot-info-table -eltorito-alt-boot -e boot/efi.img -no-emul-boot" + eend $? + fi + fi + + eoutdent + ;; + esac + ;; + esac + CURRENT_DIR=$(pwd) if cd "$BUILD_OUTPUT" ; then if [ "$BOOT_METHOD" = "grub2" ]; then @@ -1123,7 +1258,7 @@ else 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} ." - "$MKISOFS" -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \ + $MKISOFS -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \ -l -r -J $BOOT_ARGS -no-pad \ -o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$? # both of these need core.img there, so it’s easier to write it here @@ -1145,28 +1280,10 @@ else 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 - elif [ "$HYBRID_METHOD" = "isohybrid" ] ; then - if ! which isohybrid >/dev/null 2>&1 ; then - bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common" - 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 - # by default use our manifold boot method: - else + elif [ "$HYBRID_METHOD" = "manifold" ] ; then # isoinfo is part of both mkisofs and genisoimage so we're good bootoff=$(isoinfo -l -i "${ISO_OUTPUT}/${ISO_NAME}" | \ - sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN;1 *$/s//\1/p') + sed -n '/^.*\[ *\([0-9]*\)[] ].* ISOLINUX.BIN[;1]* *$/s//\1/p') if ! [ -r boot/grub/core.img ] ; then ewarn "boot/grub/core.img not found, not creating manifold boot ISO file" elif [ "${bootoff:-0}" -lt 1 ] ; then @@ -1184,6 +1301,29 @@ else fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null eend $? fi + # use isohybrid as default + else + if ! which isohybrid >/dev/null 2>&1 ; then + bailout 12 "isohybrid binary not found - please install syslinux/syslinux-common" + 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 + einfo "Detected uefi support for isohybrid, enabling." + ISOHYBRID_OPTIONS=--uefi + fi + + log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}" + isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}" + eend $? + fi fi # generate md5sum and sha1sum of ISO if we are using class 'RELEASE': @@ -1214,14 +1354,58 @@ else fi # }}} -# pack artifacts {{{ -if [ -n "$PACK_ARTIFACTS" ]; then - log "Packing artifcats" - einfo "Packing artifacts" - [ -f "${CHROOT_ARCHIVE}" ] && rm -r "${CHROOT_ARCHIVE}" - tar -c -a -f ${CHROOT_ARCHIVE} --preserve-permissions -C "$(dirname ${CHROOT_OUTPUT})" "$(basename ${CHROOT_OUTPUT})" - eend 0 -fi +# netboot package {{{ +create_netbootpackage() { + local OUTPUT_FILE="${NETBOOT}/grml_netboot_package_${GRML_NAME}_${VERSION}.tar.bz2" + + 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." + ewarn "Skipping stage 'netboot' as $OUTPUT_FILE exists already." ; eend 0 + return 0 + elif [ -n "$SKIP_NETBOOT" ] ; then + log "Skipping stage 'netboot' as requested via option -Q" + ewarn "Skipping stage 'netboot' as requested via option -Q" ; eend 0 + return 0 + fi + + mkdir -p "$NETBOOT" + + if ! [ -r "${CHROOT}/usr/lib/syslinux/pxelinux.0" ] ; then + ewarn "File /usr/lib/syslinux/pxelinux.0 not found in build chroot." ; eend 0 + eindent + einfo "Install syslinux[-common] package in chroot to get a netboot package." + eoutdent + return 0 + fi + + local OUTPUTDIR="${NETBOOT}/build_tmp" + local WORKING_DIR="${OUTPUTDIR}/grml_netboot_package_${GRML_NAME}_${VERSION}/tftpboot/" + + mkdir -p "$WORKING_DIR" + + cp "${CHROOT_OUTPUT}"/boot/vmlinuz-* "$WORKING_DIR"/vmlinuz + cp "${CHROOT_OUTPUT}"/boot/initrd.img-* "$WORKING_DIR"/initrd.img + cp "${CHROOT_OUTPUT}"/usr/lib/syslinux/pxelinux.0 "${WORKING_DIR}/pxelinux.0" + + mkdir -p "${WORKING_DIR}/pxelinux.cfg" + if [ -r "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" ] ; then + cp "${BUILD_OUTPUT}/boot/isolinux/netboot.cfg" "${WORKING_DIR}/pxelinux.cfg/default" + else + ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found." ; eend 0 + fi + + if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then + sha1sum "${OUTPUT_FILE}" > "${OUTPUT_FILE}.sha1" + einfo "Generated netboot package ${OUTPUT_FILE}" ; eend 0 + rm -rf "${OUTPUTDIR}" + else + rm -rf "${OUTPUTDIR}" + eerror "Could not generate netboot package ${OUTPUT_FILE}" ; eend 1 + bailout 21 + fi +} + +create_netbootpackage # }}} # log build information to database if grml-live-db is installed and enabled {{{