2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-21 08:33:20 +00:00
Commit Graph

28195 Commits

Author SHA1 Message Date
Daniel Hilst 2f715ac371 Merge pull request #7818 from VersatusHPC/release/2.19-rc1
ci(xcat-core): Fixes to get CI running for all 2.19 targets
2.19.0
2026-09-17 18:18:48 -03:00
Daniel Hilst 52fd332180 Merge pull request #7838 from VersatusHPC/fix/riscv64-diskless-flat-machine-type
fix(xcat-core): the diskless flat case clears the machine type on riscv64
2026-09-17 18:12:50 -03:00
Daniel Hilst 2e6ca07172 Merge pull request #7841 from VersatusHPC/fix/ubuntu-power-diskful-installer-loop
fix(xcat-core): the Ubuntu POWER diskful install never leaves the installer
2026-09-17 12:38:17 -03:00
Daniel Hilst d694456244 Merge pull request #7855 from VersatusHPC/fix/ddns-tsig-algorithm-downgrade
fix(xcat-core): makedns leaves records behind because named cannot verify its own TSIG key
2026-09-17 11:39:44 -03:00
Daniel Hilst 03376eb150 Merge pull request #7842 from VersatusHPC/fix/ubuntu-ppc64el-netboot-dig
fix(xcat-core): the Ubuntu ppc64el netboot image has no dig
2026-09-17 11:38:29 -03:00
Daniel Hilst 6531f77277 Merge pull request #7839 from VersatusHPC/fix/ubuntu-node-netplan-search-domain
fix(xcat-core): a compute node cannot resolve the management node by short name
2026-09-17 11:37:01 -03:00
Daniel Hilst 007a38867b Merge pull request #7837 from VersatusHPC/fix/genesis-deb-release-placeholder
fix(xcat-core): the Genesis deb version never advances past snap000000000000
2026-09-17 11:36:48 -03:00
Daniel Hilst a891e8f741 Merge pull request #7832 from VersatusHPC/fix/ci-ubuntu-genesis-dhclient
fix(xcat-core): the Ubuntu Genesis image ships without a DHCP client
2026-09-17 11:36:37 -03:00
Daniel Hilst 782a2a57b0 Merge pull request #7831 from VersatusHPC/fix/ci-ubuntu-ppc-boot-files
fix(xcat-core): nodeset cannot boot an Ubuntu POWER install from live media
2026-09-17 11:36:27 -03:00
Daniel Hilst 23de8a92e0 fix(xcat-core): the flat case leaves the machine type on the node on ppc64
reg_linux_diskless_installation_flat corrupts the KVM machine type, proves the
node fails to boot, restores the machine type and then removes it again. On
ppc64 the two ladders name different machine types: the restore writes
machine:pseries-rhel7.6.0 and the cleanup removes machine:pseries-7.6.0. The sed
matches nothing, so the node keeps machine:pseries-rhel7.6.0 after the case ends
and the next case runs against a node the previous one changed.

The cleanup ladder now names the machine type the restore ladder writes.

diskless_flat_vmothersetting_machine.bats covers it: the ppc64le cleanup cases
are red on the commit before this one.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-17 07:36:10 -03:00
Daniel Hilst b4735e10e2 test(xcat-core): the machine-type test accepts a cleanup that removes nothing
diskless_flat_vmothersetting_machine.bats checked the restore with a substring
match and checked the cleanup only for the absence of "unary operator
expected". A cleanup that writes the machine type back, or leaves it in place,
passed both.

The test now reads the value chdef receives. The restore must write exactly
machine:<type>, and must keep a setting the node already carries. The cleanup
must write an empty value when the machine type is all there is, and must leave
the other setting behind when there is one. The chdef stub brackets its
arguments so an empty value is not the same as no call.

ppc64le is red on the cleanup: the restore ladder writes
machine:pseries-rhel7.6.0 and the cleanup ladder removes machine:pseries-7.6.0,
so the node keeps the machine type. x86_64 and riscv64 pass.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-17 07:35:51 -03:00
Daniel Hilst af2a4c08d5 Merge pull request #7840 from VersatusHPC/fix/gettimezone-error-sentence-as-timezone
fix(xcat-core): gettimezone returns an error sentence as a timezone name
2026-09-16 20:07:40 -03:00
Daniel Hilst eb37cd6e20 fix(xcat-core): naming util-linux-extra stops the Genesis build on jammy
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>
2026-09-16 18:03:52 -03:00
Daniel Hilst ea2b86adef test(xcat-core): naming util-linux-extra stops the Genesis build on jammy
builddeb-genesis-base names util-linux-extra in REQUIRED_PACKAGES for every
release. Measured on the four Ubuntu management nodes: focal and jammy report
"Candidate: (none)" for that package and carry hwclock in util-linux, which is
essential and already in the build root; noble and resolute carry it in
util-linux-extra. apt-get install with a package it cannot locate exits
non-zero, and the script runs under set -euo pipefail, so the build stops on
two supported targets before dracut runs.

util-linux only Suggests util-linux-extra, and the install passes
--no-install-recommends, so a release that split the package has to name it.

The test asserts the unconditional list does not name it, and drives the
selector that decides, with apt-cache shadowed for a release that has the
package and one that does not.

It also drops the assertion that matched "verify-genesis-payload" against the
text of the build script. That proved the string was present, not that the
verifier ran, ran before packaging, or stopped the build -- and the script it
names does not exist on this branch.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-16 18:02:47 -03:00
Daniel Hilst 75c0af5373 fix(xcat-core): debian_install_prescript.t passes when the file it reads is missing
debian_install_prescript.t called plan skip_all when xCAT-server/lib/xcat/plugins/debian.pm was absent, so a checkout that lost
the file reported 0 tests and exit 0. A test that cannot fail measures nothing.

Die instead, which is what makentp_ntp_deps.t already does for setupntp.

With xCAT-server/lib/xcat/plugins/debian.pm moved aside the file now exits 2 and prints "debian.pm not found";
before this change it exited 0 and printed "1..0 # SKIP debian.pm not found". With the file
present the test passes either way.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-15 21:11:00 -03:00
Daniel Hilst bc4ddbe34e fix(xcat-core): builddebs_release_placeholder.t passes when the file it reads is missing
builddebs_release_placeholder.t called plan skip_all when builddebs.pl was absent, so a checkout that lost
the file reported 0 tests and exit 0. A test that cannot fail measures nothing.

Die instead, which is what makentp_ntp_deps.t already does for setupntp.

With builddebs.pl moved aside the file now exits 2 and prints "builddebs.pl not found";
before this change it exited 0 and printed "1..0 # SKIP builddebs.pl not found". With the file
present the test passes either way.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-15 21:10:56 -03:00
Daniel Hilst 6a41acf2db fix(xcat-core): the retried DNS update carries two TSIG records
makedns reports "error was FORMERR" for an update that named rejected with
NOTAUTH. The FORMERR is the answer to the retry, not to the first attempt.

send_ddns_update in ddns.pm signs the packet the caller built, and signs that
same packet again on each attempt. Net::DNS::Packet::sign_tsig appends the TSIG
to the additional section, so the second attempt sends two TSIG records and
named answers FORMERR. FORMERR is neither NOTAUTH nor SERVFAIL, so the routine
stops and reports it. The NOTAUTH and SERVFAIL retry can never be accepted, on
any algorithm.

Each attempt now signs a request of its own. A packet cannot be unsigned again,
so ddns_update_request copies the prerequisite and update records into a new
Net::DNS::Update instead, and the caller keeps the unsigned original.

ddns_update_retry.t fails before this change: the second attempt carries two
TSIG records, and an update that the retry answers with NOERROR still reports
failure.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-15 20:43:58 -03:00
Daniel Hilst 69be7872f2 test(xcat-core): capture the DNS update retry sending two TSIG records
send_ddns_update signs the same packet on every attempt. Net::DNS appends the
TSIG to the additional section, so the second attempt carries two TSIG records.
named answers FORMERR to that message, which is neither NOTAUTH nor SERVFAIL, so
the routine stops and reports FORMERR. The retry path can never be accepted.

ddns_update_retry.t drives send_ddns_update with a resolver that answers FORMERR
to a message with more than one TSIG record, as named does, and otherwise
answers a scripted rcode. It asserts that every attempt carries exactly one TSIG
record and the same update records, and that a retry answered NOERROR reports
success. Both subtests fail before the fix.

The header of each new test records that XCATROOT must name the tree under test,
because xCAT::Table adds the installed /opt/xcat/lib/perl to @INC.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-15 20:43:58 -03:00
Daniel Hilst 4eb9718548 fix(xcat-core): makedns rewrites its own TSIG key and then fails against it
makedns exits 1 on a management node that has Net::DNS below 1.36 and an
hmac-sha256 key, and reports "Failure encountered updating <zone> with entry
'', error was FORMERR".

update_namedconf in ddns.pm rewrites the named.conf key stanza to hmac-md5
whenever Net::DNS is below 1.36, and ddns_tsig_algorithm returns hmac-md5 for
the same reason. ddns_sign_update signs with site.dhcpomapialgorithm, which
xcatconfig sets to hmac-sha256 on EL9 and later. named matches a TSIG key by
name and by algorithm, so it answers NOTAUTH. The retry signs the same packet
a second time, and named answers FORMERR to the two signatures.

The version test protected the two-argument sign_tsig($name, $secret), which
produces an HMAC-MD5 signature only. ddns_sign_update signs every other
algorithm through a KEY RR, so the Net::DNS version no longer selects the
algorithm. This change deletes the rewrite and the version test, and signs with
the algorithm the key stanza declares. OmapiPolicy->algorithm_rr_type maps that
algorithm to its KEY RR number.

ddns_named_key_algorithm.t fails before this change: it reads the stanza as
hmac-md5 where the key was hmac-sha256.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-15 20:43:58 -03:00
Daniel Hilst b9b66aab14 test(xcat-core): capture makedns rewriting its own TSIG key algorithm
On a management node with Net::DNS below 1.36, makedns rewrites the named.conf
key stanza to hmac-md5. It then signs the update with the algorithm the site
table selects. named matches a TSIG key by name and by algorithm, so it rejects
every update and makedns exits 1.

ddns_named_key_algorithm.t drives update_namedconf over a scratch named.conf and
then signs one update with the context that run produced. It asserts that the
stanza keeps the algorithm the key was generated with, that the signature uses
that algorithm, and that named is not restarted. Two of its five subtests fail
before the fix.

ddns_omapi_policy.t pinned the rewrite as correct, so its expectations move to
the algorithm the key already has.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-15 20:43:58 -03:00
Daniel Hilst 6f635541e4 test(xcat-core): a missing deb converter makes the arch test skip, not fail
genesis_base_deb_arch.t stopped with a die when debuild-xcat-genesis-base was
absent, because a checkout without the converter has no deb rename to measure.
The BATS file skipped there instead, and a skip reads green.

setup() now asserts the script is readable.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 10:26:13 -03:00
Daniel Hilst e2ef0662aa test(xcat-core): the machine-type test is written as a Perl program
diskless_flat_vmothersetting_machine.t measures shell. It lifts two commands
out of reg_linux_diskless_installation_flat, renders the xcattest placeholders,
writes a wrapper that shadows lsdef and chdef, and shells out. The Perl adds
nothing the shell cannot state, and the case file it reads is shell itself.

The test moves to xCAT-test/bats, which the xcat_test workflow already runs. It
keeps what it proved: on ppc64le, x86_64 and riscv64 the restore writes a
machine type rather than an empty vmothersetting, the check that follows it
passes, and the remove path compares two defined strings. A command that stops
matching fails the test instead of covering nothing.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 10:14:00 -03:00
Daniel Hilst 4b9572a0a3 test(xcat-core): the Genesis shell tests are written as Perl programs
Eight unit tests measure shell code: the Genesis dracut cmdline hooks, doxcat,
getcert, the two Genesis deb builders, go-xcat and the genesis test case. The
Perl in each one is scaffolding. It reads the script, lifts a block out with a
regular expression, writes a wrapper, shells out and reads the files back. A
reader follows two languages to reach one assertion, and the scaffolding is
longer than the assertion.

xCAT-test/bats already states this kind of assertion in the language of the
thing under test, and the xcat_test workflow runs it. The eight files move
there. Each one keeps what it proved: the rpm architecture becomes the Debian
architecture and names the deb it supersedes, the dracut hook picks the console
mode the multiplexer can provide, the hook gives root the home directory /,
getcert stops when the image ships no openssl, the genesis case defines its
node with the architecture of the management node and fails when nodeset fails,
doxcat picks dhcpcd where the release drops the ISC client, and go-xcat names
the Genesis packages the packaging builds.

helpers/shell_source.bash gains refute_grep. bash ignores errexit for a command
inverted with "!", so "! grep" anywhere but the last line of a test can never
fail it.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 10:07:49 -03:00
Daniel Hilst 79b2e44498 style(xcat-core): the payload test comment describes the verifier that was replaced
The comment above the /usr/bin/awk case in genesis_payload_verification.t
said what the verifier used to do with an absolute path. The rule the
reader needs is what dracut_install does with one.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:50:36 -03:00
Daniel Hilst b91795a8f4 test(xcat-core): a failed extraction in thirteen test files stops the whole suite
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>
2026-09-14 08:46:57 -03:00
Daniel Hilst e82af69caf test(xcat-core): a missing fixture in two POWER install tests stops the whole suite
debian_install_prescript.t and ubuntu_subiquity_storage.t called BAIL_OUT
at eight places where an extraction or a fixture was not what they
expected. prove stops every remaining file on a bail-out, so one changed
script hides the results of every test that would have run after it. die
is just as loud and costs only its own file.

Three comments also carried the incident rather than the constraint. The
prescript test header named a build number, a cell, a case and the ssh
error the node produced nine times; the boot-file test repeated the
nodeset message and the media table below it.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:35:54 -03:00
Daniel Hilst fd97960dbc test(xcat-core): a failed extraction in the timezone test stops the whole suite
utils_gettimezone.t called BAIL_OUT when it could not lift the two
routines out of Utils.pm. prove stops every remaining file on a bail-out,
so a rename in Utils.pm that breaks the regex in this file also hides
every test that would have run after it. die is just as loud and costs
only this file.

The header also carried the incident report: a node name, an autoinst
file and line, the anaconda message and the minutes the node spent in
status=installing. The reader needs the contract, which is that the value
must be one token.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:35:02 -03:00
Daniel Hilst b0f87b2b99 style(xcat-core): the netplan test comment traces the failure across four layers
The comment on the use-domains assertion in ubuntu_subiquity_installnic.t
followed the missing search domain from systemd-networkd through
updateflag.awk to a node stuck in postbooting. The assertion below it
already names what is checked. The comment now carries the one fact the
code does not show: networkd defaults UseDomains to no.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:34:35 -03:00
Daniel Hilst ba5cf830f3 test(xcat-core): a failed extraction in the machine-type test stops the whole suite
diskless_flat_vmothersetting_machine.t called BAIL_OUT at four places
where it could not read or match the case file. prove stops every
remaining file on a bail-out, so an edit to the case that breaks a regex
in this file also hides every test that would have run after it. die is
just as loud and costs only this file.

The header also traced the empty vmothersetting out to the red cell. What
the reader needs is the ladder that names two architectures.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:34:10 -03:00
Daniel Hilst 012e2fb835 test(xcat-core): a failed extraction in the release test stops the whole suite
builddebs_release_placeholder.t called BAIL_OUT when its extraction of
the release decision stopped matching. prove stops every remaining file
on a bail-out, so a rewrite of builddebs.pl that breaks the regex in this
file also hides every test that would have run after it. die is just as
loud and costs only this file.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:33:44 -03:00
Daniel Hilst 3a715962d8 test(xcat-core): a failed extraction in the Genesis build-root test stops the whole suite
genesis_ubuntu_build_root.t called BAIL_OUT at four places where an
extraction stopped matching. prove stops every remaining file on a
bail-out, so one stale regex in this file hides the results of the tests
that would have run after it. die is just as loud and costs only this
file.

Four comments in the same file also explained more than the code hides:
the header retold the failure the test exists for, two narrated the two
helper subroutines, and one traced the lease failure across doxcat, the
image and the node.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:24:54 -03:00
Daniel Hilst 28e59642ca style(xcat-core): the boot-file test comments retell the bug report
Three comments in debian_install_boot_files.t explain more than the code
hides. One narrates the media table the assertions already list. One
repeats the nodeset error message and the releases that produce it. One
describes what mkinstall used to refuse before the change.

A comment states why, once, where the reader cannot re-derive it. Each of
the three now carries only the fact the assertions do not show.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 08:23:53 -03:00
Daniel Hilst b7be80d450 fix(xcat-core): the Ubuntu ppc64el netboot image has no dig
genimage returns 2 with "Failed to find usr/bin/dig" for
ubuntu22.04 and ubuntu24.04 on ppc64el, so packimage writes no initrd.gz
and the diskless compute node never boots.

xCAT-server/share/xcat/netboot/ubuntu had a ppc64el package list for
20.04 and 26.04 only. imgutils::get_profile_def_filename then falls back
to compute.pkglist, which installs no dig, no cpio and no chrony.

Add the 22.04 and 24.04 ppc64el lists, and the ppc64le spelling each
release already carries. Both take the content of the 26.04 ppc64el list:
the ppc64el images build their initrd with mkinitrd, so they install
bind9-dnsutils and leave out the dracut packages the x86_64 lists take.

ubuntu_ppc64el_pkglists.t fails without these files.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 07:30:16 -03:00
Daniel Hilst 2b150830c9 test(xcat-core): the Ubuntu ppc64el netboot image has no dig
genimage stops with "Failed to find usr/bin/dig in
/install/netboot/ubuntu24.04.4/ppc64el/compute/rootimg" and returns 2, so
packimage writes no initrd.gz and nodeset reports "Did you run genimage
before running packimg?". The diskless compute node never boots.

xCAT-server/share/xcat/netboot/ubuntu ships a package list for ppc64el on
20.04 and on 26.04 only. imgutils::get_profile_def_filename finds no
ppc64el list for 22.04 or 24.04 and falls back to compute.pkglist, which
installs no dig. mkinitrd copies usr/bin/dig into the initrd and
find_rootimg_file calls xdie when the file is absent.

The test reads the four ppc64el package lists the pipeline provisions and
asserts each one installs dig, a kernel and nfs-common. It fails on 22.04
and 24.04 and passes on 20.04 and 26.04.

Evidence: reg_linux_diskless_installation_flat on ubuntu-24-ppc64le-devel
in xcat-core-devel-ubuntu-cd build 120, xcattest.log.20260911175800 on
xcat25-mn.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 07:30:16 -03:00
Daniel Hilst 5570a4c64a fix(xcat-core): the Ubuntu POWER diskful install never leaves the installer
reg_linux_diskfull_installation_flat fails on ubuntu-22-ppc64le-devel and
ubuntu-24-ppc64le-devel in build #121 of xcat-core-devel-ubuntu-cd. The
Subiquity installer starts, errors in its early-commands, tars
/var/log/installer to port 8080 and reboots, nine times in 75 minutes. No
system is ever installed, so the address answers from the live installer and
the case ends on
"root@xcat25-cn: Permission denied (publickey,password)".

mkinstall in xCAT-server/lib/xcat/plugins/debian.pm selected
pre.ubuntu.subiquity and then replaced it with pre.ubuntu.ppc64 for every
ppc64 node, whichever installer was in use. pre.ubuntu.ppc64 writes a partman
recipe, and the early-commands append it to /autoinstall.yaml, which Subiquity
cannot parse.

pre.ubuntu.subiquity offered a UEFI branch and a BIOS branch, so a ppc64el node
took the BIOS branch and was given a bios_grub partition. POWER firmware loads
the boot loader from a PReP partition.

install_prescript now returns the script from the installer and the
architecture together, and the ppc64 script is reached only on the
debian-installer path. pre.ubuntu.subiquity gains a PReP branch, taken when
uname reports a POWER machine, which flags an 8M first partition prep and makes
that partition the grub device.

debian_install_prescript.t and the PReP case of ubuntu_subiquity_storage.t fail
without these changes.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 07:27:58 -03:00
Daniel Hilst 637d953d5a test(xcat-core): the storage harness counts two partitioning branches by hand
ubuntu_subiquity_storage.t rewrites every /tmp/partitionfile redirect in the
extracted block into a scratch tree, and bails out unless it rewrote exactly
two. The number is the count of firmware branches the script had when the
harness was written, so adding a branch stops the test rather than covering it.

The guard now counts the branches it found and requires one redirect each, and
fails separately if any path escaped the sandbox. It still bails out on a block
with fewer than two branches, which would mean the extraction stopped matching.

Still red on the PReP case of the previous commit: the block does not ask uname
for the machine architecture yet.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 07:27:58 -03:00
Daniel Hilst 4a8877618a test(xcat-core): the Ubuntu POWER diskful install loops in the installer
reg_linux_diskfull_installation_flat fails on ubuntu-22-ppc64le-devel and
ubuntu-24-ppc64le-devel in build #121 of xcat-core-devel-ubuntu-cd. The node
answers ping but the case ends on
"root@xcat25-cn: Permission denied (publickey,password)" and the node status
never leaves powering-on.

The serial console shows why: the Subiquity installer starts, runs the
early-commands, errors, tars /var/log/installer to port 8080 and reboots. Nine
cycles in 75 minutes. The installed system never exists, so the address belongs
to the live installer and it refuses the root key.

Two causes, both POWER-only.

mkinstall picks pre.ubuntu.subiquity, then overwrites that choice with
pre.ubuntu.ppc64 for every ppc64 node. That script writes a partman recipe;
the early-commands append it to /autoinstall.yaml, which Subiquity then cannot
parse.

pre.ubuntu.subiquity has a UEFI branch and a BIOS branch and nothing else, so a
ppc64el node takes the BIOS branch and is given a bios_grub partition. POWER
firmware boots from a PReP partition.

debian_install_prescript.t drives the script choice, which mkinstall keeps
inline, so it bails out. ubuntu_subiquity_storage.t gains a PReP case; its
extracted block asks uname for the machine architecture, which the block does
not do yet.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 07:27:58 -03:00
Daniel Hilst 2baa56534c fix(xcat-core): gettimezone returns an error sentence as a timezone name
The EL 10 riscv64 compute node installs no package. Its kickstart carries
"timezone Could not determine timezone checksum --utc" at line 21, anaconda
answers "One or zero arguments are expected for the timezone command", and the
node holds status=installing until retry_install.sh reinstalls over it
(build 114).

gettimezone in Utils.pm compares /etc/localtime against every file under
/usr/share/zoneinfo and, when that pipeline exits non-zero, returns the string
"Could not determine timezone checksum" to its caller as a name. The Rocky 10.2
riscv64 cloud image ships no /etc/localtime and runs on UTC, so the pipeline
prints nothing and exits 1.

gettimezone now reads the /etc/localtime symlink first, which is what every
current distribution uses and what the scan cannot answer for a host with no
/etc/localtime, then the scan, then /etc/timezone, and returns UTC when none of
them names a zone. It never returns a value with a space in it, which is all the
kickstart timezone command accepts. The paths take an optional root prefix so
the test drives them against a scratch tree.

xCAT-test/unit/utils_gettimezone.t stops without _zone_from_path, and each of the
three sources it asserts fails a separate assertion when it is removed.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 07:27:00 -03:00
Daniel Hilst 75474f10fd test(xcat-core): gettimezone returns an error sentence as a timezone name
The EL 10 riscv64 compute node xcat56-cn never installs a package. Its kickstart
carries, at line 21, "timezone Could not determine timezone checksum --utc";
anaconda answers "One or zero arguments are expected for the timezone command"
and stops. The node holds status=installing until retry_install.sh reinstalls
over it (build 114).

gettimezone in Utils.pm compares /etc/localtime against every file under
/usr/share/zoneinfo and returns the string "Could not determine timezone
checksum" when that pipeline exits non-zero. The Rocky 10.2 riscv64 cloud image
has no /etc/localtime and runs on UTC, so the pipeline prints nothing, exits 1,
and the sentence is written into the kickstart as a name.

This test drives the routine against a scratch root and asserts it names a zone
for a root with a symlink, with /etc/timezone, and with neither -- and that the
value is one token, which is all the kickstart timezone command accepts.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-14 07:26:59 -03:00
Daniel Hilst 840a6c56c6 fix(xcat-core): a compute node cannot resolve the management node by short name
On Ubuntu 26.04 the installed compute node keeps systemd-resolved, which takes
the DNS server from DHCP and no search domain, so /etc/resolv.conf reads
"search .". mypostscript then runs "updateflag.awk $MASTER 3002" with the short
management node name, the flag update fails eleven times, and the node stays at
postbooting until retry_install.sh gives up. The management node does offer
domain-search; the node discards it.

compute.subiquity.tmpl writes /target/etc/netplan/00-xcat-install.yaml with
dhcp4: true alone, so systemd-networkd applies its UseDomains default of no.
Add dhcp4-overrides: use-domains: true to both branches, the one that renames
the interface and the one that matches by MAC alone.

ubuntu_subiquity_installnic.t runs the template's own late-command and asserts
the netplan it writes carries the setting. It fails without this change.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-13 20:54:51 -03:00
Daniel Hilst 55b84e5530 test(xcat-core): the Ubuntu node netplan discards the DHCP search domain
The netplan xCAT writes for a compute node sets dhcp4: true and nothing else,
so systemd-networkd keeps its UseDomains default of no. The node takes the DNS
server from DHCP and drops the offered domain-search, and no single-label name
resolves on the installed node.

Assert the rendered netplan asks networkd to use the DHCP domains. The
assertion runs the template's own late-command, so it reads the file the
installer writes, not the template text.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-13 20:54:43 -03:00
Daniel Hilst 35e4ac2d3a fix(xcat-core): the diskless flat case clears the machine type on riscv64
reg_linux_diskless_installation_flat fails on an EL 10 riscv64 compute node after the node has
provisioned correctly. The check that fails is "vmothersetting contains machine", and lsdef shows
the attribute empty.

The case corrupts the KVM machine type, checks that the node does not boot, and restores it. The
restore reads str3 from a ladder that names ppc64 and x86_64 only, so on riscv64 str3 is empty and
chdef writes an empty vmothersetting. The remove path later compares str1 against that same empty
str3, which bash reports as "unary operator expected".

Both ladders gain a riscv64 arm giving machine:virt, the machine a riscv64 guest runs and the one
guest_arch_profile in kvm.pm sets. The two comparisons now quote their operands, so an empty value
compares instead of ending the command.

diskless_flat_vmothersetting_machine.t fails five of fifteen assertions without this change.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-13 04:54:05 -03:00
Daniel Hilst d94059e1b5 test(xcat-core): the diskless flat case clears the machine type on riscv64
reg_linux_diskless_installation_flat corrupts the KVM machine type of the compute node, checks
that the node does not boot, and restores it. The restore picks the machine type from a ladder
that names ppc64 and x86_64 only. On any other architecture str3 stays empty, so chdef writes an
empty vmothersetting and the check that follows it, "vmothersetting contains machine", fails. The
remove path reads the same ladder and compares against an empty string, which bash reports as
"unary operator expected".

diskless_flat_vmothersetting_machine.t lifts both commands out of the case file and runs them with
lsdef and chdef shadowed, so the assertions read the value the case would write. It fails five of
fifteen assertions, all of them riscv64.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-13 04:49:56 -03:00
Daniel Hilst 54ac0915d0 fix(xcat-core): the Genesis deb version never advances past snap000000000000
Every Genesis deb the Ubuntu dep pipeline publishes is versioned
2.19.0-snap000000000000. apt never upgrades an installed
xcat-genesis-base, so the channel cannot ship a Genesis fix.

Release is a tracked placeholder that buildrpms.pl overwrites with the
commit time. The dep job clones xcat-core only to build the Genesis
debs, so buildrpms.pl never runs there and builddebs.pl reads the
placeholder as an authoritative release.

builddebs.pl now treats an all-zero Release as an unstamped tree and
falls back to the commit time. snap_release() renders a real time, so
no build ever writes that value.

builddebs_release_placeholder.t covers it. The test fails on the
unfixed tree with snap000000000000.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-12 14:06:24 -03:00
Daniel Hilst 5d090ec2a2 test(xcat-core): the Genesis deb version never advances past snap000000000000
Every Genesis deb the Ubuntu dep pipeline publishes is versioned
2.19.0-snap000000000000, so apt never upgrades an installed
xcat-genesis-base and the channel cannot ship a Genesis fix.

Release is a tracked placeholder. buildrpms.pl overwrites it with the
commit time, but the dep job clones xcat-core only to build the Genesis
debs, so buildrpms.pl never runs and builddebs.pl reads the placeholder
as an authoritative release.

The test extracts the release decision from builddebs.pl and runs it
against a tree that carries the placeholder. It fails today with
snap000000000000 and passes for a real Release file, no Release file,
and an explicit --release.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-12 14:06:00 -03:00
Daniel Hilst 57dddd4efd test(xcat-core): follow the per-architecture Genesis scripts dependency
xcat_riscv64_genesis_dependency.t pins the deb dependency on the legacy Genesis
scripts as a single xcat-genesis-scripts-amd64 entry qualified [!riscv64]. That
entry gives a ppc64el management node the amd64 scripts package, which pulls the
amd64 Genesis base with it, and this branch replaces it with one entry per
architecture.

The test now asserts that every xcat-genesis-scripts entry names an architecture
that has a legacy Genesis, and that the ppc64el reduction asks for
xcat-genesis-scripts-ppc64el. The riscv64 assertions are unchanged: no entry
applies there.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-11 16:25:47 -03:00
Daniel Hilst da9e17fb53 fix(xcat-core): check the absolute paths the Genesis module installs, and name the deb the rename supersedes
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>
2026-09-11 16:00:57 -03:00
Daniel Hilst b3ed5e6d24 test(xcat-core): a Genesis image with no /usr/bin/awk passes verification
verify-genesis-payload reads the names the dracut module installs back out of
module-setup.sh and checks each one against the extracted payload. It drops
every name that starts with "/", so the 609 absolute paths the EL module names
are checked by nothing. An image built without /usr/bin/awk, /etc/services or
/lib64/libnss_dns.so.2 passes.

The Genesis debs carry the architecture in the package name. 2.19 renames the
ppc64 debs to ppc64el, and neither builddeb-genesis-base nor
debuild-xcat-genesis-base names the deb the new package supersedes. dpkg keeps
xcat-genesis-base-ppc64 installed beside xcat-genesis-base-ppc64el, and the old
package owns the same files under /opt/xcat/share/xcat/netboot/genesis.

genesis_payload_verification.t drives the verifier against a payload missing
/usr/bin/awk and one missing /etc/services. genesis_base_deb_arch.t asserts the
Replaces and Breaks the alien path writes. genesis_base_deb_control_rewrite.t
lifts rewrite_control() out of builddeb-genesis-base and runs it over the
control file in the tree.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-11 16:00:32 -03:00
Daniel Hilst 24e22671b4 Merge branch 'master' of https://github.com/xcat2/xcat-core into release/2.19-rc1
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>
2026-09-11 15:59:58 -03:00
Daniel Hilst 9aaf52235b fix(xcat-core): the Ubuntu Genesis image ships without a DHCP client
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>
2026-09-11 15:09:27 -03:00