set -e
# global variables
-GRML_LIVE_VERSION='0.9.21'
+GRML_LIVE_VERSION='0.9.22'
PN="$(basename $0)"
CMDLINE="$0 $@"
ISO_DATE="$(date +%Y-%m-%d)"
-g <grml_name>] set the grml flavour name
-h display short usage information and exit
-i <iso_name> name of ISO
+ -I <src_directory> directory which provides files that should become
+ part of the chroot/ISO
-o <output_directory> main output directory of the build process
-q skip mksquashfs
-r <release_name< release name
bailout() {
rm -f /var/run/fai/fai_softupdate_is_running \
/var/run/fai/FAI_INSTALLATION_IN_PROGRESS
+ [ -n "$SQUASHFS_STDERR" ] && rm -rf "$SQUASHFS_STDERR"
[ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
[ -n "$1" ] && EXIT="$1" || EXIT="1"
[ -n "$2" ] && eerror "$2">&2
# }}}
# command line parsing {{{
-while getopts "a:C:c:g:i:o:r:s:t:v:bBFuqVz" opt; do
+while getopts "a:C:c:g:i:I:o:r:s:t:v:bBFuqVz" opt; do
case "$opt" in
a) ARCH="$OPTARG" ;;
b) BUILD_ONLY=1 ;;
C) CONFIG="$OPTARG" ;;
g) GRML_NAME="$OPTARG" ;;
i) ISO_NAME="$OPTARG" ;;
+ I) CHROOT_INSTALL="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
q) SKIP_MKSQUASHFS=1 ;;
r) RELEASENAME="$OPTARG" ;;
# }}}
# assume sane defaults (if not set already) {{{
-[ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
-[ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
-[ -n "$CLASSES" ] || CLASSES='GRML,I386'
-[ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators '
-[ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
-[ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
-[ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
-[ -n "$GRML_NAME" ] || GRML_NAME='grml'
-[ -n "$HOSTNAME" ] || HOSTNAME='grml'
-[ -n "$NFSROOT_CONF" ] || NFSROOT_CONF='/etc/grml/fai/make-fai-nfsroot.conf'
-[ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
-[ -n "$SUITE" ] || SUITE='stable'
-[ -n "$USERNAME" ] || USERNAME='grml'
-[ -n "$VERSION" ] || VERSION='0.0.1'
+[ -n "$ARCH" ] || ARCH="$(dpkg --print-architecture)"
+[ -n "$BOOT_METHOD" ] || BOOT_METHOD='isolinux'
+[ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
+[ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
+[ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_MEDIUM,I386"
+[ -n "$DISTRI_INFO" ] || DISTRI_INFO='Grml - Live Linux for system administrators '
+[ -n "$DISTRI_NAME" ] || DISTRI_NAME="grml"
+[ -n "$DISTRI_SPLASH" ] || DISTRI_SPLASH='grml.png'
+[ -n "$FORCE_ISO_REBUILD" ] || FORCE_ISO_REBUILD="false"
+[ -n "$GRML_FAI_CONFIG" ] || GRML_FAI_CONFIG='/etc/grml/fai'
+[ -n "$GRML_NAME" ] || GRML_NAME='grml'
+[ -n "$HOSTNAME" ] || HOSTNAME='grml'
+[ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
+[ -n "$NFSROOT_CONF" ] || NFSROOT_CONF='/etc/grml/fai/make-fai-nfsroot.conf'
+[ -n "$OUTPUT" ] || OUTPUT='/grml/grml-live'
+[ -n "$RELEASENAME" ] || RELEASENAME='grml-live rocks'
+[ -n "$SQUASHFS_EXCLUDES_FILE " ] || SQUASHFS_EXCLUDES_FILE='/etc/grml/fai/squashfs-excludes'
+[ -n "$SUITE" ] || SUITE='stable'
+[ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
+[ -n "$USERNAME" ] || USERNAME='grml'
+[ -n "$VERSION" ] || VERSION='0.0.1'
+[ -n "$WINDOWS_BINARIES" ] || WINDOWS_BINARIES='http://the.earth.li/~sgtatham/putty/latest/x86/'
# }}}
# some misc checks before executing FAI {{{
[ -n "$ARCH" ] && echo " Architecture: $ARCH"
[ -n "$BOOT_METHOD" ] && echo " Boot method: $BOOT_METHOD"
[ -n "$TEMPLATE_DIRECTORY" ] && echo " Template files: $TEMPLATE_DIRECTORY"
+ [ -n "$CHROOT_INSTALL" ] && echo " Install files from directory to chroot: $CHROOT_INSTALL"
[ -n "$FAI_ARGS" ] && echo " additional arguments for FAI: $FAI_ARGS"
[ -n "$LOGFILE" ] && echo " Logging to file: $LOGFILE"
[ -n "$SQUASHFS_ZLIB" ] && echo " Using ZLIB (instead of LZMA) compression."
fi
if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; then
- if ! [ -r "$CHROOT_OUTPUT/etc/grml_version" ] ; then
+ if ! [ -r "$CHROOT_OUTPUT/etc/debian_version" ] ; then
log "Error: does not look like you have a working chroot. Updating/building not possible."
eerror "Error: does not look like you have a working chroot. Updating/building not possible. (Drop -u/-b option?)"
eend 1
"$HOSTNAME" $FAI_ACTION "$CHROOT_OUTPUT" $FAI_ARGS | tee -a $LOGFILE
RC="$PIPESTATUS" # notice: bash-only
+ FORCE_ISO_REBUILD=true
+
if [ "$RC" != 0 ] ; then
log "Error while executing fai [exit code ${RC}]. Exiting."
eerror "Error while executing fai [exit code ${RC}]. Exiting." ; eend 1
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?
# }}}
if [ -z "$NO_ADDONS" ] ; then
[ -d "$BUILD_OUTPUT"/boot/addons ] || mkdir -p "$BUILD_OUTPUT"/boot/addons
- cp /boot/memtest86+.bin "$BUILD_OUTPUT"/boot/addons/memtest
+ if [ -r "$TEMPLATE_DIRECTORY"/boot/addons/memtest ] ; then
+ log "Installing $TEMPLATE_DIRECTORY/boot/addons/memtest"
+ cp "$TEMPLATE_DIRECTORY"/boot/addons/memtest "$BUILD_OUTPUT"/boot/addons/memtest
+ elif [ -r /boot/memtest86+.bin ] ; then
+ log "Installing /boot/memtest86+.bin"
+ cp /boot/memtest86+.bin "$BUILD_OUTPUT"/boot/addons/memtest
+ else
+ ewarn "No memtest binary found, skipping."
+ log "No memtest binary found, skipping."
+ eend 0
+ fi
fi
# if we don't have an initrd we a) can't boot and b) there was an error
cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
- if [ -z "$NO_ADDONS" ] ; then
+ if [ -n "$NO_ADDONS" ] ; then
+ log "Skipping installation boot addons requested via \$NO_ADDONS."
+ einfo "Skipping installation boot addons requested via \$NO_ADDONS."
+ eend 0
+ else
if ! [ -d /usr/share/grml-live/templates/boot/addons/bsd4grml ] ; then
ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
else
sed -i "s/%VERSION%/$VERSION/" "$BUILD_OUTPUT"/boot/grub/grub.cfg
sed -i "s/%GRML_NAME%/$SHORT_GRML_NAME/" "$BUILD_OUTPUT"/boot/grub/grub.cfg
+ if [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] ; then
+ sed -i "s/%VERSION%/$VERSION/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
+ sed -i "s/%GRML_LONG_NAME%/$DISTRI_NAME/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
+ sed -i "s/%GRML_NAME%/$SHORT_GRML_NAME/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
+ sed -i "s/%ARCH%/$ARCH/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
+ fi
+
sed -i "s/%VERSION%/$VERSION/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
- sed -i "s/%GRML_NAME%/$GRML_NAME/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
+ sed -i "s/%GRML_LONG_NAME%/$GRML_NAME/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
+ sed -i "s/%GRML_NAME%/$SHORT_GRML_NAME/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
sed -i "s/%ARCH%/$ARCH/" "$BUILD_OUTPUT"/boot/isolinux/grml.cfg
sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/" "$BUILD_OUTPUT"/boot/isolinux/vesamenu.cfg
sed -i "s/%GRML_NAME_SQUASHFS%/$GRML_NAME_SQUASHFS/" "$BUILD_OUTPUT"/boot/isolinux/f4
sed -i "s/%GRML_NAME_SQUASHFS%/$GRML_NAME_SQUASHFS/" "$BUILD_OUTPUT"/boot/isolinux/f5
- if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] ; then
+ if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
log "including grml.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
echo "include grml.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
[ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
einfo "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
if grep -q "^include ${DISTRI_NAME}.cfg" "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
log "include for ${DISTRI_NAME}.cfg already present, nothing to do."
+ eindent
einfo "include for ${DISTRI_NAME}.cfg already present, nothing to do."
+ eoutdent
eend $?
else
log "including ${DISTRI_NAME}.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
fi
# jump back to grub from bsd4grml:
+ if [ -e "$BUILD_OUTPUT"/boot/grub/stage2 ]; then
+ GRUB_LEGACY=stage2
+ else
+ GRUB_LEGACY=stage2_eltorito
+ fi
if [ -e "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 ]; then
if [ -e "$BUILD_OUTPUT"/boot/grub/core.img ]; then
GRUB_VERSION=2
else
GRUB_VERSION=1
fi
- if [ -e "$BUILD_OUTPUT"/boot/grub/stage2 ]; then
- GRUB_LEGACY=stage2
- else
- GRUB_LEGACY=stage2_eltorito
- fi
# why not ed(1)?
for file in "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 \
sed -i -e "s!%GRUB_VERSION%!$GRUB_VERSION!g" \
-e "s!%GRUB_LEGACY%!$GRUB_LEGACY!g" "$file"
done
+
+ sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6
+ fi
+ if [ -e "$BUILD_OUTPUT"/boot/grub/$GRUB_LEGACY ]; then
+ sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/menu.lst
+ sed -i "s/%GRUB_LEGACY%/$GRUB_LEGACY/g" "$BUILD_OUTPUT"/boot/grub/grub.cfg
+ else
+ sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/menu.lst
+ sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/grub.cfg
fi
# autostart for Windows:
fi
# windows-binaries:
- if [ -n "$WINDOWS_BINARIES" ] ; then
+ if [ -n "$NO_WINDOWS_BINARIES" ] ; then
+ log "Skipping download of windows binaries as requested via \$NO_WINDOWS_BINARIES."
+ einfo "Skipping download of windows binaries as requested via \$NO_WINDOWS_BINARIES."
+ eend 0
+ else
if [ -f "$BUILD_OUTPUT"/windows/putty.exe ] ; then
log "$BUILD_OUTPUT/windows exists already, skipping stage 'WINDOWS_BINARIES'"
ewarn "$BUILD_OUTPUT/windows exists already, skipping stage 'WINDOWS_BINARIES'" ; eend 0
done )
fi
fi
- log "Finished execution of stage 'WINDOWS_BINARIES' [$(date)]"
- einfo "Finished execution of stage 'WINDOWS_BINARIES'" ; eend 0
+ log "Finished execution of stage 'WINDOWS_BINARIES' [$(date)]"
+ einfo "Finished execution of stage 'WINDOWS_BINARIES'" ; eend 0
fi
+
+ FORCE_ISO_REBUILD=true
einfo "Finished execution of stage 'boot'" ; eend 0
fi
-# ppc:
-elif [ "$ARCH" = powerpc ] ; then
- ewarn 'Warning: formorer, it is your turn. :)'>&2
-# unsuported:
else
+ log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
fi
+# support installation of local files into the chroot/ISO
+if [ -n "$CHROOT_INSTALL" ] ; then
+ if ! [ -d "$CHROOT_INSTALL" ] ; then
+ log "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
+ ewarn "Configuration variable \$CHROOT_INSTALL is set but not a directory; ignoring"
+ else
+ log "Copying local files to chroot as requested via \$CHROOT_INSTALL"
+ einfo "Copying local files to chroot as requested via \$CHROOT_INSTALL"
+ rsync -avz --inplace "$CHROOT_INSTALL"/ "$CHROOT_OUTPUT/"
+ eend $?
+ einfo "Make sure to run squashfs stage, otherwise your local files won't be part of the ISO."
+ FORCE_ISO_REBUILD=true
+ fi
+fi
+
if [ -f "$BUILD_OUTPUT"/live/${GRML_NAME}.squashfs -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
log "$BUILD_OUTPUT/live exists already, skipping stage 'squashfs'"
ewarn "$BUILD_OUTPUT/live exists already, skipping stage 'squashfs'" ; eend 0
# get rid of unnecessary files when building grml-small for final release:
if echo "$CLASSES" | grep -q GRML_SMALL ; then
- SQUASHFS_OPTIONS="$SQUASHFS_OUTPUT -e initrd.img* vmlinuz*"
+ SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
fi
- SQUASHFS_OUTPUT="$(mktemp -t grml-live.XXXXXX)"
+ SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
+
log "mksquashfs $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB"
if mksquashfs $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
- -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB 2>"${SQUASHFS_OUTPUT}" ; then
+ -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB 2>"${SQUASHFS_STDERR}" ; then
echo "${GRML_NAME}.squashfs" > $BUILD_OUTPUT/live/filesystem.module
log "Finished execution of stage 'squashfs' [$(date)]"
einfo "Finished execution of stage 'squashfs'" ; eend 0
- rm -f "${SQUASHFS_OUTPUT}"
else
log "There was an error executing stage 'squashfs' [$(date)]:"
- log "$(cat $SQUASHFS_OUTPUT)"
+ log "$(cat $SQUASHFS_STDERR)"
eerror "There was an error executing stage 'squashfs':" ; eend 1
- cat "${SQUASHFS_OUTPUT}"
- rm -f "${SQUASHFS_OUTPUT}"
+ cat "${SQUASHFS_STDERR}"
bailout
fi
+
+ FORCE_ISO_REBUILD=true
fi
# create md5sum file:
BOOT_FILE="boot/grub/stage2_eltorito"
fi
-if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" ] ; then
- log "$ISO_OUTPUT exists already, skipping stage 'iso build'"
- ewarn "$ISO_OUTPUT exists already, skipping stage 'iso build'" ; eend 0
+if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
+ log "$ISO_OUTPUT/${ISO_NAME} exists already, skipping stage 'iso build'"
+ ewarn "$ISO_OUTPUT/${ISO_NAME} exists already, skipping stage 'iso build'" ; eend 0
else
mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
+ if $FORCE_ISO_REBUILD ; then
+ log "Forcing rebuild of ISO because files on ISO have been modified."
+ 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
MKISOFS='mkisofs'