REQUIRED_PACKAGES named util-linux-extra for every release. focal and jammy
have no such package -- apt reports "Candidate: (none)" -- so apt-get install
exits non-zero and, under set -euo pipefail, the build stops before dracut
runs. hwclock is in util-linux there, which is essential and already present.
optional_packages() keeps a package only where apt has a candidate for it, and
util-linux-extra goes through it. The unconditional list keeps isc-dhcp-client
and ifenslave, which every release has and neither of which the build root
carries by itself.
The call to verify-genesis-payload goes with it. That script is added by the
genesis payload branch, not this one, so the line stopped the build at the
point it was meant to guard.
Also corrects the plan count and a dereference in the test committed before
this one.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
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>
verify-genesis-payload dropped every name that started with "/" before checking
the payload, so the 609 absolute paths the EL dracut module installs were
checked by nothing. An image with no /usr/bin/awk passed. The filter now drops
only option words, and an absolute name is read back under the payload root.
The ppc64 to ppc64el rename left the new Genesis base deb without a relation to
the deb it replaces, so dpkg kept xcat-genesis-base-ppc64 installed beside it
with its own copy of the files under /opt/xcat/share/xcat/netboot/genesis.
builddeb-genesis-base and debuild-xcat-genesis-base now write Replaces and
Breaks for the superseded package, as the genesis-scripts control file already
does. The native path takes the architecture rewrite into rewrite_control() so
the superseded name is derived in one place.
genesis_payload_verification.t, genesis_base_deb_arch.t and
genesis_base_deb_control_rewrite.t fail without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
master moved 149 commits ahead of the branch point and four files needed a
decision.
xCAT/debian/control and xCATsn/debian/control: master moved nmap and
ipmitool-xcat into Depends, raised the ipmitool version and added the s390x
OpenEmbedded Genesis recommendation. The branch made the genesis-scripts
dependency per architecture. Both are kept, so the ppc64el metapackage depends
on xcat-genesis-scripts-ppc64el and no longer on the amd64 package.
build-utils/lib/XCAT/BuildUtils.pm and xCAT-test/unit/build_utils.t: master
replaced @DEB_ARCHES plus the branch's %NO_RISCV64 exception list with
%ARCH_PACKAGES, which carries the architecture list per package.
deb_package_arches returns the same answer for every package, so master's form
is kept and %NO_RISCV64 is dropped.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
builddeb-genesis-base installs its build root from REQUIRED_PACKAGES. That list
has no isc-dhcp-client, no ifenslave and no util-linux-extra, so dracut cannot
find dhclient, ifenslave or hwclock. dracut_install prints one line for each and
returns, the script never reads dracut's result, and the .deb is packaged with
three holes. A Genesis image with no dhclient never obtains a provisioning lease.
Add the three packages, and run verify-genesis-payload on the extracted payload
before dpkg-buildpackage. --commands-from reads the command names back from the
module that is about to be built, so a later addition to the module is checked
too. This is what xCAT-genesis-base.spec already does for EL.
genesis_ubuntu_build_root.t fails five of its eight assertions without this
change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The go-xcat shell behavior tests were written as Perl harnesses, which made the shell assertions harder to read and kept shell-specific setup outside a native shell test framework.
Add BATS to the GitHub Actions dependency set, run BATS tests from the same preserved source tree as the Perl unit suite, and move the go-xcat repository checks into xCAT-test/autotest/bats.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
Every case that boots a node into the el10 legacy Genesis image fails with
"root@<cn>: Permission denied (publickey,password,keyboard-interactive)".
mknb writes the management node key to /.ssh/authorized_keys, and sshd looks
for it under the home directory of root.
The dracut cmdline hook deletes the root entry the image ships with
"sed -i '/^root:x/d'" and appends its own entry with the home directory /.
dracut 99base writes that entry, and from dracut 060 the password field holds
x only when the image is built --hostonly. The Genesis image is built with -N,
so el10 (dracut 107) ships "root::0:0::/root:/bin/sh". The delete does not
match, two root entries survive, and getpwnam returns the first one. el8
(dracut 049) and el9 (dracut 057) always ship the x and are not affected.
The delete now matches the user name only. All three cmdline hooks carry the
same statement and all three change.
genesis_root_home.t runs the rewrite against both entry shapes and fails on
the empty password field without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
A compute node that boots the legacy Genesis image built on el10 stops after
"Getting initial certificate --> <mn>:3001". /etc/xcat is empty, getdestiny never runs and
the node reports no destiny, so xcatd leaves nodelist.status at powering-on. On the node,
openssl reports "command not found" and the getcert process stays alive.
xCAT-genesis-base.spec never build-requires openssl. el8 and el9 hold /usr/bin/openssl in
the build root as a dependency of another package, and el10 does not, so dracut_install in
dracut_105/el/module-setup.sh installed nothing and reported nothing. getcert line 8 waits
for openssl with no bound, which turns the missing command into a wait instead of an error.
The spec now build-requires openssl on every release. verify-genesis-payload reads the
command names back from the dracut module with --commands-from and requires each one in the
payload, so the next name the build root does not supply fails the build. getcert reports a
missing openssl and stops, and bounds the wait for /etc/xcat/certkey.pem at 600 seconds,
which is far longer than the background 4096 bit key needs.
The spec read %{_target_cpu} after BuildArch: noarch, where rpm has already set it to
noarch, so the dmidecode and efibootmgr build-requires never applied and a sed deleted their
dracut_install line on every architecture. Every shipped image lacks both. The spec now
reads %{tarch}, and the dracut module installs whichever of the two the build root carries,
because ppc64le packages neither.
xCAT-test/unit/genesis_getcert_missing_openssl.t, genesis_payload_verification.t and
genesis_base_spec_buildrequires.t fail on the test commit before this one.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
debuild-xcat-genesis-base maps only x86_64 to amd64. For the ppc64 rpm it
leaves every name at ppc64, so it builds xcat-genesis-base-ppc64 and
writes "Breaks: xcat-genesis-scripts-ppc64". The Debian architecture is
ppc64el, and the packages xCAT-genesis-scripts builds for it are named
ppc64el, so the Breaks names a package no repository publishes.
This change replaces the single x86_64 test with an architecture map:
x86_64 to amd64, ppc64 and ppc64le to ppc64el. The map now drives the
source tree rename, the control and changelog rewrite, and the Breaks
field. PACKAGE_ARCH keeps the rpm value, because the preinst removes the
Genesis tree under that name.
genesis_base_deb_arch.t drives the script with alien shadowed. It fails
the three ppc64el assertions without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The nodeset_shell_incorrectmasterip case passed while "nodeset testnode shell" failed with
"/tftpboot/boot/grub2/grub2.x86_64 does not exits". The grub2 sub-case asserted nothing. Every
genesis case reported "After 30 iterations node status: powering-on" and passed anyway.
check_destiny in xCAT-test/autotest/testcase/genesis/test.sh discarded the return value of
runcmd and read the boot configuration file, which grub2.pm writes before it stops on the
missing boot loader. xCAT builds no grub2 boot loader for x86_64, so the file is absent on a
correctly built management node. wait_for_boot in genesistest.pl waited for nodelist.status
"booted"; a Genesis node reports its destiny with getdestiny and xcatd writes "shell",
"configuring" or "booting" from it. Every caller discarded the return value. The node did not
reach even those statuses, because getdestiny makes its request file with mktemp and the
dracut module never installed it.
check_destiny now returns the status of nodeset, and the grub2 check stages an empty
grub2.<arch> when the management node has none and removes it after. wait_for_node_status
takes the status the destiny implies and each caller fails when the node does not reach it;
the shell case moved into run_nodeset_shell_test so its result can be read. clearenv no longer
waits, because "rinstall <node> boot" boots a disk with no operating system and reports
nothing. The dracut modules install mktemp and verify-genesis-payload requires it.
Tests: genesis_incorrectmasterip_check.t runs the check with a failing nodeset and reads
whether the boot loader is present when nodeset runs; genesis_testcase_helpers.t drives the
status wait and the shell case; genesis_payload_verification.t reads a payload without mktemp.
Each fails on the parent commit.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
(cherry picked from commit 8ecf0a806785023aca0ea6d1b0e41810630816b2)
The Release hunk of the original commit is dropped. buildrpms.pl writes Release from
SOURCE_DATE_EPOCH at build time, so the committed snap stamp is build debris.
A compute node that boots the legacy Genesis image on el10 x86_64 never acquires an
address. Its serial console reports "/usr/bin/doxcat: line 293: dhclient: command not
found" and then "It seems to be taking a while to acquire an IPv4 address". The DHCP
server side is sound: Kea leases the address and the node never asks for it.
AlmaLinux 10 and EPEL 10 package no ISC dhcp-client. dracut_install reports a missing
binary and returns, so module-setup.sh named dhclient, the build kept going and the image
shipped without a client. doxcat then named dhclient at six call sites with no
alternative.
doxcat now chooses its client at run time. genesis_dhcp_command() returns the command
line for one interface and one address family, and genesis_start_dhcp() runs it and
reports when the image carries none. The ISC client keeps its command line where a
release packages it, so el8 and el9 are unchanged. Where it is absent, dhcpcd stands in:
AlmaLinux 10 baseos packages it at 236 KB, and it carries its own resolv.conf, hostname
and ntp hooks, so it needs no dhclient-script. dhcpcd on a single interface exits when
its 30 second timeout expires and de-configures the interface as it goes, so it is asked
for -t 0 and -p.
The dracut module installs whichever client the build root carries, together with the
hooks dhcpcd runs on every lease. The spec build-requires dhcpcd from rhel 10 on, and
verify-genesis-payload now requires usr/sbin/dhcpcd there, so an image that ships with no
client fails the build instead of reaching a node.
genesis_dhcp_client.t drives both routines with the clients shadowed by recording stubs.
It fails on the parent commit, and deleting the dhcpcd branch turns five of its
assertions red.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
(cherry picked from commit b9329998c80383bb0397d16a558f66a6bb9db399)
A compute node fetches the legacy Genesis kernel and initramfs, the kernel starts, and then
nothing else happens: doxcat never runs, the node acquires no address, sshd refuses every
connection and the node stays at status=powering-on. The five genesis test cases in
xCAT-test/autotest/testcase/genesis have never passed. VersatusHPC/xcat-internal#78.
Three holes in the image, each fatal on its own. dracut_105/el/xcat-cmdline.sh ends in
`while :; do tmux attach-session -t doxcat || tmux new-session -s doxcat doxcat; done`, and the
image carries no locale data, so tmux exits with "need UTF-8 locale" and the loop spins
without ever reaching doxcat. module-setup.sh does not install
/usr/libexec/openssh/sshd-session, which OpenSSH 9.8 and later exec for every connection and
which EL9 now ships. xCAT-genesis-base.spec does not BuildRequire dhcp-client, so dhclient is
absent from the build chroot; dracut_install reports the missing binary and returns, and the
module install function keeps going, so the image ships without it.
xcat-cmdline.sh now resolves xcat_console_mode() once and runs doxcat directly when the
terminal multiplexer cannot start a session; the same shape replaces the screen loop on
Ubuntu. module-setup.sh installs the OpenSSH session helpers and the C.utf8 locale where they
exist. The spec BuildRequires dhcp-client on the releases that package it, and runs the new
xCAT-genesis-builder/verify-genesis-payload over the extracted payload, which fails the build
when sshd needs a helper the image lacks, when tmux has no UTF-8 locale, or when a binary the
caller named is missing.
The same runs exposed four defects in the test cases themselves. test.sh defined its synthetic
node as ppc64le whatever the management node was, so nodeset could not find a genesis kernel on
x86_64. genesistest.pl get_os() matched neither AlmaLinux nor Rocky and reported the OS as
unsupported. The -g check read $? instead of check_genesis_file()'s return value, so it could
never fail. And testxdsh() met "REMOTE HOST IDENTIFICATION HAS CHANGED" from the second boot
on, because Genesis makes new host keys every boot and nothing dropped the stale known_hosts
entry. test.sh now derives the node arch from uname and takes the tftp root from TFTPDIR,
get_os() recognises the redhat family, report_genesis_files() carries the result to an exit
status, and forget_host_keys() runs makeknownhosts -r before each probe.
Tests: genesis_console_mode.t drives xcat_console_mode() with the multiplexer shadowed;
genesis_payload_verification.t drives the verifier over payload trees carrying each hole;
genesis_testcase_helpers.t drives get_os(), check_genesis_file(), report_genesis_files() and
testxdsh(); genesis_incorrectmasterip_check.t runs test.sh against a scratch tftp root. Each
fails on the parent commit. The verifier also reports all three holes against the released
xCAT-genesis-base-x86_64-2.19.0-snap202609021858 payload.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
(cherry picked from commit cb6021eb3cdb3abc75e4dd6704cb42b28074e140)
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
A riscv64 build of xcat-core dies at xCAT-genesis-scripts with "Cannot find/open
srpm: ...xCAT-genesis-scripts-riscv64-2.19.0-<release>.src.rpm", because the srpm
rpm produced is named xCAT-genesis-scripts-%{tarch}-2.19.0-<release>.src.rpm.
xCAT-genesis-scripts.spec and xCAT-genesis-base.spec take their package name from
%{tarch}, which an %ifarch ladder sets for x86, x86_64, ppc64 and aarch64. riscv64
is absent, so rpm leaves the macro unexpanded and builds a package whose NAME
contains it. buildrpms.pl then looks for the name it asked for and cannot find it.
Add the riscv64 branch to both specs. An arch that is still missing from the
ladder now stops the build with %{error:} instead of naming a package after a
macro.
xCAT-test/unit/genesis_spec_target_arch.t covers this: it fails on riscv64
without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
(cherry picked from commit c9de89ccceaaa618f9e91568d74812b349c513ac)
The riscv64 kernel was built without ACPI. Firmware that publishes ACPI
tables and no device tree - server-class RISC-V boards, and edk2 with
acpi=on - therefore left the kernel with no hardware description: it died
before console initialisation, so a node handed the image by grub2 went
silent at ExitBootServices and never reached the discovery action.
Enable ACPI, its error interfaces and the EFI stub the image is already
booted through. Rebuilt with these options, the same image on the same
firmware parses the RSDP, XSDT, FACP, DSDT, APIC, RHCT and SPCR tables,
reaches multi-user and starts discovering, and the kernel now also sees
the SMBIOS entry point the firmware exports.