diff --git a/usr/bin/archboot-aarch64-create-container.sh b/usr/bin/archboot-aarch64-create-container.sh index 9e76423e0..535b8c537 100755 --- a/usr/bin/archboot-aarch64-create-container.sh +++ b/usr/bin/archboot-aarch64-create-container.sh @@ -36,5 +36,6 @@ if [[ "${_RUNNING_ARCH}" == "x86_64" ]]; then _clean_locale "${1}" _clean_container "${1}" || exit 1 fi +_reproducibility "${1}" _set_hostname "${1}" || exit 1 echo "Finished container setup in ${1} ." diff --git a/usr/bin/archboot-x86_64-create-container.sh b/usr/bin/archboot-x86_64-create-container.sh index 323bbcccb..3db54b5d8 100755 --- a/usr/bin/archboot-x86_64-create-container.sh +++ b/usr/bin/archboot-x86_64-create-container.sh @@ -32,6 +32,7 @@ if grep -q "^\[testing" /etc/pacman.conf; then sed -i -e '/^#\[community-testing\]/ { n ; s/^#// }' "${1}/etc/pacman.conf" sed -i -e 's:^#\[testing\]:\[testing\]:g' -e 's:^#\[community-testing\]:\[community-testing\]:g' "${1}/etc/pacman.conf" fi +_reproducibility "${1}" _set_hostname "${1}" || exit 1 echo "Finished container setup in ${1} ." diff --git a/usr/lib/archboot/container_functions b/usr/lib/archboot/container_functions index 80eda3668..8b453e933 100644 --- a/usr/lib/archboot/container_functions +++ b/usr/lib/archboot/container_functions @@ -166,6 +166,13 @@ _copy_mirrorlist_and_pacman_conf() { grep -qw 'archboot' /etc/hostname && cp /etc/pacman.conf "${1}"/etc/pacman.conf } +_reproducibility() { + echo "Reproducibility changes ..." + sed -i -e '/INSTALLDATE/{n;s/.*/0/}' "${1}"/var/lib/pacman/local/*/desc + rm "${1}"/var/cache/ldconfig/aux-cache + rm "${1}"/etc/ssl/certs/java/cacerts +} + _set_hostname() { echo "Setting hostname to archboot ..." echo 'archboot' > "${1}/etc/hostname" diff --git a/usr/lib/archboot/iso_functions b/usr/lib/archboot/iso_functions index 7f5d92712..b081a45a2 100644 --- a/usr/lib/archboot/iso_functions +++ b/usr/lib/archboot/iso_functions @@ -56,9 +56,13 @@ _prepare_kernel_initramfs_files() { # remove on mkinitcpio 32 release cp "/usr/lib/initcpio/functions" "/usr/lib/initcpio/functions.old" [[ -f "/usr/share/archboot/patches/31-initcpio.functions.fixed" ]] && cp "/usr/share/archboot/patches/31-initcpio.functions.fixed" "/usr/lib/initcpio/functions" + cp "/usr/bin/mkinitcpio" "/usr/bin/mkinitcpio.old" + [[ -f "/usr/share/archboot/patches/31-mkinitcpio.fixed" ]] && cp "/usr/share/archboot/patches/31-mkinitcpio.fixed" "/usr/bin/mkinitcpio" + #shellcheck disable=SC2154 mkinitcpio -c "${MKINITCPIO_CONFIG}" -k "${ALL_kver}" -g "${_ISODIR}/boot/initramfs_${_RUNNING_ARCH}.img" || exit 1 mv "/usr/lib/initcpio/functions.old" "/usr/lib/initcpio/functions" + mv "/usr/bin/mkinitcpio.old" "/usr/bin/mkinitcpio" install -m644 "${ALL_kver}" "${_ISODIR}/boot/vmlinuz_${_RUNNING_ARCH}" # install ucode files [[ "${_RUNNING_ARCH}" == "aarch64" ]] || cp /boot/intel-ucode.img "${_ISODIR}/boot/" diff --git a/usr/share/archboot/patches/31-mkinitcpio.fixed b/usr/share/archboot/patches/31-mkinitcpio.fixed new file mode 100644 index 000000000..bd0a2e221 --- /dev/null +++ b/usr/share/archboot/patches/31-mkinitcpio.fixed @@ -0,0 +1,732 @@ +#!/bin/bash +# +# mkinitcpio - modular tool for building an initramfs images +# + +declare -r version=31 + +shopt -s extglob + +### globals within mkinitcpio, but not intended to be used by hooks + +# needed files/directories +_f_functions=/usr/lib/initcpio/functions +_f_config=/etc/mkinitcpio.conf +_d_hooks=/etc/initcpio/hooks:/usr/lib/initcpio/hooks +_d_install=/etc/initcpio/install:/usr/lib/initcpio/install +_d_flag_hooks= +_d_flag_install= +_d_firmware=({/usr,}/lib/firmware/updates {/usr,}/lib/firmware) +_d_presets=/etc/mkinitcpio.d + +# options and runtime data +_optmoduleroot= _optgenimg= +_optcompress= _opttargetdir= +_optosrelease= +_optuefi= _optmicrocode=() _optcmdline= _optsplash= _optkernelimage= _optuefistub= +_optshowautomods=0 _optsavetree=0 _optshowmods=0 +_optquiet=1 _optcolor=1 +_optskiphooks=() _optaddhooks=() _hooks=() _optpreset=() +declare -A _runhooks _addedmodules _modpaths _autodetect_cache + +# export a sane PATH +export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' + +# Sanitize environment further +# GREP_OPTIONS="--color=always" will break everything +# CDPATH can affect cd and pushd +# LIBMOUNT_* options can affect findmnt and other tools +unset GREP_OPTIONS CDPATH "${!LIBMOUNT_@}" + +usage() { + cat < Add specified hooks, comma separated, to image + -c, --config Use alternate config file. (default: /etc/mkinitcpio.conf) + -g, --generate Generate cpio image and write to specified path + -H, --hookhelp Display help for given hook and exit + -h, --help Display this message and exit + -k, --kernel Use specified kernel version (default: $(uname -r)) + -L, --listhooks List all available hooks + -M, --automods Display modules found via autodetection + -n, --nocolor Disable colorized output messages + -p, --preset Build specified preset from /etc/mkinitcpio.d + -P, --allpresets Process all preset files in /etc/mkinitcpio.d + -r, --moduleroot Root directory for modules (default: /) + -S, --skiphooks Skip specified hooks, comma-separated, during build + -s, --save Save build directory. (default: no) + -d, --generatedir Write generated image into + -t, --builddir Use DIR as the temporary build directory + -D, --hookdir Specify where to look for hooks + -U, --uefi Build an UEFI executable + -V, --version Display version information and exit + -v, --verbose Verbose output (default: no) + -z, --compress Use an alternate compressor on the image + + Options for UEFI executable (-U, --uefi): + --cmdline Set kernel command line from file + (default: /etc/kernel/cmdline or /proc/cmdline) + --microcode Location of microcode + --osrelease Include os-release (default: /etc/os-release) + --splash Include bitmap splash + --kernelimage Kernel image + --uefistub Location of UEFI stub loader + +EOF +} + +version() { + cat < "$_d_workdir/autodetect_modules" + msg "build directory saved in %s" "$_d_workdir" + else + rm -rf "$_d_workdir" + fi + fi + + exit "$err" +} + +resolve_kernver() { + local kernel=$1 arch= + + if [[ -z $kernel ]]; then + uname -r + return 0 + fi + + if [[ ${kernel:0:1} != / ]]; then + echo "$kernel" + return 0 + fi + + if [[ ! -e $kernel ]]; then + error "specified kernel image does not exist: \`%s'" "$kernel" + return 1 + fi + + kver "$kernel" && return + + error "invalid kernel specified: \`%s'" "$1" + + arch=$(uname -m) + if [[ $arch != @(i?86|x86_64) ]]; then + error "kernel version extraction from image not supported for \`%s' architecture" "$arch" + error "there's a chance the generic version extractor may work with a valid uncompressed kernel image" + fi + + return 1 +} + +hook_help() { + local resolved script=$(PATH=$_d_install type -p "$1") + + # this will be true for broken symlinks as well + if [[ -z $script ]]; then + error "Hook '%s' not found" "$1" + return 1 + fi + + if resolved=$(readlink "$script") && [[ ${script##*/} != "${resolved##*/}" ]]; then + msg "This hook is deprecated. See the '%s' hook" "${resolved##*/}" + return 0 + fi + + . "$script" + if ! declare -f help >/dev/null; then + error "No help for hook $1" + return 1 + fi + + msg "Help for hook '$1':" + help + + list_hookpoints "$1" +} + +hook_list() { + local p hook resolved + local -a paths hooklist depr + local ss_ordinals=(¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹) + + IFS=: read -ra paths <<<"$_d_install" + + for path in "${paths[@]}"; do + for hook in "$path"/*; do + [[ -e $hook || -L $hook ]] || continue + + # handle deprecated hooks and point to replacement + if resolved=$(readlink "$hook") && [[ ${hook##*/} != "${resolved##*/}" ]]; then + resolved=${resolved##*/} + + if ! index_of "$resolved" "${depr[@]}"; then + # deprecated hook + depr+=("$resolved") + _idx=$(( ${#depr[*]} - 1 )) + fi + + hook+=${ss_ordinals[_idx]} + fi + + hooklist+=("${hook##*/}") + done + done + + msg "Available hooks" + printf '%s\n' "${hooklist[@]}" | sort -u | column -c"$(tput cols)" + + if (( ${#depr[*]} )); then + echo + for p in "${!depr[@]}"; do + printf $'%s This hook is deprecated in favor of \'%s\'\n' \ + "${ss_ordinals[p]}" "${depr[p]}" + done + fi +} + +compute_hookset() { + local h + + for h in "${HOOKS[@]}" "${_optaddhooks[@]}"; do + in_array "$h" "${_optskiphooks[@]}" && continue + _hooks+=("$h") + done +} + +build_image() { + local out=$1 compress=$2 errmsg pipestatus + + case $compress in + cat) + msg "Creating uncompressed initcpio image: %s" "$out" + unset COMPRESSION_OPTIONS + ;; + *) + msg "Creating %s-compressed initcpio image: %s" "$compress" "$out" + ;;& + xz) + COMPRESSION_OPTIONS=('--check=crc32' "${COMPRESSION_OPTIONS[@]}") + ;; + lz4) + COMPRESSION_OPTIONS=('-l' "${COMPRESSION_OPTIONS[@]}") + ;; + zstd) + COMPRESSION_OPTIONS=('-T0' "${COMPRESSION_OPTIONS[@]}") + ;; + esac + + pushd "$BUILDROOT" >/dev/null + + # Reproducibility: set all timestamps to 0 + find . -mindepth 1 -execdir touch -hcd "@0" "{}" + + + # If this pipeline changes, |pipeprogs| below needs to be updated as well. + find . -mindepth 1 -printf '%P\0' | + sort -z | + LANG=C bsdtar --uid 0 --gid 0 --null -cnf - -T - | + LANG=C bsdtar --null -cf - --format=newc @- | + $compress "${COMPRESSION_OPTIONS[@]}" > "$out" + + pipestatus=("${PIPESTATUS[@]}") + pipeprogs=('find' 'sort' 'bsdtar (step 1)' 'bsdtar (step 2)' "$compress") + + popd >/dev/null + + for (( i = 0; i < ${#pipestatus[*]}; ++i )); do + if (( pipestatus[i] )); then + errmsg="${pipeprogs[i]} reported an error" + break + fi + done + + if (( _builderrors )); then + warning "errors were encountered during the build. The image may not be complete." + fi + + if [[ $errmsg ]]; then + error "Image generation FAILED: %s" "$errmsg" + elif (( _builderrors == 0 )); then + msg "Image generation successful" + fi +} + +build_uefi(){ + local out=$1 initramfs=$2 cmdline=$3 osrelease=$4 splash=$5 kernelimg=$6 uefistub=$7 microcode=(${@:7}) errmsg= + OBJCOPYARGS=() + + msg "Creating UEFI executable: %s" "$out" + + if [[ -z "$uefistub" ]]; then + for stub in {/usr,}/lib/{systemd/boot/efi,gummiboot}/linux{x64,ia32}.efi.stub; do + if [[ -f "$stub" ]]; then + uefistub="$stub" + msg2 "Using UEFI stub: %s" "$uefistub" + break + fi + done + elif [[ ! -f "$uefisub" ]]; then + error "UEFI stub '%s' not found" "$uefistub" + return 1 + fi + + if [[ -z "$kernelimg" ]]; then + for img in "/lib/modules/$KERNELVERSION/vmlinuz" "/boot/vmlinuz-$KERNELVERSION" "/boot/vmlinuz-linux"; do + if [[ -f "$img" ]]; then + kernelimg="$img" + msg2 "Using kernel image: %s" "$kernelimg" + break + fi + done + fi + if [[ ! -f "$kernelimg" ]]; then + error "Kernel image '%s' not found" "$kernelimage" + return 1 + fi + + if [[ -z "$cmdline" ]]; then + if [[ -f "/etc/kernel/cmdline" ]]; then + cmdline="/etc/kernel/cmdline" + elif [[ -f "/usr/lib/kernel/cmdline" ]]; then + cmdline="/usr/lib/kernel/cmdline" + else + warning "Note: /etc/kernel/cmdline does not exist and --cmdline is unset!" + cmdline="/proc/cmdline" + warning "Reusing current kernel cmdline from $cmdline" + fi + msg2 "Using cmdline file: %s" "$cmdline" + fi + if [[ ! -f "$cmdline" ]]; then + error "Kernel cmdline file '%s' not found" "$cmdline" + return 1 + fi + + if [[ -z "$osrelease" ]]; then + if [[ -f "/etc/os-release" ]]; then + osrelease="/etc/os-release" + elif [[ -f "/usr/lib/os-release" ]]; then + osrelease="/usr/lib/os-release" + fi + msg2 "Using os-release file: %s" "$osrelease" + fi + if [[ ! -f "$osrelease" ]]; then + error "os-release file '%s' not found" "$osrelease" + return 1 + fi + + if [[ -z "$initramfs" ]]; then + error "Initramfs '%s' not found" "$initramfs" + return 1 + fi + + if [[ -n "$splash" ]]; then + OBJCOPYARGS+=(--add-section .splash="$splash" --change-section-vma .splash=0x40000) + msg2 "Using splash image: %s" "$splash" + fi + + for image in "${microcode[@]}"; do + msg2 "Using microcode image: %s" "$image" + done + + objcopy \ + --add-section .osrel="$osrelease" --change-section-vma .osrel=0x20000 \ + --add-section .cmdline=<(grep '^[^#]' "$cmdline" | tr -s '\n' ' ') --change-section-vma .cmdline=0x30000 \ + --add-section .linux="$kernelimg" --change-section-vma .linux=0x2000000 \ + --add-section .initrd=<(cat ${microcode[@]} "$initramfs") --change-section-vma .initrd=0x3000000 \ + ${OBJCOPYARGS[@]} "$uefistub" "$out" + + status=$? + if (( $status )) ; then + error "UEFI executable generation FAILED" + else + msg "UEFI executable generation successful" + fi +} + +process_preset() ( + local preset=$1 preset_cli_options=$2 preset_image= preset_options= + local -a preset_mkopts preset_cmd + if (( MKINITCPIO_PROCESS_PRESET )); then + error "You appear to be calling a preset from a preset. This is a configuration error." + cleanup 1 + fi + + # allow path to preset file, else resolve it in $_d_presets + if [[ $preset != */* ]]; then + printf -v preset '%s/%s.preset' "$_d_presets" "$preset" + fi + + . "$preset" || die "Failed to load preset: \`%s'" "$preset" + + (( ! ${#PRESETS[@]} )) && warning "Preset file \`%s' is empty or does not contain any presets." "$preset" + + # Use -m and -v options specified earlier + (( _optquiet )) || preset_mkopts+=(-v) + (( _optcolor )) || preset_mkopts+=(-n) + + (( _optsavetree )) && preset_mkopts+=(-s) + + ret=0 + for p in "${PRESETS[@]}"; do + msg "Building image from preset: $preset: '$p'" + preset_cmd=("${preset_mkopts[@]}") + + preset_kver=${p}_kver + if [[ ${!preset_kver:-$ALL_kver} ]]; then + preset_cmd+=(-k "${!preset_kver:-$ALL_kver}") + else + warning "No kernel version specified. Skipping image \`%s'" "$p" + continue + fi + + preset_config=${p}_config + if [[ ${!preset_config:-$ALL_config} ]]; then + preset_cmd+=(-c "${!preset_config:-$ALL_config}") + else + warning "No configuration file specified. Skipping image \`%s'" "$p" + continue + fi + + preset_image=${p}_image + if [[ ${!preset_image} ]]; then + preset_cmd+=(-g "${!preset_image}") + else + warning "No image file specified. Skipping image \`%s'" "$p" + continue + fi + + preset_options=${p}_options + if [[ ${!preset_options} ]]; then + preset_cmd+=(${!preset_options}) # intentional word splitting + fi + + preset_efi_image=${p}_efi_image + if [[ ${!preset_efi_image:-$ALL_efi_image} ]]; then + preset_cmd+=(-U "${!preset_efi_image:-$ALL_efi_image}") + fi + + preset_microcode=${p}_microcode[@] + if [[ ${!preset_microcode:-$ALL_microcode} ]]; then + for mc in "${!preset_microcode:-${ALL_microcode[@]}}"; do + preset_cmd+=(--microcode "$mc") + done + fi + + preset_cmd+=($OPTREST) + msg2 "${preset_cmd[*]}" + MKINITCPIO_PROCESS_PRESET=1 "$0" "${preset_cmd[@]}" + (( $? )) && ret=1 + done + + exit $ret +) + +preload_builtin_modules() { + local modname field value path + + # Prime the _addedmodules list with the builtins for this kernel. We prefer + # the modinfo file if it exists, but this requires a recent enough kernel + # and kmod>=27. + + if [[ -r $_d_kmoduledir/modules.builtin.modinfo ]]; then + while IFS=.= read -rd '' modname field value; do + _addedmodules[${modname//-/_}]=2 + case $field in + alias) + _addedmodules["${value//-/_}"]=2 + ;; + esac + done <"$_d_kmoduledir/modules.builtin.modinfo" + + elif [[ -r $_d_kmoduledir/modules.builtin ]]; then + while IFS=/ read -ra path; do + modname=${path[-1]%.ko} + _addedmodules["${modname//-/_}"]=2 + done <"$_d_kmoduledir/modules.builtin" + fi +} + +. "$_f_functions" + +trap 'cleanup 130' INT +trap 'cleanup 143' TERM + +_opt_short='A:c:D:g:H:hk:nLMPp:r:S:sd:t:U:Vvz:' +_opt_long=('add:' 'addhooks:' 'config:' 'generate:' 'hookdir': 'hookhelp:' 'help' + 'kernel:' 'listhooks' 'automods' 'moduleroot:' 'nocolor' 'allpresets' + 'preset:' 'skiphooks:' 'save' 'generatedir:' 'builddir:' 'version' 'verbose' 'compress:' + 'uefi:' 'microcode:' 'splash:' 'kernelimage:' 'uefistub:' 'cmdline:' 'osrelease:') + +parseopts "$_opt_short" "${_opt_long[@]}" -- "$@" || exit 1 +set -- "${OPTRET[@]}" +unset _opt_short _opt_long OPTRET + +while :; do + case $1 in + # --add remains for backwards compat + -A|--add|--addhooks) + shift + IFS=, read -r -a add <<< "$1" + _optaddhooks+=("${add[@]}") + unset add + ;; + -c|--config) + shift + _f_config=$1 + ;; + --cmdline) + shift + _optcmdline=$1 + ;; + -k|--kernel) + shift + KERNELVERSION=$1 + ;; + -s|--save) + _optsavetree=1 + ;; + -d|--generatedir) + shift + _opttargetdir=$1 + ;; + -g|--generate) + shift + [[ -d $1 ]] && die "Invalid image path -- must not be a directory" + if ! _optgenimg=$(readlink -f "$1") || [[ ! -e ${_optgenimg%/*} ]]; then + die "Unable to write to path: \`%s'" "$1" + fi + ;; + -h|--help) + usage + cleanup 0 + ;; + -V|--version) + version + cleanup 0 + ;; + -p|--preset) + shift + _optpreset+=("$1") + ;; + -n|--nocolor) + _optcolor=0 + ;; + -U|--uefi) + shift + [[ -d $1 ]] && die "Invalid image path -- must not be a directory" + if ! _optuefi=$(readlink -f "$1") || [[ ! -e ${_optuefi%/*} ]]; then + die "Unable to write to path: \`%s'" "$1" + fi + ;; + -v|--verbose) + _optquiet=0 + ;; + -S|--skiphooks) + shift + IFS=, read -r -a skip <<< "$1" + _optskiphooks+=("${skip[@]}") + unset skip + ;; + -H|--hookhelp) + shift + hook_help "$1" + exit + ;; + -L|--listhooks) + hook_list + exit 0 + ;; + --splash) + shift + [[ -f $1 ]] || die "Invalid file -- must be a file" + _optsplash=$1 + ;; + --kernelimage) + shift + _optkernelimage=$1 + ;; + --uefistub) + shift + _optkernelimage=$1 + ;; + -M|--automods) + _optshowautomods=1 + ;; + --microcode) + shift + _optmicrocode+=($1) + ;; + -P|--allpresets) + _optpreset=("$_d_presets"/*.preset) + [[ -e ${_optpreset[0]} ]] || die "No presets found in $_d_presets" + ;; + --osrelease) + shift + [[ ! -f $1 ]] && die "Invalid file -- must be a file" + _optosrelease=$1 + ;; + -t|--builddir) + shift + export TMPDIR=$1 + ;; + -z|--compress) + shift + _optcompress=$1 + ;; + -r|--moduleroot) + shift + _optmoduleroot=$1 + ;; + -D|--hookdir) + shift + _d_flag_hooks+="$1/hooks:" + _d_flag_install+="$1/install:" + ;; + --) + shift + break 2 + ;; + esac + shift +done + +OPTREST="$@" + +if [[ -t 1 ]] && (( _optcolor )); then + try_enable_color +fi + +if [[ -n $_d_flag_hooks && -n $_d_flag_install ]]; then + _d_hooks=${_d_flag_hooks%:} + _d_install=${_d_flag_install%:} +fi + + +# If we specified --uefi but no -g we want to create a temporary initramfs which will be used with the efi executable. +if [[ $_optuefi && $_optgenimg == "" ]]; then + tmpfile=$(mktemp -t mkinitcpio.XXXXXX) + trap "rm $tmpfile" EXIT + _optgenimg="$tmpfile" +fi + +# insist that /proc and /dev be mounted (important for chroots) +# NOTE: avoid using mountpoint for this -- look for the paths that we actually +# use in mkinitcpio. Avoids issues like FS#26344. +[[ -e /proc/self/mountinfo ]] || die "/proc must be mounted!" +[[ -e /dev/fd ]] || die "/dev must be mounted!" + +# use preset $_optpreset (exits after processing) +if (( ${#_optpreset[*]} )); then + map process_preset "${_optpreset[@]}" + exit +fi + +if [[ $KERNELVERSION != 'none' ]]; then + KERNELVERSION=$(resolve_kernver "$KERNELVERSION") || cleanup 1 + _d_kmoduledir=$_optmoduleroot/lib/modules/$KERNELVERSION + [[ -d $_d_kmoduledir ]] || die "'$_d_kmoduledir' is not a valid kernel module directory" +fi + +_d_workdir=$(initialize_buildroot "$KERNELVERSION" "$_opttargetdir") || cleanup 1 +BUILDROOT=${_opttargetdir:-$_d_workdir/root} + +. "$_f_config" || die "Failed to read configuration \`%s'" "$_f_config" + +arrayize_config + +# after returning, hooks are populated into the array '_hooks' +# HOOKS should not be referenced from here on +compute_hookset + +if (( ${#_hooks[*]} == 0 )); then + die "Invalid config: No hooks found" +fi + +if (( _optshowautomods )); then + msg "Modules autodetected" + PATH=$_d_install . 'autodetect' + build + printf '%s\n' "${!_autodetect_cache[@]}" | sort + cleanup 0 +fi + +if [[ $_optgenimg ]]; then + # check for permissions. if the image doesn't already exist, + # then check the directory + if [[ ( -e $_optgenimg && ! -w $_optgenimg ) || + ( ! -d ${_optgenimg%/*} || ! -w ${_optgenimg%/*} ) ]]; then + die 'Unable to write to %s' "$_optgenimg" + fi + + _optcompress=${_optcompress:-${COMPRESSION:-zstd}} + if ! type -P "$_optcompress" >/dev/null; then + warning "Unable to locate compression method: %s" "$_optcompress" + _optcompress=cat + fi + + msg "Starting build: %s" "$KERNELVERSION" +elif [[ $_opttargetdir ]]; then + msg "Starting build: %s" "$KERNELVERSION" +else + msg "Starting dry run: %s" "$KERNELVERSION" +fi + +# set functrace and trap to catch errors in add_* functions +declare -i _builderrors=0 +set -o functrace +trap '(( $? )) && [[ $FUNCNAME = add_* ]] && (( ++_builderrors ))' RETURN + +preload_builtin_modules + +map run_build_hook "${_hooks[@]}" || (( ++_builderrors )) + +# process config file +parse_config "$_f_config" + +# switch out the error handler to catch all errors +trap -- RETURN +trap '(( ++_builderrors ))' ERR +set -o errtrace + +install_modules "${!_modpaths[@]}" + +# unset errtrace and trap +set +o functrace +set +o errtrace +trap -- ERR + +# this is simply a nice-to-have -- it doesn't matter if it fails. +ldconfig -r "$BUILDROOT" &>/dev/null +# fix reproducibility +[[ -e "$BUILDROOT/var/cache/ldconfig/aux-cache" ]] && rm "$BUILDROOT/var/cache/ldconfig/aux-cache" + +# Set umask to create initramfs images and EFI images as 600 +umask 077 + +if [[ $_optgenimg ]]; then + build_image "$_optgenimg" "$_optcompress" +elif [[ $_opttargetdir ]]; then + msg "Build complete." +else + msg "Dry run complete, use -g IMAGE to generate a real image" +fi + +if [[ $_optuefi && $_optgenimg ]]; then + build_uefi "$_optuefi" "$_optgenimg" "$_optcmdline" "$_optosrelease" "$_optsplash" "$_optkernelimage" "$_optuefistub" "${_optmicrocode[@]}" +fi + +cleanup $(( !!_builderrors )) + +# vim: set ft=sh ts=4 sw=4 et: