mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-21 08:33:20 +00:00
b91795a8f4
Thirteen test files this branch adds call BAIL_OUT at fifty-one places: an extraction that stopped matching, a fixture that is not there, a harness that wrote no log. prove stops every remaining file on a bail-out, not only the file that called it, so one of them hides the results of every test that would have run after it. die is just as loud and costs only its own file. Fifteen comments the branch added also carried the incident rather than the constraint. Three pasted an error transcript, five traced a failure from a macro or a missing file out to a node that never boots, and the rest counted call sites, package sizes or dracut build numbers. Each now states the one fact the reader cannot re-derive from the code. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
121 lines
4.1 KiB
Bash
Executable File
121 lines
4.1 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# verify-genesis-payload [--commands-from <module-setup.sh>] <payload-root> [required-path ...]
|
|
#
|
|
# dracut_install() reports a missing binary and returns, so the module install function keeps
|
|
# going and the image ships without it. Check the extracted payload before it is packaged.
|
|
#
|
|
# Paths given on the command line are relative to <payload-root>. --commands-from reads back
|
|
# what the dracut module installs: a bare command name is looked for in the four binary
|
|
# directories, an absolute path under <payload-root> itself. The caller adds what only it
|
|
# knows (the DHCP client is not the same package on every release); the rules below come from
|
|
# the payload itself.
|
|
|
|
set -u
|
|
|
|
commands_from=""
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--commands-from)
|
|
commands_from=${2:-}
|
|
shift 2 || true
|
|
;;
|
|
--commands-from=*)
|
|
commands_from=${1#*=}
|
|
shift
|
|
;;
|
|
*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
payload=${1:-}
|
|
if [ -z "$payload" ] || [ ! -d "$payload" ]; then
|
|
echo "verify-genesis-payload: not a payload directory: ${payload:-<empty>}" >&2
|
|
exit 2
|
|
fi
|
|
shift
|
|
|
|
missing=""
|
|
|
|
# have PATH: true when the payload carries PATH as a file, following the usr-merge symlinks
|
|
# the image ships (/sbin -> usr/sbin).
|
|
have() {
|
|
[ -e "$payload/$1" ]
|
|
}
|
|
|
|
require() {
|
|
local path=$1 why=$2
|
|
have "$path" || missing="$missing
|
|
$path ($why)"
|
|
}
|
|
|
|
for path in "$@"; do
|
|
require "$path" "required by the build"
|
|
done
|
|
|
|
# The dracut module names every command and every data file Genesis needs. A name the build
|
|
# root does not supply installs nothing and says nothing, so read the names back and check
|
|
# each one. Names under a condition are release-dependent, so only the top level of install()
|
|
# counts.
|
|
if [ -n "$commands_from" ]; then
|
|
if [ ! -r "$commands_from" ]; then
|
|
echo "verify-genesis-payload: cannot read $commands_from" >&2
|
|
exit 2
|
|
fi
|
|
commands=$(awk '
|
|
/^install\(\)/ { in_install = 1; next }
|
|
in_install && /^}/ { in_install = 0 }
|
|
in_install && /^ dracut_install / {
|
|
sub(/#.*/, "")
|
|
sub(/^ dracut_install /, "")
|
|
print
|
|
}' "$commands_from" | tr ' \t' '\n\n' | grep -v '^$' | grep -v '^-' | sort -u)
|
|
if [ -z "$commands" ]; then
|
|
echo "verify-genesis-payload: no command name read from $commands_from" >&2
|
|
exit 2
|
|
fi
|
|
for want in $commands; do
|
|
case "$want" in
|
|
# dracut_install installs an absolute path at that same path, so read it back
|
|
# under the payload root. Dropping these let an image with no /usr/bin/awk pass.
|
|
/*) have "${want#/}" || missing="$missing
|
|
$want (installed by $commands_from)"
|
|
;;
|
|
*) have "bin/$want" || have "sbin/$want" \
|
|
|| have "usr/bin/$want" || have "usr/sbin/$want" \
|
|
|| missing="$missing
|
|
$want (installed by $commands_from)"
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
require usr/sbin/sshd "Genesis is reached over ssh"
|
|
require usr/bin/mktemp "getdestiny makes its request file with it"
|
|
|
|
# OpenSSH 9.8 split the per-connection work into sshd-session, which sshd execs by absolute
|
|
# path. EL9 carries OpenSSH 9.9, so an image with sshd alone refuses every connection.
|
|
if have usr/sbin/sshd && grep -qa 'sshd-session' "$payload/usr/sbin/sshd" 2>/dev/null; then
|
|
if ! have usr/libexec/openssh/sshd-session && ! have usr/lib/openssh/sshd-session; then
|
|
missing="$missing
|
|
usr/libexec/openssh/sshd-session (this sshd execs it for every connection)"
|
|
fi
|
|
fi
|
|
|
|
# tmux exits under the C locale. The hook falls back to running doxcat directly, so this is
|
|
# not fatal to booting, but a Genesis shell without tmux loses the console attach.
|
|
if have usr/bin/tmux && ! have usr/lib/locale/C.utf8/LC_CTYPE; then
|
|
missing="$missing
|
|
usr/lib/locale/C.utf8/LC_CTYPE (tmux refuses to start without a UTF-8 locale)"
|
|
fi
|
|
|
|
if [ -n "$missing" ]; then
|
|
echo "verify-genesis-payload: $payload is incomplete:$missing" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "verify-genesis-payload: $payload is complete"
|
|
exit 0
|