X-Git-Url: https://git.grml.org/?p=grml-live.git;a=blobdiff_plain;f=grml-live;h=88d796fb56bcc3cf1f7b52f70b5fec6189da2f02;hp=63cdb9bdafb7007975baab720ac134c6dc97c982;hb=db5741b5b41210da401504a3493d9a284da32e9c;hpb=b0b7374fbb2bd14e006dedb6a7fc0eb4327241ea diff --git a/grml-live b/grml-live index 63cdb9b..88d796f 100755 --- a/grml-live +++ b/grml-live @@ -59,6 +59,7 @@ Usage: $PN [options, see as follows] -r release name -s Debian suite; values: etch, lenny, squeeze, sid -t place of the templates + -T unpack chroot tar archive before starting -u update existing chroot instead of rebuilding it from scratch -U arrange output to be owned by specified username -v specify version number of the release @@ -68,10 +69,9 @@ Usage: $PN [options, see as follows] Usage examples: $PN - $PN -c GRMLBASE,GRML_MEDIUM,I386 -o /dev/shm/grml - $PN -c GRMLBASE,GRML_SMALL,REMOVE_DOCS,I386 -g grml-small -v 1.0 - $PN -c GRMLBASE,GRML_FULL,I386 -i grml_0.0-1.iso -v 0.0-1 - $PN -c GRMLBASE,GRML_FULL,I386 -s sid -V -r 'grml-live rocks' + $PN -c GRMLBASE,GRML_FULL,AMD64 -o /dev/shm/grml + $PN -c GRMLBASE,GRML_FULL,AMD64 -i grml_0.0-1.iso -v 0.0-1 + $PN -c GRMLBASE,GRML_FULL,AMD64 -s sid -V -r 'grml-live rocks' More details: man grml-live + /usr/share/doc/grml-live/grml-live.html http://grml.org/grml-live/ @@ -149,6 +149,12 @@ umount_all() { umount $CHROOT_OUTPUT/sys 2>/dev/null || /bin/true umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true + + # certain FAI versions sadly leave a ramdisk behind, so better safe than sorry + if [ -x /usr/lib/fai/mkramdisk ] ; then + /usr/lib/fai/mkramdisk -u "$(readlink -f ${CHROOT_OUTPUT}/var/lib/dpkg)" >/dev/null 2>&1 || /bin/true + fi + umount "${CHROOT_OUTPUT}/grml-live/sources/" 2>/dev/null || /bin/true [ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}" } @@ -191,7 +197,7 @@ trap umount_all EXIT # log output: # usage: log "string to log" -log() { echo "$*" >> $LOGFILE ; } +log() { [ -n "$LOGFILE" ] && echo "$*" >> $LOGFILE ; } # cut string at character number int = $1 # usage: cut_string 5 "1234567890" will output "12345" @@ -293,7 +299,7 @@ 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:g:i:I:o:r:s:t:T:U:v:AbBFnNquVz" opt; do case "$opt" in a) ARCH="$OPTARG" ;; A) PACK_ARTIFACTS=1 ;; @@ -313,6 +319,7 @@ while getopts "a:C:c:d:D:g:i:I:o:r:s:t:U:v:AbBFnNquVz" opt; do r) RELEASENAME="$OPTARG" ;; s) SUITE="$OPTARG" ;; t) TEMPLATE_DIRECTORY="$OPTARG";; + T) UNPACK_CHROOT="$(readlink -f $OPTARG)" ;; v) VERSION="$OPTARG" ;; F) FORCE=1 ;; u) UPDATE=1 ;; @@ -328,7 +335,7 @@ shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter # assume sane defaults (if not set already) {{{ [ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)" [ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux' -[ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_MEDIUM,$(echo ${ARCH} | tr 'a-z' 'A-Z')" +[ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_FULL,$(echo ${ARCH} | tr 'a-z' 'A-Z')" [ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)" [ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators ' [ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml" @@ -353,6 +360,7 @@ shift $(($OPTIND - 1)) # set ARGV to the first not parsed commandline parameter [ -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/" # }}} # some misc checks before executing FAI {{{ @@ -390,6 +398,7 @@ if [ -z "$FORCE" ] ; then [ -n "$CONFIG" ] && echo " Configuration: $CONFIG" [ -n "$GRML_FAI_CONFIG" ] && echo " Config directory: $GRML_FAI_CONFIG" echo " main directory: $OUTPUT" + [ -n "$UNPACK_CHROOT" ] && echo " Chroot from: $UNPACK_CHROOT" [ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT" [ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT" [ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT" @@ -439,7 +448,6 @@ if [ -n "${PACK_ARTIFACTS}" ]; then [ -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}" fi # }}} @@ -496,6 +504,28 @@ log "$CMDLINE" einfo "Logging actions to logfile $LOGFILE" # }}} +# unpack chroot {{{ +if [ -n "${UNPACK_CHROOT}" ]; then + log "Unpacking chroot from ${UNPACK_CHROOT}" + einfo "Unpacking chroot from ${UNPACK_CHROOT}" + [ -d "$CHROOT_OUTPUT" ] || mkdir -p "${CHROOT_OUTPUT}" + tar -xf "${UNPACK_CHROOT}" -C "${CHROOT_OUTPUT}/" --strip-components 1 | RC=$? + echo $RC + if [ "$RC" != 0 ] ; then + eend 1 + bailout 1 + fi + eend 0 +fi +# }}} + +# cleanup CHROOT_ARCHIVE now {{{ +if [ -n "${PACK_ARTIFACTS}" ]; then + # can't do this earlier, as UNPACK_CHROOT might point to CHROOT_ARCHIVE + [ -n "${CHROOT_ARCHIVE}" -a -f "${CHROOT_ARCHIVE}" ] && rm "${CHROOT_ARCHIVE}" +fi +# }}} + # on-the-fly configuration {{{ if [ -n "$FAI_DEBOOTSTRAP" ] ; then sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF" @@ -626,18 +656,18 @@ else # move fai logs into grml_logs directory mkdir -p "$LOG_OUTPUT"/fai/ cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/ + rm -rf "$CHROOT_OUTPUT"/var/log/fai + # copy fai package list + cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/ + # fixup owners chown root:adm "$LOG_OUTPUT"/fai/* chmod 664 "$LOG_OUTPUT"/fai/* - rm -rf "$CHROOT_OUTPUT"/var/log/fai - - # Remove all FAI logs from chroot if class RELEASE is used: - rm -f "$CHROOT_OUTPUT"/var/log/install_packages.list umount_all # notice: 'fai dirinstall' does not seem to exit appropriate, so: ERROR='' - CHECKLOG=/var/log/fai/$HOSTNAME/last + CHECKLOG="$LOG_OUTPUT"/fai/ if [ -r "$CHECKLOG/software.log" ] ; then # 1 errors during executing of commands grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1 @@ -661,30 +691,84 @@ else log "Finished execution of stage 'fai dirinstall' [$(date)]" einfo "Finished execution of stage 'fai dirinstall'" fi - - einfo "Find FAI build logs at $(readlink -f /var/log/fai/$HOSTNAME/last)" - log "Find FAI build logs at $(readlink -f /var/log/fai/$HOSTNAME/last)" - eend 0 fi 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 # }}} @@ -1101,17 +1185,53 @@ 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 && \ + dpkg --compare-versions $(dpkg-query -W -f='${Version}\n' xorriso 2>/dev/null) gt-nl 1.1.6-2 ; 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 + + 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 + ;; + esac + ;; + esac + CURRENT_DIR=$(pwd) if cd "$BUILD_OUTPUT" ; then if [ "$BOOT_METHOD" = "grub2" ]; then @@ -1122,7 +1242,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 @@ -1144,28 +1264,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 @@ -1183,6 +1285,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':