The xNBA loaders, the upstream iPXE loaders with the UEFI shim, the
POWER grub2 image and yaboot count as a boot loader download. Genesis
files, pxelinux.0, the POWER grub2 configuration and a similar-looking
name do not.
For each loader file that a TFTP tree can hold, the check accepts an
xnba node or an ipxe node when that file can SAN-boot it: undionly.kpxe
in the root for both, xnba.kpxe for xnba, and the upstream BIOS loader
for ipxe. The upstream UEFI loader alone is not enough.
A server without x86 network boot scripts gets no warning, and a ready
server gets none. An upgraded server with only the xNBA scripts gets one
warning for each missing upstream loader file, the UEFI shim and the
snponly.efi it loads included, and one for the network scripts. A single
missing file gets its own warning, and a directory under xcat/ipxe/nets
is not a network boot script.
A node of an x86_64 or x86 image profile gets netboot=ipxe, and the
ppc64le and riscv64 profiles keep grub2. The x86 node templates, read
with the stanza parser of mkdef, define netboot=ipxe, the ppc64le
template keeps petitboot, and the e1350 noderes table gives the compute
group ipxe.
A profile change keeps netboot=xnba, and gives a node without a method,
a netboot=pxe node and a node of another architecture the method of its
profile.
The next change makes discovery set netboot=ipxe on an x86 node, so the
two checks that expect xnba for an x86 node without an x86 method go.
The checks that keep an x86 method that is already set stay.
The global Kea classes give the upstream loader to an x86 client that
cannot fetch its script, and the Etherboot class gives it the BIOS
loader. The network classes and the ISC x86 lines give the Genesis
script under xcat/ipxe/nets to a client with the iPXE features of its
path, and the Kea subnet lists those classes. Without an upstream loader
file on the server, neither backend names it or the second stage that it
would fetch, and the ISC lines stop such a client before the fallback.
The xNBA files name no global class.
An xnba node gets xNBA from its own first-stage classes when the server
has the xNBA BIOS file, and still xcat/xnba.efi without the local UEFI
file. Without the xNBA BIOS file it has no first-stage classes, as it
has no ISC host statements. An ipxe node without a SAN disk carries the
upstream loader in its own first-stage classes.
The ISC configuration test also checks these lines in configurations
that makedhcp upgraded, one of them with indented declarations.
The DHCP wire cases now expect the upstream loader for an x86 client
with no reservation, and its network script for a second stage that
reports the features in option 175. A second stage without them gets the
loader again, and an xnba node still gets xNBA.
The next change gives unknown x86 clients the upstream iPXE loader, and
an xnba node carries its own first-stage classes in Kea. These checks
describe the xNBA loader for unknown clients, so they go: the files,
tests and architectures of the global x86 classes, the network classes,
the Etherboot class, the UEFI class of the proxyDHCP case, and the xNBA
branches and missing-loader cases of the ISC x86 lines.
The node class checks of an xnba node and of an ipxe node compare only
the second-stage classes, which do not change. The test after the change
covers the new loader.
The Kea classes and the ISC host statements of a netboot=ipxe node name
the ipxe-xcat loaders without a local file. The node script goes to a
client with HTTP, bzImage and PXE on BIOS and HTTP and EFI on UEFI, and
the first-stage classes negate the same test. A SAN node needs iSCSI as
well. An xnba node beside an ipxe node keeps its classes. dhcp.pm gives
node classes to ipxe and xnba nodes, with their method and SAN flag. Kea
defines option 175, the ISC header declares every feature that a host
statement tests, and no host statement depends on parentheses: each
feature test sits inside its architecture test.
nodeset through the ipxe plugin writes the BIOS, UEFI, elilo and
pxelinux files of a node under xcat/ipxe/nodes, and the scripts name
that directory. An xnba node still gets xcat/xnba/nodes. SvrUtils reads
the nodeset state of both. An x86_64 osimage accepts netboot=ipxe, and
the noderes.netboot description lists it.
lookupNetboot lists the netboot methods that an osimage accepts. The
x86_64 case compared the whole list, so any new x86 method broke it.
It now checks that xnba, pxe and grub2 are accepted, in any order.
A local dhcpd, and an external one without netboot=ipxe nodes, get no
check. An external dhcpd that returns the check host updates every
node, after one omshell run that creates the host, whose statement
tests every iPXE feature option, and one that reads it back and removes
it. The first run opens no host, and each run creates a host with its
own name and address.
A rejected statement, a run cut short or without a reply, a lost
connection and the host of another run leave the netboot=ipxe nodes
unchanged, and the error names the server and the nodes. The replies
are those of dhcpd 4.4.
makedhcp adds the missing ISC declarations after the gpxe option space,
and the missing Kea definitions after the existing ones, once. Indented
ISC declarations and declarations with more blanks count. An ISC
configuration without the gpxe space gives an error and stays as it is,
and so does a Kea definition of option 175 without the gpxe
encapsulation, and makedhcp then writes nothing.
makedhcp writes the ISC configuration and restarts dhcpd at once. When
the configuration declares no gpxe option space, or makedhcp cannot
write the file or restart dhcpd, it reports the error and changes no
subnet or host. A marker beside the configuration stays until a restart
succeeds, so the next run restarts dhcpd before it changes a host.
Without a dhcpd.conf, or with one that xCAT did not write, it gives no
error and goes on to write a new configuration. Kea restarts to load the
definitions, also when the Control Agent applies the host reservations.
Every option code stays a number: JSON::XS writes a number that Perl has
used as a string as a JSON string, and Kea rejects it. kea-dhcp4 -t
checks an upgraded and a current configuration that makedhcp writes
back.
Hold the Kea classes, the ISC x86 lines, and the ISC host statements of
each netboot=xnba and netboot=pxe branch to the exact text the renderers
produced before the x86 loader became selectable.
kea_node_client_classes_for_nodes returns early, without a localboot
list, when it cannot open the noderes or mac table.
kea_sync_node_client_classes then dereferences that missing list and
dies with "Can't use an undefined value as an ARRAY reference".
dhcp_kea_ddns_deferral.t takes this path, so the unit tests fail on
master since #7830 added the localboot list.
Check the early answer and the sync with both tables unavailable.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
xcattest loads xCAT::Test::OS from /opt/xcat/lib/perl. xCAT-test.spec
installs it, but xCAT-test/debian/install does not, so xcattest on an
Ubuntu management node dies at startup with "Can't locate
xCAT/Test/OS.pm in @INC".
Check that the RPM spec and the Debian install list both ship every
module under xCAT-test/lib/xCAT. The Debian check fails.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
xcattest reports "Test case <name> has an invalid OS option - Linux" and then
"There is no valid case to run", so every case is skipped on openEuler.
Recorded on an openEuler 24.03 LTS SP4 management node with xCAT 2.20.0: both
flat provisioning cases were rejected and the run measured nothing.
Two causes, both in the os: comparison in xCAT-test/xcattest. get_current_os
takes the /etc/os-release branch, finds no sles, and falls off the end of that
branch, so it returns the exit status of the failed grep, 256, which names no
distribution. And a case marked os:Linux expands to exactly rhels, sles and
ubuntu, so openEuler would be rejected even by a correct get_current_os.
Both halves move into xCAT::Test::OS. xcattest finds it beside itself and the
package installs it at <prefix>/lib/perl. current_os takes a path prefix, so a
test describes a system by writing release files into a scratch tree. openEuler
is named in both halves and nothing else changes.
xCAT-test/unit/xcattest_os_selection.t covers it. Removing openeuler from
linux_aliases fails two checks, and removing the openEuler branch from
current_os fails three. A further case gives a root both /etc/redhat-release
and an openEuler /etc/os-release and asserts rhels10, so the precedence is
named: openEuler ships neither that file nor /etc/lsb-release.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
On a new Kea management node, makedhcp -n defers DDNS because no key
exists. After makedns -n writes the key, makedhcp -a keeps the DHCPv4
configuration without dhcp-ddns and writes no kea-dhcp-ddns.conf, so
DNS updates stay off.
The test runs makedhcp -n without a key, adds the key, runs
makedhcp -a, and checks the rendered DHCPv4 and D2 configurations.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
enable_repo_commands chose subscription-manager from the vendor id and the presence of the
binary. An unregistered RHEL node has both, so the postscript ran
`subscription-manager repos --enable`, the command failed for want of a registration, and only
the fallback to `dnf config-manager` enabled the builder repository. The log named the
repository, not the registration.
The decision now takes the registration state. registered_with_subscription_manager reads the
exit status and the output of `subscription-manager identity`, which the postscript runs, and
enable_repo_commands emits the subscription-manager command only for a registered node. A
Foreman, Katello or Red Hat Satellite client registers through subscription-manager, so the same
path covers it, and the vendor id no longer decides. uses_subscription_manager is removed with
its caller.
service_node_artifacts_el.t asserts the probe against the registered and the unregistered output
of subscription-manager 1.30.12, against a missing binary, and against a call without root
privilege. It also asserts that an unregistered node runs no subscription-manager command.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The servicenode postscript enabled the builder repository with dnf
config-manager on every vendor. On RHEL that repository is defined in
/etc/yum.repos.d/redhat.repo, which subscription-manager owns and
regenerates, so the enabled flag does not survive the next refresh. The
builder repository turns off again and dnf install xCATsn stops resolving
perl-IO-Tty, perl-Crypt-CBC, perl-Crypt-Rijndael and perl(Expect).
ELBuilderRepo::enable_repo_commands returns the commands to try in order.
uses_subscription_manager names the vendors whose repository file
subscription-manager owns, beside builder_repo_ids which already names the
repository per vendor. RHEL asks subscription-manager first and keeps
config-manager as the fallback. Every other vendor gets config-manager
alone, which is what it had before.
service_node_artifacts_el.t asserts the command order per vendor. Without
the subscription-manager branch, the order assertion fails and no other
assertion does.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
kea_build_ddns_intent returned the deferral under a deferred key. No other
xCAT code uses that key: dhcp.pm reports through error, warning, node and
data, and makedhcp already passed this message to the callback as a warning.
The intent hash now carries the message under warning, so one name describes
it from the hash to the callback. Behaviour does not change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
kea_build_ddns_intent returns an error when no DDNS key material exists, and
makedhcp -n reports it instead of configuring Kea. No unit test reads that
decision, so the error path and the D2 path are both unmeasured.
dhcp_kea_ddns_deferral.t drives kea_build_ddns_intent with and without key
material, and drives the sub that attaches the D2 connection to the DHCPv4 and
DHCPv6 configurations. It also holds down the two boundaries the change must
keep: a management node whose site.dnshandler is not ddns asks for no D2
configuration, and an unreadable networks table stays an error.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The comments added with the EL service node fixes carried the bug report: the
symptom on a named cell, the causal chain down to what the compute node sees,
and a claim that a step cannot fail the node. The comment rules put the symptom
and the chain in the commit and leave the invariant in the source.
Each one is cut to the fact the code cannot show: that EPEL and the builder
repository are both off on a fresh EL install, that exportfs refuses an NFS
mount without an explicit fsid, and that everything below a point in the
postscript runs commands on the node.
No executable line changes. The fast oracle passes.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
nodepurge removes the autoinstall configuration of each node it deletes. The
cleanup loop was inline in the nodepurge sub of profilednodes.pm, which no test
can load, so the loop moves to xCAT::ProfiledNodeUtils->remove_node_config_files
with its behaviour unchanged.
nodepurge_autoinst_cleanup.t drives that routine against a scratch directory. It
fails here: the Subiquity node keeps its directory, and the preseed file and the
.pre and .post scripts are removed.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
Every service node defect in this change set was a generated artifact that was
already wrong before any node booted: a repository file that enabled no builder
repo, a template that resolved to the wrong installer, an exports line that was
never written. The tests that caught them are one file per fix, so each knows
one defect and together they know no defect class. A fix nobody has made yet is
covered by none of them.
service_node_artifacts_el.t renders the artifacts an EL service node needs from
one fixture and asserts each: the builder repository per release and vendor,
including that EL8 is powertools and not crb; the template the service profile
resolves, which must not be a Subiquity one; and the export line for a local
directory and for a re-exported mount, where an absent fsid is what made a
service node export nothing.
A missing module or sub fails rather than skips, and the file reports every gap
instead of dying at the first, because on an unfixed tree this test is the gap
report. Measured: 17 assertions pass on the branch, and the base fails two of
them by name.
It does not cover the boot half -- the lease, the tftp handover, the mount the
installer performs -- so it replaces no end-to-end run. It replaces the 45 to
90 minutes those runs cost in the ROUNDS of a minimization.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
servicenode.nfsserver=1 asks a service node to set up file services for the nodes behind it.
With site.installloc set, AAsn.pm mounts the install directory from the management node and
exports nothing, and setup_NFS only starts the daemon, so the service node serves no NFS at all.
Only the branch where installloc is unset ever wrote an export.
An Ubuntu compute node boots the live installer with casper, which mounts the install tree over
NFS from its own service node. Measured on xcat22-cn: the boot arguments carried
nfsroot=192.168.222.21:/install/ubuntu24.04.4/x86_64, and the node stopped at "(initramfs) Unable
to find a live file system on the network". On xcat22-sn, showmount -e returned an empty list and
/etc/exports was empty while nfs-kernel-server was active. EL never needed this, because anaconda
fetches over http.
setup_NFS now exports the install directory when nothing exports it yet, then runs exportfs after
the daemon. Re-exporting an NFS mount is not the same as exporting a local directory: the kernel
cannot derive a filesystem id for one and refuses the export without an explicit fsid, so
nfs_export_line adds fsid and crossmnt when the directory is itself a mount. The fsid comes from
the path, so a restart does not hand clients a new filesystem identity.
An export the kernel refuses is reported and does not fail the service node. The EL cell is
re-run on this tree, because an EL service node now writes an export it did not write before.
svrutils_nfs_export_line.t drives the routine. Five mutations were tried and each one fails the
assertions that name it.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The name of the EL builder repository was decided inside servicenode, so a test of that decision
had to load the postscript. It is a table with one row per vendor and EL major version, and it
belongs in a module.
ELBuilderRepo ships in /install/postscripts and is copied to /xcatpost with the postscripts, so
it loads on a service node that has no xCAT package yet. servicenode keeps the side effects:
enable EPEL, ask the module for the ids, enable the first one dnf knows, and report what it
could not enable.
servicenode_builder_repo.t is now a table: Alma, Rocky, CentOS Stream, RHEL and Oracle Linux
across EL8, EL9 and EL10, plus the capitalised PowerTools that Rocky 8.4 and earlier shipped.
Returning crb for EL8 fails nine of its assertions.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
xCAT-server requires perl-IO-Tty, perl-Crypt-CBC, perl-Crypt-Rijndael and perl(Expect). EL keeps
them in the distribution builder repository, which is disabled on a fresh install. The
servicenode postscript enabled EPEL and nothing else, so dnf install xCATsn on the service node
did not resolve and the node ended with no xcatd. Measured on xcat42-sn: epel enabled, crb
disabled.
builder_repo_ids returns the repository ids to try, most likely first. It covers AlmaLinux,
Rocky and CentOS Stream (crb on 9 and 10, powertools with the CentOS 8 spelling after it on 8),
RHEL (codeready-builder-for-rhel-<major>-<arch>-rpms) and Oracle Linux
(ol<major>_codeready_builder). Any other vendor falls back to those community spellings, which
is a guess and is written down as one. It returns an empty list rather than guess when
/etc/os-release names no release.
enable_el_dependency_repos enables the first id dnf knows. Neither repository is fatal: a site
can run without EPEL, and xcat-dep carries the same perl closure. The rule is that an absent
repository must be visible, so each one that could not be enabled prints a line naming the
packages it carried and the consequence, and logs it at local4.warning. The node still sets up.
servicenode now returns early under caller(), so a test can load it for its subroutines.
servicenode_builder_repo.t drives every arm. Without the guard the test executed the postscript
instead of loading it, which is how it failed before this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
makedhcp <node> adds the per-node classes to the loaded Kea config and
writes it back with encode_config. The proxyDHCP class sets always-send
to 1, and the renderer that turns the flag into a JSON boolean is not on
that path. Kea rejects the file ("unexpected integer, expecting
boolean"), so makedhcp fails for every node deferred to proxyDHCP.
The test syncs a proxyDHCP node, encodes the config and expects a JSON
boolean. It fails on this tree.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
A Windows UEFI install deferred to proxyDHCP gets boot-file-name "" in its
Kea reservation. Kea treats the empty string as not specified, so the
subnet classes still match the node on architecture, and xcat-uefi-x64
offers it xcat/xnba.efi instead of leaving it to the daemon on port 4011.
The test syncs a proxyDHCP node and a netboot node against the real
architecture classes. It expects the proxyDHCP MAC in xcat-localboot and
every boot-file class to exclude that class. It fails on this tree.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>