mirror of
https://gitlab.archlinux.org/tpowa/archboot.git
synced 2024-09-19 19:40:37 +02:00
fix reproducibilty on initrds
This commit is contained in:
parent
2aef84ac5d
commit
f78c682c07
5 changed files with 745 additions and 0 deletions
|
@ -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} ."
|
||||
|
|
|
@ -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} ."
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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/"
|
||||
|
|
732
usr/share/archboot/patches/31-mkinitcpio.fixed
Normal file
732
usr/share/archboot/patches/31-mkinitcpio.fixed
Normal file
|
@ -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 <<EOF
|
||||
mkinitcpio $version
|
||||
usage: ${0##*/} [options]
|
||||
|
||||
Options:
|
||||
-A, --addhooks <hooks> Add specified hooks, comma separated, to image
|
||||
-c, --config <config> Use alternate config file. (default: /etc/mkinitcpio.conf)
|
||||
-g, --generate <path> Generate cpio image and write to specified path
|
||||
-H, --hookhelp <hookname> Display help for given hook and exit
|
||||
-h, --help Display this message and exit
|
||||
-k, --kernel <kernelver> 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 <file> Build specified preset from /etc/mkinitcpio.d
|
||||
-P, --allpresets Process all preset files in /etc/mkinitcpio.d
|
||||
-r, --moduleroot <dir> Root directory for modules (default: /)
|
||||
-S, --skiphooks <hooks> Skip specified hooks, comma-separated, during build
|
||||
-s, --save Save build directory. (default: no)
|
||||
-d, --generatedir <dir> Write generated image into <dir>
|
||||
-t, --builddir <dir> Use DIR as the temporary build directory
|
||||
-D, --hookdir <dir> Specify where to look for hooks
|
||||
-U, --uefi <path> Build an UEFI executable
|
||||
-V, --version Display version information and exit
|
||||
-v, --verbose Verbose output (default: no)
|
||||
-z, --compress <program> Use an alternate compressor on the image
|
||||
|
||||
Options for UEFI executable (-U, --uefi):
|
||||
--cmdline <path> Set kernel command line from file
|
||||
(default: /etc/kernel/cmdline or /proc/cmdline)
|
||||
--microcode <path> Location of microcode
|
||||
--osrelease <path> Include os-release (default: /etc/os-release)
|
||||
--splash <path> Include bitmap splash
|
||||
--kernelimage <path> Kernel image
|
||||
--uefistub <path> Location of UEFI stub loader
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
version() {
|
||||
cat <<EOF
|
||||
mkinitcpio $version
|
||||
EOF
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
local err=${1:-$?}
|
||||
|
||||
if [[ $_d_workdir ]]; then
|
||||
# when _optpreset is set, we're in the main loop, not a worker process
|
||||
if (( _optsavetree )) && [[ -z ${_optpreset[*]} ]]; then
|
||||
printf '%s\n' "${!_autodetect_cache[@]}" > "$_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:
|
Loading…
Reference in a new issue