Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 1255 lines (1108 sloc) 54.567 kb
#!/bin/bash
# Filename: grml-live
# Purpose: build process script for generating a (grml based) Linux Live-ISO
# Authors: grml-team (grml.org),
# (c) Michael Prokop <mika@grml.org>,
# (c) Thorsten Glaser <tg@mirbsd.org>
# Bug-Reports: see http://grml.org/bugs/
# License: This file is licensed under the GPL v2 or any later version.
################################################################################
# some misc and global stuff {{{
export LANG=C
export LC_ALL=C
# define function getfilesize before "set -e"
if stat --help >/dev/null 2>&1; then
getfilesize='stat -c %s' # GNU stat
else
getfilesize='stat -f %z' # BSD stat
fi
# exit on any error:
set -e
# global variables
GRML_LIVE_VERSION='0.9.43'
PN="$(basename $0)"
CMDLINE="$0 $@"
SOURCES_LIST_FILE='/etc/grml/fai/apt/sources.list'
ADDONS_LIST_FILE='/boot/isolinux/addons_list.cfg'
# }}}
# usage information {{{
usage()
{
echo "
$PN - build process script for generating a (grml based) Linux Live-ISO
Usage: $PN [options, see as follows]
-a <architecture> architecture; available values: i386 and amd64
-b build the ISO without updating the chroot via FAI
-B build the ISO without touching the chroot (skips cleanup)
-c <classe[s]> classes to be used for building the ISO via FAI
-C <configfile> configuration file for grml-live
-d <date> use specified date instead of build time as date of release
-F force execution without prompting
-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
-n skip generation of ISO
-o <output_directory> main output directory of the build process
-q skip mksquashfs
-r <release_name> release name
-s <suite> Debian suite; values: etch, lenny, squeeze, sid
-t <template_directory> place of the templates
-u update existing chroot instead of rebuilding it from scratch
-v <version_number> specify version number of the release
-V increase verbosity in the build process
-z use ZLIB instead of LZMA compression (depends on
squashfs-tools version)
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'
More details: man grml-live + /usr/share/doc/grml-live/grml-live.html
http://grml.org/grml-live/
Please send your bug reports and feedback to the grml-team: http://grml.org/bugs/
"
}
# make sure it's possible to get usage information without being
# root or actually executing the script
if [ "$1" = '-h' -o "$1" = '--help' ] ; then
usage
[ "$(id -u 2>/dev/null)" != 0 ] && echo "Please notice that this script requires root permissions."
exit 0
fi
# }}}
# some runtime checks {{{
# we need root permissions for the build-process:
if [ "$(id -u 2>/dev/null)" != 0 ] ; then
echo "Error: please run this script with uid 0 (root)." >&2
exit 1
fi
if [ -r /var/run/fai/FAI_INSTALLATION_IN_PROGRESS ] ; then
echo "/usr/sbin/fai already running or was aborted before.">&2
echo "You may remove /var/run/fai/FAI_INSTALLATION_IN_PROGRESS and try again.">&2
exit 1
fi
# see #449236
if [ -r /var/run/fai/fai_softupdate_is_running ] ; then
echo "/usr/sbin/fai softupdate already running or was aborted before.">&2
echo "You may remove /var/run/fai/fai_softupdate_is_running and try again.">&2
exit 1
fi
# }}}
# lsb-functions and configuration stuff {{{
# make sure they are not set by default
VERBOSE=''
FORCE=''
UPDATE=''
BUILD_ONLY=''
BUILD_DIRTY=''
HOSTNAME=''
if [ -r /etc/grml/lsb-functions ] ; then
. /etc/grml/lsb-functions
else
einfo() { echo " [*] $*" ;}
eerror() { echo " [!] $*">&2 ;}
ewarn() { echo " [x] $*" ;}
eend() { return 0 ;}
eindent() { return 0 ;}
eoutdent() { return 0 ;}
fi
# source main configuration file:
LIVE_CONF=/etc/grml/grml-live.conf
. $LIVE_CONF
# }}}
# clean exit {{{
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
log "------------------------------------------------------------------------------"
exit "$EXIT"
}
trap bailout 1 2 3 3 6 9 14 15
# }}}
# log file stuff {{{
[ -n "$LOGFILE" ] || LOGFILE=/var/log/grml-live.log
touch $LOGFILE
chown root:adm $LOGFILE
chmod 664 $LOGFILE
# }}}
# some important functions {{{
# log output:
# usage: log "string to log"
log() { echo "$*" >> $LOGFILE ; }
# cut string at character number int = $1
# usage: cut_string 5 "1234567890" will output "12345"
cut_string() {
[ -n "$2" ] || return 1
echo "$2" | head -c "$1"; echo -ne "\n"
}
# prepend int = $1 spaces before string = $2
# usage: extend_string_begin 5 "123" will output " 123"
extend_string_begin() {
[ -n "$2" ] || return 1
local COUNT="$(echo $2 | wc -c)"
local FILL="$(expr $COUNT - $1)"
while [ "$FILL" -gt 1 ] ; do
echo -n " "
local FILL=$(expr $FILL - 1)
done
while [ "$FILL" -lt 1 ] ; do
echo -n " "
local FILL=$(expr $FILL + 1)
done
echo "$2" | head -c "$1"; echo -ne "\n"
}
# append int = $1 spaces to string = $2
# usage: extend_string_begin 5 "123" will output "123 "
extend_string_end() {
[ -n "$2" ] || return 1
echo -n "$2" | head -c "$1"
local COUNT="$(echo $2 | wc -c)"
local FILL="$(expr $COUNT - $1)"
while [ "$FILL" -gt 1 ] ; do
echo -n " "
local FILL=$(expr $FILL - 1)
done
while [ "$FILL" -lt 1 ] ; do
echo -n " "
local FILL=$(expr $FILL + 1)
done
echo -ne "\n"
}
# }}}
# read local (non-packaged) configuration {{{
LOCAL_CONFIG=/etc/grml/grml-live.local
if [ -r "$LOCAL_CONFIG" ] ; then
log "Sourcing $LOCAL_CONFIG"
. $LOCAL_CONFIG
else
log "No $LOCAL_CONFIG found, not sourcing it"
LOCAL_CONFIG=''
fi
# }}}
# command line parsing {{{
while getopts "a:C:c:d:g:i:I:o:r:s:t:v:bBFnquVz" opt; do
case "$opt" in
a) ARCH="$OPTARG" ;;
b) BUILD_ONLY=1 ;;
B) BUILD_DIRTY=1 ;;
c) CLASSES="$OPTARG" ;;
C) CONFIG="$OPTARG" ;;
d) DATE="$OPTARG" ;;
g) GRML_NAME="$OPTARG" ;;
i) ISO_NAME="$OPTARG" ;;
I) CHROOT_INSTALL="$OPTARG" ;;
n) SKIP_MKISOFS=1 ;;
o) OUTPUT="$OPTARG" ;;
q) SKIP_MKSQUASHFS=1 ;;
r) RELEASENAME="$OPTARG" ;;
s) SUITE="$OPTARG" ;;
t) TEMPLATE_DIRECTORY="$OPTARG";;
v) VERSION="$OPTARG" ;;
F) FORCE=1 ;;
u) UPDATE=1 ;;
V) VERBOSE="-v" ;;
z) SQUASHFS_ZLIB="-nolzma" ;;
?) echo "invalid option -$OPTARG" >&2; bailout 1 ;;
esac
done
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 "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
[ -n "$CHROOT_OUTPUT" ] || CHROOT_OUTPUT="$OUTPUT/grml_chroot"
[ -n "$CLASSES" ] || CLASSES="GRMLBASE,GRML_MEDIUM,I386"
[ -n "$DATE" ] || DATE="$(date +%Y-%m-%d)"
[ -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='lenny'
[ -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 "$CLASSES" ] || bailout 1 "Error: \$CLASSES unset, please set it in $LIVE_CONF or
specify it on the command line using the -c option."
[ -n "$OUTPUT" ] || bailout 1 "Error: \$OUTPUT unset, please set it in $LIVE_CONF or
specify it on the command line using the -o option."
# set subdirectories according to $OUTPUT:
CHROOT_OUTPUT="$OUTPUT/grml_chroot"
BUILD_OUTPUT="$OUTPUT/grml_cd"
ISO_OUTPUT="$OUTPUT/grml_isos"
# trim characters that are known to cause problems inside $GRML_NAME;
# for example isolinux does not like '-' inside the directory name
[ -n "$GRML_NAME" ] && export SHORT_NAME="$(echo $GRML_NAME | tr -d ',./;\- ')"
# export variables to have them available in fai scripts:
[ -n "$GRML_NAME" ] && export GRML_NAME="$GRML_NAME"
[ -n "$RELEASENAME" ] && export RELEASENAME="$RELEASENAME"
# }}}
# ZERO_LOGFILE - check for backwards compatibility reasons {{{
# this was default behaviour until grml-live 0.9.34:
if [ -n "$ZERO_LOGFILE" ] ; then
PRESERVE_LOGFILE='' # make sure it's cleaned then
ewarn "Please consider disabling the \$ZERO_LOGFILE option as grml-live clears..."
ewarn "... the logfile $LOGFILE by default (unless \$PRESERVE_LOGFILE is set) nowadays."
eend 0
fi
# }}}
# ask user whether the setup is ok {{{
if [ -z "$FORCE" ] ; then
echo
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"
echo " main directory: $OUTPUT"
[ -n "$CHROOT_OUTPUT" ] && echo " Chroot target: $CHROOT_OUTPUT"
[ -n "$BUILD_OUTPUT" ] && echo " Build target: $BUILD_OUTPUT"
[ -n "$ISO_OUTPUT" ] && echo " ISO target: $ISO_OUTPUT"
[ -n "$GRML_NAME" ] && echo " Grml name: $GRML_NAME"
[ -n "$RELEASENAME" ] && echo " Release name: $RELEASENAME"
[ -n "$DATE" ] && echo " Build date: $DATE"
[ -n "$VERSION" ] && echo " Grml version: $VERSION"
[ -n "$SUITE" ] && echo " Debian suite: $SUITE"
[ -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 "$BOOTID" ] && echo " Boot identifier: $BOOTID"
[ -n "$NO_BOOTID" ] && echo " Skipping bootid feature."
[ -n "$DEFAULT_BOOTOPTIONS" ] && echo " Adding default bootoptions: \"$DEFAULT_BOOTOPTIONS\""
[ -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."
[ -n "$SQUASHFS_OPTIONS" ] && echo " Using SQUASHFS_OPTIONS ${SQUASHFS_OPTIONS}"
[ -n "$VERBOSE" ] && echo " Using VERBOSE mode."
[ -n "$UPDATE" ] && echo " Executing UPDATE instead of fresh installation."
[ -n "$SKIP_MKSQUASHFS" ] && echo " Skipping creation of SQUASHFS file."
[ -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."
echo
echo -n "Is this ok for you? [y/N] "
read a
if ! [ "$a" = 'y' -o "$a" = 'Y' ] ; then
bailout 1 "Exiting as requested."
fi
echo
fi
# }}}
# clean/zero/remove logfiles {{{
if [ -n "$PRESERVE_LOGFILE" ] ; then
echo "Preserving logfile $LOGFILE as requested via \$PRESERVE_LOGFILE"
else
# make sure it is empty (as it is e.g. appended to grml-live-db)
echo -n > $LOGFILE
fi
if [ -n "$ZERO_FAI_LOGFILE" ] ; then
if [ -d /var/log/fai/"$HOSTNAME" ] ; then
rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last)"
rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-dirinstall)"
rm -rf /var/log/fai/"$HOSTNAME"/"$(readlink /var/log/fai/"$HOSTNAME"/last-softupdate)"
rm -f /var/log/fai/"$HOSTNAME"/last \
/var/log/fai/"$HOSTNAME"/last-dirinstall \
/var/log/fai/"$HOSTNAME"/last-softupdate
fi
fi
# }}}
# source config and startup {{{
if [ -n "$CONFIG" ] ; then
if ! [ -f "$CONFIG" ] ; then
log "Error: $CONFIG could not be read. Exiting. [$(date)]"
eerror "Error: $CONFIG could not be read. Exiting." ; eend 1
bailout 1
else
log "Sourcing $CONFIG"
. $CONFIG
fi
fi
start_seconds=$(cut -d . -f 1 /proc/uptime)
log "------------------------------------------------------------------------------"
log "Starting grml-live [${GRML_LIVE_VERSION}] run on $(date)"
log "Executed grml-live command line:"
log "$CMDLINE"
einfo "Logging actions to logfile $LOGFILE"
# }}}
# on-the-fly configuration {{{
if [ -n "$MIRROR_DIRECTORY" ] ; then
if ! [ -d "$MIRROR_DIRECTORY/debian" ] ; then
log "Error: $MIRROR_DIRECTORY/debian does not seem to exist. Exiting. [$(date)]"
eerror "Error: $MIRROR_DIRECTORY/debian does not seem to exist. Exiting." ; eend 1
bailout 1
fi
cat > "$SOURCES_LIST_FILE" << EOF
# NOTE: This file is *NOT* meant for manual customisation! This file is
# modified by grml-live and any changes might be overriden.
# You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
# or FAI's fcopy command with /etc/grml/fai/config/files instead!
EOF
echo "$MIRROR_SOURCES" >> "$SOURCES_LIST_FILE"
if [ -n "$GRML_LIVE_SOURCES" ] ; then
echo "$GRML_LIVE_SOURCES" >> "$SOURCES_LIST_FILE"
fi
elif [ -n "$GRML_LIVE_SOURCES" ] ; then
cat > "$SOURCES_LIST_FILE" << EOF
# NOTE: This file is *NOT* meant for manual customisation! This file is
# modified by grml-live and any changes might be overriden.
# You might consider using GRML_LIVE_SOURCES in /etc/grml/grml-live.conf*
# or FAI's fcopy command with /etc/grml/fai/config/files instead!
EOF
echo "$GRML_LIVE_SOURCES" >> "$SOURCES_LIST_FILE"
fi
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':
case $SUITE in
unstable) SUITE='sid' ;;
# make sure that we *NEVER* write any broken suite name to sources.list,
# otherwise we won't be able to adjust it one next (correct) execution
stable) ;;
testing) ;;
etch) ;;
lenny) ;;
squeeze) ;;
sid) ;;
*) echo "Sorry, $SUITE is not a valid Debian suite, exiting.">&2; bailout 1 ;;
esac
DIST=" etch\| stable\| lenny\| squeeze\| testing\| sid\| unstable"
sed "s/\(^deb .\+\)\([ \t]*\)\($DIST\)\([ \t]*\)\(main \)/\1 \2$SUITE\4\5/" "$SOURCES_LIST_FILE" | sponge "$SOURCES_LIST_FILE"
for file in "$LIVE_CONF" "$CONFIG" "$LOCAL_CONFIG" ; do
if [ -n "$file" ] ; then
sed "s/^SUITE=.*/SUITE=\"$SUITE\"/" $file | sponge $file
sed "s/\(^deb .\+\)\([ \t]*\)\($DIST\)\([ \t]*\)\(main \)/\1 \2$SUITE\4\5/" "$file" | sponge "$file"
fi
done
# notice: activate grml-live pool only if we are building against unstable:
if grep -qe unstable -qe sid "$SOURCES_LIST_FILE" ; then
grep -q 'grml-live.*main' "$SOURCES_LIST_FILE" || \
grep grml-stable "$SOURCES_LIST_FILE" | \
sed 's/grml-stable/grml-live/' >> "$SOURCES_LIST_FILE"
else
grep -q 'grml-live.*main' "$SOURCES_LIST_FILE" && \
sed 's/.*grml-live.*/# removed grml-live repository/' "$SOURCES_LIST_FILE" | sponge "$SOURCES_LIST_FILE"
fi
for file in "$LIVE_CONF" "$CONFIG" "$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 ! [[ "$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?)."
eerror "Tip: Either invoke grml-live with '-a i386' or adjust the architecture class. Exiting."
eend 1
bailout
fi
elif echo $CLASSES | grep -qi amd64 ; then
if ! [[ "$ARCH" == "amd64" ]] ; then
log "Error: You specified the AMD64 class but are trying to build something else (I386?)."
eerror "Error: You specified the AMD64 class but are trying to build something else (I386?)."
eerror "Tip: Either invoke grml-live with '-a amd64' or adjust the architecture class. Exiting."
eend 1
bailout
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"
fi
# }}}
# CHROOT_OUTPUT - execute FAI {{{
if [ -n "$BUILD_DIRTY" ]; then
log "Skipping stage 'fai' as requested via option -B"
ewarn "Skipping stage 'fai' as requested via option -B" ; eend 0
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
FAI_ACTION=dirinstall
fi
if [ -n "$UPDATE" -o -n "$BUILD_ONLY" ] ; 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
bailout 20
fi
fi
if [ -d "$CHROOT_OUTPUT/bin" -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
log "Skiping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already."
ewarn "Skiping stage 'fai dirinstall' as $CHROOT_OUTPUT exists already." ; eend 0
else
mkdir -p "$CHROOT_OUTPUT" || bailout 5 "Problem with creating $CHROOT_OUTPUT for FAI"
if [ -n "${MIRROR_DIRECTORY}" ] ; then
mkdir -p "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
mount --bind "${MIRROR_DIRECTORY}" "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
fi
log "Executed FAI command line:"
log "BUILD_ONLY=$BUILD_ONLY fai $VERBOSE -C $GRML_FAI_CONFIG -c$CLASSES -u $HOSTNAME $FAI_ACTION $CHROOT_OUTPUT $FAI_ARGS"
BUILD_ONLY="$BUILD_ONLY" fai $VERBOSE -C "$GRML_FAI_CONFIG" -c"$CLASSES" -u \
"$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: 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
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 the initramfs:
# chroot $CHROOT_OUTPUT update-initramfs -u -t => might break when using kernel-package :(
chroot $CHROOT_OUTPUT update-initramfs -u -k all
eend $?
fi
# Remove all FAI logs from chroot if class RELEASE is used:
if [ -f "$CHROOT_OUTPUT"/etc/grml_fai_release ] ; then
rm -rf "$CHROOT_OUTPUT"/var/log/fai/*
fi
# make sure we don't leave any mounts - FAI doesn't remove them always
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
umount $CHROOT_OUTPUT/dev 2>/dev/null || /bin/true
[ -n "$MIRROR_DIRECTORY" ] && umount "${CHROOT_OUTPUT}/${MIRROR_DIRECTORY}"
# notice: 'fai dirinstall' does not seem to exit appropriate, so:
ERROR=''
CHECKLOG=/var/log/fai/$HOSTNAME/last
if [ -r "$CHECKLOG/software.log" ] ; then
# 1 errors during executing of commands
grep 'dpkg: error processing' $CHECKLOG/software.log >> $LOGFILE && ERROR=1
grep 'E: Method http has died unexpectedly!' $CHECKLOG/software.log >> $LOGFILE && ERROR=2
grep 'ERROR: chroot' $CHECKLOG/software.log >> $LOGFILE && ERROR=3
grep 'E: Failed to fetch' $CHECKLOG/software.log >> $LOGFILE && ERROR=4
grep 'Unable to write mmap - msync (28 No space left on device)' $CHECKLOG/software.log >> $LOGFILE && ERROR=5
fi
if [ -r "$CHECKLOG/shell.log" ] ; then
grep 'FAILED with exit code' $CHECKLOG/shell.log >> $LOGFILE && ERROR=2
fi
if [ -n "$ERROR" ] ; then
log "Error: there was a critical error [${ERROR}] during execution of stage 'fai dirinstall' [$(date)]"
eerror "Error: there was a critical error during execution of stage 'fai dirinstall'"
eerror "Note: check out ${CHECKLOG}/ for details. [exit ${ERROR}]"
eend 1
bailout 1
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 [ -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
# }}}
# BUILD_OUTPUT - execute arch specific stuff and squashfs {{{
[ -n "$BUILD_OUTPUT" ] || BUILD_OUTPUT="$OUTPUT/grml_cd"
mkdir -p "$BUILD_OUTPUT" || bailout 6 "Problem with creating $BUILD_OUTPUT for stage ARCH"
# i386:
if [ "$ARCH" = i386 ] || [ "$ARCH" = amd64 ] ; then
if [ -d "$BUILD_OUTPUT"/boot/isolinux -a -z "$UPDATE" -a -z "$BUILD_ONLY" ] ; then
log "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already."
ewarn "Skipping stage 'boot' as $BUILD_OUTPUT/boot/isolinux exists already." ; eend 0
else
# booting stuff:
[ -d "$BUILD_OUTPUT"/boot/isolinux ] || mkdir -p "$BUILD_OUTPUT"/boot/isolinux
[ -d "$BUILD_OUTPUT"/boot/"${SHORT_NAME}" ] || mkdir -p "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"
if [ -z "$NO_ADDONS" ] ; then
[ -d "$BUILD_OUTPUT"/boot/addons ] || mkdir -p "$BUILD_OUTPUT"/boot/addons
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 (either install package grml-live-addons or memtest86+), skipping."
log "No memtest binary found (either install package grml-live-addons or memtest86+), skipping."
eend 0
fi
fi
# 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)"
if [ -n "$INITRD" ] ; then
cp $INITRD "$BUILD_OUTPUT"/boot/"${SHORT_NAME}"/initrd.gz
find $CHROOT_OUTPUT/boot/ -name initrd\*.bak -exec rm {} \;
else
log "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting"
eerror "Error: No initrd found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
bailout 10
fi
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
else
log "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting"
eerror "Error: No kernel found inside $CHROOT_OUTPUT/boot/ - Exiting" ; eend 1
bailout 11
fi
[ -n "$TEMPLATE_DIRECTORY" ] || TEMPLATE_DIRECTORY='/usr/share/grml-live/templates'
if ! [ -d "${TEMPLATE_DIRECTORY}"/boot ] ; then
log "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting."
eerror "Error: ${TEMPLATE_DIRECTORY}/boot does not exist. Exiting." ; eend 1
bailout 8
fi
# *always* copy files to output directory so the variables
# get adjusted according to the build
cp ${TEMPLATE_DIRECTORY}/boot/isolinux/* "$BUILD_OUTPUT"/boot/isolinux/
if [ -n "$NO_ADDONS" ] ; then
log "Skipping installation of boot addons as requested via \$NO_ADDONS."
einfo "Skipping installation of boot addons as requested via \$NO_ADDONS."; eend 0
else
if ! [ -d "$TEMPLATE_DIRECTORY"/boot/addons ] ; then
log "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)"
ewarn "Boot addons not found, skipping therefore. (Consider installing package grml-live-addons)" ; eend 0
else
# copy only files so we can handle bsd4grml on its own
for file in ${TEMPLATE_DIRECTORY}/boot/addons/* ; do
test -f $file && cp $file "$BUILD_OUTPUT"/boot/addons/
done
if [ -n "$NO_ADDONS_BSD4GRML" ] ; then
log "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."
einfo "Skipping installation of bsd4grml as requested via \$NO_ADDONS_BSD4GRML."; eend 0
else
if [ -d "$TEMPLATE_DIRECTORY"/boot/addons/bsd4grml ] ; then
cp -a ${TEMPLATE_DIRECTORY}/boot/addons/bsd4grml "$BUILD_OUTPUT"/boot/addons/
else
log "bsd4grml addon not found, skipping therefore."
ewarn "bsd4grml addon not found, skipping therefore." ; eend 0
fi
fi
fi # no "$TEMPLATE_DIRECTORY"/boot/addons
fi # NO_ADDONS
if ! [ -d ${TEMPLATE_DIRECTORY}/boot/grub ] ; then
log "grub templates do not exist, skipping therefore."
ewarn "grub templates do not exist, skipping therefore." ; eend 0
else
if ! [ -d "${BUILD_OUTPUT}/boot/grub" ] ; then
cp -a ${TEMPLATE_DIRECTORY}/boot/grub "$BUILD_OUTPUT"/boot/
fi
# make sure we have recent template files available, otherwise updating
# the strings like $GRML_NAME and $VERSION might be out of date
cp ${TEMPLATE_DIRECTORY}/boot/grub/* "$BUILD_OUTPUT"/boot/grub/
fi
if ! [ -d "${TEMPLATE_DIRECTORY}"/GRML ] ; then
log "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting."
eerror "Error: ${TEMPLATE_DIRECTORY}/GRML does not exist. Exiting." ; eend 1
bailout 9
fi
[ -d "$BUILD_OUTPUT"/GRML ] || mkdir "$BUILD_OUTPUT"/GRML
cp -a ${TEMPLATE_DIRECTORY}/GRML/* "$BUILD_OUTPUT"/GRML/
# 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-version ] ; then
sed -i "s/%RELEASE_INFO%/$GRML_NAME $VERSION - $RELEASENAME/" "$BUILD_OUTPUT"/GRML/grml-version
sed -i "s/%DATE%/$DATE/" "$BUILD_OUTPUT"/GRML/grml-version
fi
# make sure the squashfs filename is set accordingly:
SQUASHFS_NAME="$GRML_NAME.squashfs"
if [ -n "$NO_BOOTID" ] ; then
log 'Skipping bootid feature as requested via $NO_BOOTID.'
einfo 'Skipping bootid feature as requested via $NO_BOOTID.'
else
[ -n "$BOOTID" ] || BOOTID="$(echo ${GRML_NAME}${VERSION} | tr -d ',./;\- ')"
[ -d "$BUILD_OUTPUT"/conf ] || mkdir "$BUILD_OUTPUT"/conf
einfo "Generating /conf/bootid.txt with entry ${BOOTID}."
log "Generating /conf/bootid.txt with entry ${BOOTID}."
echo "$BOOTID" > "$BUILD_OUTPUT"/conf/bootid.txt
eend $?
fi
# adjust all variables in the templates with the according distribution information
for file in "${BUILD_OUTPUT}"/boot/isolinux/*.cfg "${BUILD_OUTPUT}"/boot/isolinux/*.msg \
"${BUILD_OUTPUT}"/boot/grub/* ; do
if [ -r "${file}" ] ; then
sed -i "s/%ARCH%/$ARCH/g" "${file}"
sed -i "s/%DATE%/$DATE/g" "${file}"
sed -i "s/%DISTRI_INFO%/$DISTRI_INFO/g" "${file}"
sed -i "s/%DISTRI_NAME%/$DISTRI_NAME/g" "${file}"
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/%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}"
if [ -n "$NO_BOOTID" ] ; then
sed -i "s/ bootid=%BOOTID%//g" "${file}" # drop bootid bootoption
else
sed -i "s/%BOOTID%/$BOOTID/g" "${file}" # adjust bootid=... argument
fi
fi
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")"
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 "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
for name in $(ls "${BUILD_OUTPUT}"/boot/isolinux/addon_*.cfg) ; do
include_name=$(basename "$name")
echo "include $include_name" >> "${BUILD_OUTPUT}/${ADDONS_LIST_FILE}"
done
if ! [ -r "${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg" ] || [ "$DISTRI_NAME" = "grml" ] ; then
log "including grmlmain.cfg in ${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
echo "include grmlmain.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
echo "include default.cfg" > "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
echo "include menuoptions.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
echo "include grml.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
for f in "${BUILD_OUTPUT}"/boot/isolinux/submenu*.cfg ; do
echo "include $(basename $f)" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
done
echo "include options.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
if [ ! -n "$NO_ADDONS" ] ; then
echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
fi
echo "include isoprompt.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
echo "include hd.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
echo "include hidden.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/grmlmain.cfg"
else # assume we are building a custom distribution:
log "File ${BUILD_OUTPUT}/boot/isolinux/${DISTRI_NAME}.cfg found, using it."
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"
echo "include ${DISTRI_NAME}.cfg" > "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
[ -n "$NO_ADDONS" ] || echo "include addons.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/distri.cfg"
fi
fi
# use old style console based isolinux method only if requested:
if [[ "${ISOLINUX_METHOD}" == "console" ]] ; then
log 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
einfo 'Using console based isolinux method as requested via $ISOLINUX_METHOD.'
if grep -q '^include console.cfg' "${BUILD_OUTPUT}/boot/isolinux/distri.cfg" ; then
einfo "include for console.cfg already foud, nothing to do."
eend 0
else
log "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
einfo "including console.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
echo "include console.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
eend $?
fi
else
log 'Using graphical boot menu.'
if grep -q '^include vesamenu.cfg' "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg" ; then
log "include for vesamenu.cfg already foud, nothing to do."
else
log "including vesamenu.cfg in ${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
echo "include vesamenu.cfg" >> "${BUILD_OUTPUT}/boot/isolinux/isolinux.cfg"
fi
fi
# jump back to grub from bsd4grml (/boot/grub/stage2):
GRUB_LEGACY=stage2
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
for file in "$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.6 \
"$BUILD_OUTPUT"/boot/addons/bsd4grml/boot.cfg \
"$BUILD_OUTPUT"/boot/isolinux/*.cfg \
"$BUILD_OUTPUT"/boot/grub/grub.cfg \
"$BUILD_OUTPUT"/boot/grub/menu.lst ; do
if [ -e "$file" ] ; then
sed -i -e "s!%GRUB_VERSION%!$GRUB_VERSION!g" \
-e "s!%GRUB_LEGACY%!$GRUB_LEGACY!g" "$file"
fi
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
elif [ -e "$BUILD_OUTPUT"/boot/grub/menu.lst -a -e "$BUILD_OUTPUT"/boot/grub/grub.cfg ] ; then
sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/menu.lst
sed -i "/%GRUB_LEGACY%/d" "$BUILD_OUTPUT"/boot/grub/grub.cfg
fi
DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot
if ! [ -r "$DPKG_LIST" ] ; then
ewarn "$DPKG_LIST could not be read, ignoring to store package information on ISO therefore."
else
einfo "Storing package list information as /GRML/${GRML_NAME}-packages.txt on ISO."
cp "$DPKG_LIST" "${BUILD_OUTPUT}/GRML/${GRML_NAME}-packages.txt"
eend $?
fi
# autostart for Windows:
if [ -d "${TEMPLATE_DIRECTORY}/windows/autostart/" ] ; then
cp ${TEMPLATE_DIRECTORY}/windows/autostart/* "$BUILD_OUTPUT"/
fi
# windows-binaries:
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 "Skipping stage 'WINDOWS_BINARIES' as $BUILD_OUTPUT/windows exists already."
ewarn "Skipping stage 'WINDOWS_BINARIES' as $BUILD_OUTPUT/windows exists already." ; eend 0
else
if ! [ -d "$BUILD_OUTPUT"/windows ] ; then
mkdir "$BUILD_OUTPUT"/windows
( cd "$BUILD_OUTPUT"/windows
for file in pageant plink pscp psftp putty puttygen ; do
wget -O ${file}.exe ${WINDOWS_BINARIES}/${file}.exe
md5sum ${file}.exe > ${file}.exe.md5
done )
fi
log "Finished execution of stage 'WINDOWS_BINARIES' [$(date)]"
einfo "Finished execution of stage 'WINDOWS_BINARIES'" ; eend 0
fi
fi
FORCE_ISO_REBUILD=true
einfo "Finished execution of stage 'boot'" ; eend 0
fi
else
log 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!'
eerror 'Error: Unsupported ARCH, sorry. Want to support it? Contribute!' ; eend 1
bailout
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 "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already."
ewarn "Skipping stage 'squashfs' as $BUILD_OUTPUT/live exists already." ; eend 0
elif [ -n "$SKIP_MKSQUASHFS" ] ; then
log "Skipping stage 'squashfs' as requested via option -q"
ewarn "Skipping stage 'squashfs' as requested via option -q" ; eend 0
else
[ -d "$BUILD_OUTPUT"/live ] || mkdir "$BUILD_OUTPUT"/live
# make sure we don't leave (even an empty) base.tgz:
[ -f "$CHROOT_OUTPUT/base.tgz" ] && rm -f "$CHROOT_OUTPUT/base.tgz"
# $SQUASHFS_BINARY is specified in the configuration:
if [ -n "$SQUASHFS_BINARY" ] ; then
if ! which "$SQUASHFS_BINARY" >/dev/null 2>&1 ; then
log "Error: specified mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting."
eerror "Error: specified mksquashfs binary ($SQUASHFS_BINARY) not found. Exiting." ; eend 1
bailout
fi
else # no $SQUASHFS_BINARY configured, let's find the according binary:
# Note: this is ALL for backward compatibility and yes: it's serious PITA.
# We'll definitely drop this once people build >2.6.28-grml* only and
# the squashfs-tools vs. squashfs-lzma-tools + zlib vs. lzma situation
# is settling...
# assume the safe default if mksquashfs-lzma isn't present:
if ! which mksquashfs-lzma >/dev/null 2>&1 ; then
SQUASHFS_BINARY='mksquashfs'
else # mksquashfs-lzma is available since squashfs-lzma-tools 4.0:
# if the user wants to use zlib then don't use mksquashfs-lzma:
if echo "$SQUASHFS_OPTIONS" | grep -q -- "-nolzma" || [ -n "$SQUASHFS_ZLIB" ] ; then
SQUASHFS_BINARY='mksquashfs'
else # neither -nolzma nor -z and mksquashfs-lzma is available:
SQUASHFS_BINARY='mksquashfs-lzma'
# backwards compatibility: someone has squashfs-lzma-tools >=4 installed but
# 1) doesn't use -nolzma in $SQUASHFS_OPTIONS or the grml-live's -z option *and*
# 2) builds against kernel version <=2.6.28-grml[64]
if ls $CHROOT_OUTPUT/boot/vmlinuz* >/dev/null 2>&1 ; then
KERNEL_IMAGE="$(ls $CHROOT_OUTPUT/boot/vmlinuz* 2>/dev/null | sort -r | head -1)"
case $KERNEL_IMAGE in
*vmlinuz-2.6.28-grml*|*vmlinuz-2.6.26-grml*|*vmlinuz-2.6.23-grml*)
log "You seem to be building a system with squashfs file format 3 using squashfs-lzma-tools >=4."
ewarn "You seem to be building a system with squashfs file format 3 using squashfs-lzma-tools >=4."
ewarn "|-> Consider installing squashfs-lzma-tools 3.3-1 for support of file format version 3."
ewarn "|-> Trying the mksquashfs binary instead of mksquashfs-lzma (though this might fail)."
ewarn "\`-> Visit http://grml.org/grml-live/#current_state for further details if building fails."
eend 0
SQUASHFS_BINARY='mksquashfs'
;;
esac
fi
# if we still want to use mksquashfs-lzma then let's choose
# blocksize 256k as this gives best result with regards to time + comopression
[[ "$SQUASHFS_BINARY" == "mksquashfs-lzma" ]] && SQUASHFS_OPTIONS="-b 256k -lzma"
fi
fi
fi
# make sure mksquashfs can handle the according option:
if [ -n "$SQUASHFS_ZLIB" ] ; then
$SQUASHFS_BINARY --help 2>&1 | grep -q -- "$SQUASHFS_ZLIB" || SQUASHFS_ZLIB=''
fi
# make sure to drop the -nolzma option if it's not available:
if echo "$SQUASHFS_OPTIONS" | grep -q -- "-nolzma" ; then
if ! $SQUASHFS_BINARY --help 2>&1 | grep -q -- '-nolzma' ; then
log "The $SQUASHFS_BINARY binary does NOT support the nolzma option, dropping it and using default mode."
ewarn "The $SQUASHFS_BINARY binary does NOT support the nolzma option, dropping it and using default mode."
SQUASHFS_OPTIONS="$(echo $SQUASHFS_OPTIONS | sed 's/-nolzma//g')"
eend 0
fi
fi
# make sure to drop the -lzma option if it's not available:
if echo "$SQUASHFS_OPTIONS" | grep -q -- "-lzma" ; then
if ! $SQUASHFS_BINARY --help 2>&1 | grep -q -- '-lzma' ; then
log "The $SQUASHFS_BINARY binary does NOT support the lzma option, dropping it and using default mode."
ewarn "The $SQUASHFS_BINARY binary does NOT support the lzma option, dropping it and using default mode."
SQUASHFS_OPTIONS="$(echo $SQUASHFS_OPTIONS | sed 's/-lzma//g')"
eend 0
fi
fi
# support exclusion of files via exclude-file:
if [ -n "$SQUASHFS_EXCLUDES_FILE" -a "$SQUASHFS_EXCLUDES_FILE" ] ; then
SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -ef $SQUASHFS_EXCLUDES_FILE"
fi
# get rid of unnecessary files when building grml-small for final release:
if echo "$CLASSES" | grep -q GRML_SMALL ; then
SQUASHFS_OPTIONS="$SQUASHFS_OPTIONS -e initrd.img* vmlinuz*"
fi
# check whether we have the according binary available:
if ! which $SQUASHFS_BINARY >/dev/null 2>&1 ; then
log "Error: mksquashfs binary (${SQUASHFS_BINARY}) could not be found. Exiting."
eerror "Error: mksquashfs binary (${SQUASHFS_BINARY}) could not be found. Exiting."
eerror "|-> Make sure to install either squashfs-tools and/or squashfs-lzma-tools."
eerror "\`-> Visit http://grml.org/grml-live/#current_state for further details."
eend 1
bailout
fi
SQUASHFS_STDERR="$(mktemp -t grml-live.XXXXXX)"
[ -n "$SQUASHFS_OPTIONS" ] && SQUASHFS_INFO_MSG="$SQUASHFS_OPTIONS"
[ -n "$SQUASHFS_ZLIB" ] && SQUASHFS_INFO_MSG="$SQUASHFS_INFO_MSG $SQUASHFS_ZLIB"
[ -n "$SQUASHFS_INFO_MSG" ] && SQUASHFS_INFO_MSG="using options: $SQUASHFS_INFO_MSG"
einfo "Squashfs build information: running binary $SQUASHFS_BINARY $SQUASHFS_INFO_MSG"
log "$SQUASHFS_BINARY $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/${GRML_NAME}.squashfs -noappend $SQUASHFS_OPTIONS $SQUASHFS_ZLIB"
if $SQUASHFS_BINARY $CHROOT_OUTPUT/* $BUILD_OUTPUT/live/"${GRML_NAME}".squashfs \
-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
else
log "Error: there was a critical error executing stage 'squashfs' [$(date)]:"
log "$(cat $SQUASHFS_STDERR)"
eerror "Error: there was a critical error executing stage 'squashfs':" ; eend 1
cat "${SQUASHFS_STDERR}"
bailout
fi
FORCE_ISO_REBUILD=true
fi
# create md5sum file:
( cd $BUILD_OUTPUT/GRML &&
find .. -type f -not -name md5sums -not -name isolinux.bin -exec md5sum {} \; > md5sums )
# }}}
# ISO_OUTPUT - mkisofs {{{
[ -n "$ISO_OUTPUT" ] || ISO_OUTPUT="$OUTPUT/grml_isos"
[ -n "$ISO_NAME" ] || ISO_NAME="${GRML_NAME}_${VERSION}.iso"
if [ "$BOOT_METHOD" = "isolinux" ] ; then
BOOT_FILE="boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat"
elif [ "$BOOT_METHOD" = "grub" ] ; then
BOOT_FILE="boot/grub/stage2"
fi
if [ -f "${ISO_OUTPUT}/${ISO_NAME}" -a -z "$UPDATE" -a -z "$BUILD_ONLY" -a -z "$BUILD_DIRTY" -a "$FORCE_ISO_REBUILD" = "false" ] ; then
log "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already."
ewarn "Skipping stage 'iso build' as $ISO_OUTPUT/${ISO_NAME} exists already." ; eend 0
elif [ -n "$SKIP_MKISOFS" ] ; then
log "Skipping stage 'iso build' as requested via option -n"
ewarn "Skipping stage 'iso build' as requested via option -n" ; eend 0
else
mkdir -p "$ISO_OUTPUT" || bailout 6 "Problem with creating $ISO_OUTPUT for stage 'iso build'"
if $FORCE_ISO_REBUILD && ! [ -f "${ISO_OUTPUT}/${ISO_NAME}" ] ; 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'
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
bailout
fi
CURRENT_DIR=$(pwd)
if cd "$BUILD_OUTPUT" ; then
log "$MKISOFS -V '${GRML_NAME} ${VERSION}' -publisher 'grml-live | grml.org' -l -r -J -no-emul-boot -boot-load-size 4 -boot-info-table -b $BOOT_FILE -o ${ISO_OUTPUT}/${ISO_NAME} ."
"$MKISOFS" -V "${GRML_NAME} ${VERSION}" -publisher 'grml-live | grml.org' \
-l -r -J -no-emul-boot -boot-load-size 4 -boot-info-table \
-b $BOOT_FILE -no-pad \
-o "${ISO_OUTPUT}/${ISO_NAME}" . ; RC=$?
# pad the output ISO to multiples of 256 KiB for partition table support
siz=$($getfilesize "${ISO_OUTPUT}/${ISO_NAME}")
cyls=$((siz / 512 / 32 / 16 + 1)) # C=$cyls H=16 S=32
siz=$((cyls * 16 * 32 * 512)) # size after padding
dd if=/dev/zero bs=1 count=1 seek=$((siz - 1)) \
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
# 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
if ! [ -r boot/grub/core.img ] ; then
ewarn "boot/grub/core.img not found, not creating manifold boot ISO file"
else
log "Creating hybrid ISO file with manifold method"
einfo "Creating hybrid ISO file with manifold 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
# pad to a whole of 2048 bytes (one CD sector)
dd if=/dev/zero bs=512 count=3 2>/dev/null
# append GRUB 2 (must be <=30720 bytes)
cat boot/grub/core.img
) | dd of="${ISO_OUTPUT}/${ISO_NAME}" conv=notrunc 2>/dev/null
eend $?
fi
fi
# generate md5sum and sha1sum of ISO if we are using class 'RELEASE':
case $CLASSES in *RELEASE*)
[ "$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
fi
)
;;
esac
cd $CURRENT_DIR
fi
if [ "$RC" = 0 ] ; then
log "Finished execution of stage 'iso build' [$(date)]"
einfo "Finished execution of stage 'iso build'" ; eend 0
else
log "Error: there was a critical error ($RC) executing stage 'iso build' [$(date)]"
eerror "Error: there was a critical error executing stage 'iso build'" ; eend 1
bailout $RC
fi
fi
# }}}
# log build information to database if grml-live-db is installed and enabled {{{
dpkg_to_db() {
if [ -d /usr/share/grml-live-db ] ; then
# safe defaults
DPKG_LIST="/var/log/fai/$HOSTNAME/last/dpkg.list" # the dpkg --list output of the chroot:
[ -n "$DPKG_DATABASE" ] || DPKG_DATABASE=/var/log/grml-live.db
[ -n "$DPKG_DBSCRIPT" ] || DPKG_DBSCRIPT=/usr/share/grml-live-db/scripts/dpkg-to-db
[ -n "$DPKG_DBOPTIONS" ] || DPKG_DBOPTIONS="--database $DPKG_DATABASE --logfile $LOGFILE --flavour $GRML_NAME --dpkg $DPKG_LIST"
if ! [ -x "$DPKG_DBSCRIPT" ] ; then
log "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information."
eerror "Error: $DPKG_DBSCRIPT is not executable, can not log dpkg information." ; eend 1
bailout 14
fi
# disable by default for now, not sure whether really everyone is using a local db file
#if ! touch "$DPKG_DATABASE" ; then
# eerror "Error: can not write to ${DPKG_DATABASE}, can not log dpkg information." ; eend 1
# bailout 14
#fi
if ! [ -r "$DPKG_LIST" ] ; then
log "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)"
ewarn "Warning: can not read $DPKG_LIST - can not provide information to $DPKG_DBSCRIPT (dirty build?)" ; eend 0
else
einfo "Logging $DPKG_LIST to database $DPKG_DATABASE"
log "Logging $DPKG_LIST to database $DPKG_DATABASE"
log "Executing $DPKG_DBSCRIPT $DPKG_DBOPTIONS"
eindent
if DB_INFO=$("$DPKG_DBSCRIPT" $DPKG_DBOPTIONS 2>&1) ; then
einfo "$DB_INFO"
eend 0
else
eerror "$DB_INFO"
eend 1
fi
eoutdent
fi
fi
}
# }}}
# finalize {{{
[ -n "$start_seconds" ] && SECONDS="$[$(cut -d . -f 1 /proc/uptime)-$start_seconds]" || SECONDS="unknown"
log "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]"
dpkg_to_db # make sure we catch the last log line as well, therefore execute between log + einfo
einfo "Successfully finished execution of $PN [$(date) - running ${SECONDS} seconds]" ; eend 0
bailout 0
# }}}
## END OF FILE #################################################################
# vim:foldmethod=marker ts=2 ft=sh ai expandtab tw=80 sw=3
Jump to Line
Something went wrong with that request. Please try again.