export LANG=C
export LC_ALL=C
+# avoid leaking into chroots
+unset TMPDIR
+
# define function getfilesize before "set -e"
if stat --help >/dev/null 2>&1; then
getfilesize='stat -c %s' # GNU stat
umount $CHROOT_OUTPUT/dev/pts 2>/dev/null || /bin/true
umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
+ if [ -n "$EXTRACT_ISO_NAME" ] ; then
+ umount "$EXTRACT_ISO_NAME" 2>/dev/null || /bin/true
+ fi
+
# 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
[ -n "${CHROOT_OUTPUT}" -a -d "${CHROOT_OUTPUT}" ] && rm -r "${CHROOT_OUTPUT}"
eend 0
fi
+
+ # get rid of automatically generated conffiles
+ rm -f ${GRML_FAI_CONFIG}/nfsroot.conf
+ rm -f ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf
+
if [ -n "$CHOWN_USER" ]; then
log "Setting ownership"
einfo "Setting ownership"
[ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
[ -n "$GRML_NAME" ] || GRML_NAME='grml'
[ -n "$HOSTNAME" ] || HOSTNAME='grml'
-[ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='manifold'
-[ -n "$NFSROOT_CONF" ] || NFSROOT_CONF="${GRML_FAI_CONFIG}/make-fai-nfsroot.conf"
+[ -n "$HYBRID_METHOD" ] || HYBRID_METHOD='isohybrid'
[ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
[ -n "$SQUASHFS_EXCLUDES_FILE" ] || SQUASHFS_EXCLUDES_FILE="${GRML_FAI_CONFIG}/config/grml/squashfs-excludes"
[ -n "$SUITE" ] || SUITE='testing'
echo -n "Is this ok for you? [y/N] "
read a
if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
- bailout 1 "Exiting as requested."
+ CLEAN_ARTIFACTS=0
+ echo "Exiting as requested."
+ exit 0
fi
echo
fi
eend 1
bailout 1
fi
- unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*/*.squashfs ; rc=$?
+
+ if ls "${mountpoint}"/live/*/*.squashfs 2>/dev/null | grep -q . ; then # ISOs >=2011.12
+ log "Using ${mountpoint}/live/*/*.squashfs for unsquashfs"
+ unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*/*.squashfs ; rc=$?
+ elif ls "${mountpoint}"/live/*.squashfs 2>/dev/null | grep -q . ; then # ISOs before 2011.12
+ log "Using ${mountpoint}/live/*.squashfs for unsquashfs"
+ unsquashfs -d "${CHROOT_OUTPUT}" "${mountpoint}"/live/*.squashfs ; rc=$?
+ else
+ log "Error: Could not find any *.squashfs files on the ISO"
+ eerror "Error: Could not find any *.squashfs files on the ISO"
+ eend 1
+ bailout 1
+ fi
+
umount "$mountpoint"
rmdir "$mountpoint"
if [ "$rc" != 0 ]; then
# }}}
# on-the-fly configuration {{{
-if [ -n "$FAI_DEBOOTSTRAP" ] ; then
- sed "s#^FAI_DEBOOTSTRAP=.*#FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"#" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
-fi
# does this suck? YES!
# /usr/share/debootstrap/scripts/unstable does not exist, instead use 'sid':
esac
export SUITE # make sure it's available in FAI scripts
-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
-done
-
# validate whether the specified architecture class matches the
# architecture (option), otherwise installation of kernel will fail
-if echo $CLASSES | grep -qi i386 ; then
+if echo $CLASSES | grep -qw 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?)."
fi
fi
-if grep -q -- 'FAI_DEBOOTSTRAP_OPTS.*--arch' "$NFSROOT_CONF" ; then
- sed "s/--arch [a-z0-9]* /--arch $ARCH /" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
-else
- sed "s|^FAI_DEBOOTSTRAP_OPTS=\"\(.*\)|FAI_DEBOOTSTRAP_OPTS=\"--arch $ARCH \1|" "$NFSROOT_CONF" | sponge "$NFSROOT_CONF"
+# generate nfsroot configuration for FAI on the fly
+if [ -z "$FAI_DEBOOTSTRAP" ] ; then
+ FAI_DEBOOTSTRAP="$SUITE http://cdn.debian.net/debian"
+fi
+
+if [ -z "$FAI_DEBOOTSTRAP_OPTS" ] ; then
+ FAI_DEBOOTSTRAP_OPTS="--exclude=info,tasksel,tasksel-data --arch $ARCH"
fi
+
+# create backup of old (not yet automatically generated) config file
+if [ -f "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" ] ; then
+ if ! grep -q 'This is an automatically generated file by grml-live' "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" ; then
+ ewarn "Found old ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf - moving to ${GRML_FAI_CONFIG}/make-fai-nfsroot.conf.outdated"
+ mv "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf" "${GRML_FAI_CONFIG}/make-fai-nfsroot.conf.outdated"
+ eend $?
+ fi
+fi
+
+echo "# This is an automatically generated file by grml-live.
+# Do NOT edit this file, your changes will be lost.
+FAI_DEBOOTSTRAP=\"$FAI_DEBOOTSTRAP\"
+FAI_DEBOOTSTRAP_OPTS=\"$FAI_DEBOOTSTRAP_OPTS\"
+# EOF " > "${GRML_FAI_CONFIG}/nfsroot.conf"
+# support FAI <=3.4.8, versions >=4.0 use nfsroot.conf
+( cd ${GRML_FAI_CONFIG} && ln -sf nfsroot.conf make-fai-nfsroot.conf )
# }}}
# CHROOT_OUTPUT - execute FAI {{{
else
[ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
- # provide inform fai about the ISO we build
- [ -d "$CHROOT_OUTPUT/etc/" ] || mkdir -p "$CHROOT_OUTPUT/etc/"
- echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
- [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
- [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
-
if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
FAI_ACTION=softupdate
else
mkdir -p "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
mount --bind "${OUTPUT}/grml_sources/" "${CHROOT_OUTPUT}/grml-live/sources/"
- # tell dpkg to use "unsafe io" during the build
- [ -d "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d" ] || mkdir -p "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d"
- 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 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 \
-u "$HOSTNAME" "$FAI_ACTION" "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
RC="$PIPESTATUS" # notice: bash-only
- rm -f "$CHROOT_OUTPUT/etc/dpkg/dpkg.cfg.d/unsafe-io"
+ # provide inform fai about the ISO we build, needs to be provided
+ # *after* FAI stage, otherwise FAI skips the debootstrap stage if
+ # there is not BASEFILE (as it checks for presence of /etc) :(
+ echo '# This file has been generated by grml-live.' > "$CHROOT_OUTPUT/etc/grml_live_version"
+ [ -n "$GRML_LIVE_VERSION" ] && echo "GRML_LIVE_VERSION=$GRML_LIVE_VERSION" >> "$CHROOT_OUTPUT/etc/grml_live_version"
+ [ -n "$SUITE" ] && echo "SUITE=$SUITE" >> "$CHROOT_OUTPUT/etc/grml_live_version"
FORCE_ISO_REBUILD=true
mkdir -p "$LOG_OUTPUT"/fai/
cp -r "$CHROOT_OUTPUT"/var/log/fai/"$HOSTNAME"/last/* "$LOG_OUTPUT"/fai/
rm -rf "$CHROOT_OUTPUT"/var/log/fai
+
+ # store copy of autogenerated configuration file
+ cp ${GRML_FAI_CONFIG}/nfsroot.conf "$LOG_OUTPUT"/fai/
+
# copy fai package list
cp "$CHROOT_OUTPUT"/var/log/install_packages.list "$LOG_OUTPUT"/fai/
# fixup owners
<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 $5}' "${CHECKLOG}/package_errors.log" | sed 's/\.$//') ; do
+ for package in $(awk '{print $1}' "${CHECKLOG}/package_errors.log") ; 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">
- <failure type="RuntimeError" message="Package ${package} is missing">
-Package $package is missing in chroot
+ <failure type="${failure_reason}" message="Package ${package} is missing">
+Package $package is missing in chroot (${failure_reason})
</failure>
</testcase>
EOF
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
- for file in memdisk chain.c32 hdt.c32 menu.c32; do
+ for file in memdisk chain.c32 hdt.c32 mboot.c32 menu.c32; do
copy_addon_file "${file}" /usr/lib/syslinux addons
done
fi
cp -a ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
+ # generate loopback.cfg config file without depending on grub's regexp module
+ # which isn't available in Debian/squeeze
+ echo "## grub2 loopback configuration" > "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+ echo "source /boot/grub/header.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+ for config in "${BUILD_OUTPUT}"/boot/grub/*_default.cfg "${BUILD_OUTPUT}"/boot/grub/*_options.cfg ; do
+ [ -r "$config" ] || continue
+ echo "source ${config##$BUILD_OUTPUT}" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+ done
+ echo "source /boot/grub/addons.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+ echo "source /boot/grub/footer.cfg" >> "${BUILD_OUTPUT}"/boot/grub/loopback.cfg
+
# 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/
sed -i "s/%SHORT_NAME%/$SHORT_NAME/g" "${file}"
sed -i "s/%VERSION%/$VERSION/g" "${file}"
- [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s/ boot=live/ boot=live $DEFAULT_BOOTOPTIONS/" "${file}"
+ [ -n "$DEFAULT_BOOTOPTIONS" ] && sed -i "s; boot=live; boot=live $DEFAULT_BOOTOPTIONS;" "${file}"
if [ -n "$NO_BOOTID" ] ; then
sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
BOOT_ARGS="-no-emul-boot -boot-load-size 4 -b boot/grub/toriboot.bin"
fi
-# Just until http://bts.grml.org/grml/issue945 has been resolved.
-# HYBRID_METHOD defaults to manifold, so make sure the default works OOTB.
+# Work around http://bts.grml.org/grml/issue945
if [[ $BOOT_METHOD != isolinux && ($HYBRID_METHOD = isohybrid || $HYBRID_METHOD = manifold) ]]; then
log "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
ewarn "Setting HYBRID_METHOD to grub2 as hybrid mode does not work with isohybrid yet."
of="${ISO_OUTPUT}/${ISO_NAME}" 2>/dev/null
# support disabling hybrid ISO image
- if [ "$HYBRID_METHOD" = "disable" ] ; then\
- 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
- 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')
- 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
- ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
- else
- log "Creating hybrid ISO file with manifold method"
- einfo "Creating hybrid ISO file with manifold method"
- if [ "$HYBRID_METHOD" = "grub2" ] ; then
- # 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
- else
- # read only one but 2048-byte sized (scale: << 2) sector
- echo $bootoff $bootoff | \
- mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
- 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
+ if [ "$HYBRID_METHOD" = "disable" ] ; then
+ 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
+ elif [ "$HYBRID_METHOD" = "manifold" ] || [ "$HYBRID_METHOD" = "grub2" ] ; 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')
+
+ if ! [ -r boot/grub/core.img ] ; then
+ log "boot/grub/core.img not found, not creating manifold boot ISO file"
+ ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
+ elif [ "${bootoff:-0}" -lt 1 ] ; then
+ log "isolinux.bin not found on the ISO file, disabling manifold boot"
+ ewarn "isolinux.bin not found on the ISO file, disabling manifold boot"
+ else
+ if [ "$HYBRID_METHOD" = "grub2" ] ; then
+ log "Creating hybrid ISO file with manifold/grub2 method"
+ einfo "Creating hybrid ISO file with manifold/grub2 method"
+ # 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
+ else
+ log "Creating hybrid ISO file with manifold method"
+ einfo "Creating hybrid ISO file with manifold method"
+ # read only one but 2048-byte sized (scale: << 2) sector
+ echo $bootoff $bootoff | \
+ mksh /usr/share/grml-live/scripts/bootilnx.mksh -A -M 4:0x96 -g $cyls:16:32 -S 2
+ fi | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
+ 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"
+ 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
+ log "isohybrid $ISOHYBRID_OPTIONS ${ISO_OUTPUT}/${ISO_NAME}"
+ isohybrid $ISOHYBRID_OPTIONS "${ISO_OUTPUT}/${ISO_NAME}"
+ eend $?
+ fi
+ 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':
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
+ log "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found."
+ ewarn "File ${BUILD_OUTPUT}/boot/isolinux/netboot.cfg not found."
+ eindent
+ log "Hint: Are you using custom templates which do not provide netboot.cfg?"
+ ewarn "Hint: Are you using custom templates which do not provide netboot.cfg?" ; eend 0
+ eoutdent
fi
if tar -C "$OUTPUTDIR" -jcf "${OUTPUT_FILE}" "grml_netboot_package_${GRML_NAME}_${VERSION}" ; then