The shell, discover, standby and runcmd destinies load the Genesis kernel
through the same UEFI script as an osimage kernel. setstate asks for a shim
with the os of the node, so an install source answers for a kernel that no
distribution signed.
The new node keeps the install source of the first node of the test, so both
shims are on disk and the order decides the answer. Two assertions of twelve
fail: the script names /install/alma9.8/x86_64/EFI/BOOT/BOOTX64.EFI.
The nodeset helper takes currstate and provmethod, so the node reads as the
shell destiny it is.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The unit tests in this branch call the plugins in their own process against a
scratch TFTP root. No xcattest case reads a script that nodeset wrote on a
management node, so a cell whose compute node has netboot=ipxe runs this code
and asserts nothing about it. el9-x86_64-devel is such a cell.
nodeset_ipxe_secureboot_shim runs nodeset against the compute node of the conf,
reads /tftpboot/xcat/ipxe/nodes/<node>.uefi, and reports whether the line after
imgload names a shim that the web server serves. It puts the nodeset state back
afterwards. A node that is not an x86_64 ipxe node prints IPXE_SHIM_SKIPPED and
passes, so a bundle can carry the case on every cell. Where no provisioning case
has set nodetype.provmethod, the case names the stateful image of the node.
Measured on an AlmaLinux 9.8 management node: with the plugins of this branch
the case reports the shim of the install source and passes. With xnba.pm and
ipxe.pm from the branch point it reports imgargs kernel as the line after
imgload and fails.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This PR adds a shim to the UEFI boot scripts of netboot=ipxe nodes, so a node
with Secure Boot on reaches its kernel.
The firmware signature database does not hold the keys of a Linux
distribution. A UEFI node with netboot=ipxe loads snponly-shim.efi and
snponly.efi, both signed, and then stops at the kernel with "Verification
failed: Security Policy Violation".
xCAT::SecureBoot::shim_url_path names a shim for one node. The shim of the
install source comes first, because its vendor certificate signs the kernel of
its own distribution. copycds keeps the names of the DVD, so the module tries
EFI/BOOT/BOOTX64.EFI, EFI/BOOT/bootx64.efi and EFI/boot/bootx64.efi: EL and
openEuler ship the first, openSUSE the second and Ubuntu the third. When no
install source carries a shim, the module names the shim of ipxe-xcat, which
verifies a kernel that a MOK key signs.
xnba.pm writes the shim line after imgload in the UEFI script of an ipxe node,
and mknb.pm writes it in the UEFI discovery scripts. iPXE fetches the shim only
when it cannot load the kernel itself, so a node with Secure Boot off reads no
shim. netboot=xnba is unchanged: no key signs xnba.efi.
The elilo and ESXi paths and the Genesis kernel stay unsigned, and the iPXE
documentation now says so. The validation matrix gets a row for a UEFI install,
a netboot image and discovery with Secure Boot on.
secureboot_ipxe_node_shim.t and secureboot_genesis_shim.t drive nodeset and
mknb into a scratch TFTP root. Four assertions of ten and two of seven fail
without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
With netboot=ipxe a UEFI node loads snponly-shim.efi, which Microsoft signs,
and reaches iPXE with Secure Boot on. The boot scripts then load the kernel
with imgfetch and imgload, and the firmware refuses it: the signature
database does not hold the keys of the distribution, and nothing signs the
Genesis kernel. The node stops with "Verification failed: Security Policy
Violation".
The two tests drive nodeset and mknb into a scratch TFTP root and read the
UEFI scripts they write. Four assertions of nine and two of seven fail on
master: no script names a shim.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
build-utils/lib/XCAT/BuildUtils.pm said the inherited chrootuid 1000 stays in
effect for the chroot. A mock configuration is Python, so the later assignment
replaces the value and nothing reads 1000 afterwards. The in-chroot build user
becomes uid 0.
buildrpms_mock_resultdir_uid.t asserted that the inherited line is still
present. The pattern is a line of the test's own fixture and mock_config_text
only appends, so the assertion passes even when the function returns the base
text unchanged. It is removed.
The comment now states the replacement and its consequence, and records why
chrootgid is left unset. Without the chrootuid assignment the file fails 2 of
10.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
Add the linuximage gpgcheck attribute. When it is set to 1 or yes,
genimage passes --gpgcheck to the shared RPM image builder, which
exports the builder's trusted RPM keys exactly as it does for openEuler
and writes gpgcheck=1 with that gpgkey for the pkgdir, kerneldir and
otherpkgdir repositories. Unset keeps the existing unverified
configuration, openEuler stays always verified, and builders without
the option reject the attribute instead of ignoring it.
Collect the otherpkgs repositories in imgutils so that an otherpkgdir
holding only URLs no longer adds a file:/// repository that fails to
download metadata on EL.
Signed-off-by: Timothy Middelkoop <tmiddelkoop@internet2.edu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the extracted-function Perl runner with BATS tests that invoke
routeop in isolated Linux namespaces. Check route commands, persistent
entries, matching routes, and replacement failures.
The case failed on openeuler20.03sp4, openeuler22.03sp4 and openeuler24.03sp4, 3 occurrences
in xcat-ci build 89. The diff check failed, not the extraction.
encrypted_passwd_openssl_diskfull is the only case in passwd/case0 that selects the extraction
by distribution. It greps /etc/*release for SUSE, then for "Red Hat|CentOS|Rocky|Alma", then for
Ubuntu. On an openEuler management node all three miss and openEuler matches, so the case takes
the final arm, prints "Sorry,this is not supported os", writes nothing to
/tmp/instcryptedpasswd, and the diff against the password table reports rc=2.
openEuler now takes the Red Hat arm. compute.openeuler.tmpl writes
"rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password#", which is byte-identical
to every EL template, so field 3 holds the hash and the EL cells already pass with that arm.
The diff check is unchanged, so the case still fails when the extraction reads the wrong field:
field 3 of the expanded line gives diff rc=0 and field 4 gives rc=1.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
(cherry picked from commit a1b9372c413f54d18ba6a60d3839e9f75d7b8261)
confignetwork_secondarynic_nicextraparams_updatenode fails on EL8 because the dump
nic_cfg.sh prints carries no extra params, although configeth wrote CONNECTED_MODE and the
node has it.
nm_show resolves the connection's backend file by globbing
/etc/NetworkManager/system-connections for the UUID. The keyfile plugin keeps a connection
there, and on EL9 and EL10 it is the only plugin. On EL8 the ifcfg-rh plugin owns the
connection and keeps it under /etc/sysconfig/network-scripts, so the glob matches nothing and
no file is dumped. Every check that greps the dump for a value nm_show does not normalize
then sees nothing.
Ask NetworkManager for the path through the UUID,FILENAME fields and keep the glob as a
fallback. Read the MTU from either spelling, because a keyfile writes "mtu=" and an ifcfg
file "MTU=".
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
xcat_persist_nic_extra_param only appended a key that was absent. When the profile already held
CONNECTED_MODE=no, a request for yes left no. It appended after the last line, so a profile with
no final newline got NAME=xcat-ens4CONNECTED_MODE=yes. In a keyfile it appended at the end of the
file, which is not the [user] section when another section follows it.
The function now rewrites the profile with awk. It replaces the line of the exact key, or inserts
the key at the end of [user] for a keyfile and at the end of an ifcfg file. It adds [user] when the
keyfile has none.
The repair block of configeth moves into xcat_nm_persist_nic_extra_params, so a test can reach the
store decision. configeth calls it after the last nmcli con up. xcat_uses_nm_keyfile now calls
xcat_nm_conn_file instead of repeating its two nmcli calls.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The persist test sourced only xcatlib.sh and never reached the gate in configeth that skipped an
ifcfg profile, so putting that gate back left every test green. Its refusal test also passed on a
127 from a missing function.
The test now calls the repair through xcat_nm_persist_nic_extra_params with nmcli stubbed to
report an ifcfg file and a keyfile. It also captures three faults of xcat_persist_nic_extra_param:
it keeps an old value, it joins the key to a last line with no newline, and it appends a keyfile
key after a section that follows [user].
nic_cfg.bats captures that nm_show prints no profile when NM reports an ifcfg file, so the xcattest
case cannot match CONNECTED_MODE=yes there. nic_cfg.sh returns before its dispatch when sourced.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
xcat-ws.conf sends /xcatws and /xcatwsv2 to https only when mod_rewrite is
loaded. Without that module the aliases run the REST CGI on any port.
An IfModule !mod_rewrite.c block now answers 403 for both aliases.
RedirectMatch comes from mod_alias, which the ScriptAlias lines of the
same file already require. Other paths, such as /install, are not changed.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
xcat-ws.conf keeps its https redirect inside an IfModule mod_rewrite.c
block. No test starts Apache with the fragment, so nothing checks what the
REST aliases answer when that module is not loaded.
wsapi_apache_access.t starts a private Apache on a free port with the
fragment from the source tree. Without mod_rewrite it expects 403 from
/xcatws and /xcatwsv2. With mod_rewrite it expects the 302 to https. In
both cases /install is still served.
The Debian packages do not install xcat-ws.conf, so the GitHub action runs
the test from the source tree after install. The installed copy skips.
The test fails without mod_rewrite: both aliases answer 200 and run the CGI.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
`rpm -V xCAT-server` reports /etc/httpd/conf.d/xcat-ws.conf and
/etc/apache2/conf.d/xcat-ws.conf changed on every EL, openEuler and SUSE
management node, for the life of the install. %install shipped the Apache 2.2
fragment as the payload, and %post replaced it with the Apache 2.4 fragment
whenever httpd, apachectl or apache2ctl reported 2.4. Every supported
distribution runs Apache 2.4, so the file on disk never matched the package
digest. The drift is a permanent false positive for anyone who verifies an
installed xCAT before trusting it.
Both fragments also began with
`LoadModule rewrite_module /usr/lib64/apache2-prefork/mod_rewrite.so`. That
file exists only on SUSE under the prefork MPM. Apache tolerates it on EL and
openEuler because conf.modules.d loaded mod_rewrite first, and logs AH01574;
where the module is not loaded first, the missing file stops Apache from
starting.
xcat-ws.conf.apache22 and xcat-ws.conf.apache24 are replaced by one
xcat-ws.conf that serves both generations: the redirect sits behind
<IfModule mod_rewrite.c>, and the authorization directives behind
<IfModule mod_authz_core.c> and its negation. %install copies that one file to
both conf.d paths and %post no longer names them, so the payload is the final
file. %post runs a2enmod rewrite where a2enmod manages modules, which is how
SUSE gets the module the removed LoadModule used to pull in.
xCAT-test/unit/wsapi_apache_conf_portable.t fails 22 of its 30 assertions
without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
`rpm -V xCAT-server` reports /etc/httpd/conf.d/xcat-ws.conf and
/etc/apache2/conf.d/xcat-ws.conf changed on every EL, openEuler and SUSE
management node, for ever. %install ships the Apache 2.2 fragment as the
payload and %post replaces it with the Apache 2.4 fragment on any server that
reports 2.4, which is every supported distribution.
Both fragments also start with
`LoadModule rewrite_module /usr/lib64/apache2-prefork/mod_rewrite.so`. That
file is absent on EL and openEuler, and absent on SUSE under any MPM but
prefork. Apache skips the line today only because the distribution loaded
mod_rewrite first, and logs AH01574.
The new test parses each shipped fragment into directives and enclosing
sections, and the spec into its scriptlet sections. It asserts the fragment
declares no LoadModule and no absolute path, that the redirect and both
generations of the authorization directives sit behind their own <IfModule>
guard, and that %post never names the installed conf.
22 of its 30 assertions fail on this commit.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
bash ignores errexit for a command inverted with "!", so a "! grep" that is not the last line of
a bats test never fails it. The ifcfg test wrote two of them, and the first could not report a
[user] section appearing in an ifcfg profile.
Both now call refute_grep, the helper that exists for this. Restoring the keyfile-only write
fails that test on both assertions.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
confignetwork_secondarynic_nicextraparams_updatenode fails on openEuler 20.03sp4, 22.03sp4 and
24.03sp4 and on el8, while its sibling confignetwork_secondarynic_updatenode passes everywhere.
The only failing check is CONNECTED_MODE=yes, twice. The run log shows configeth receives the
value -- "array_nic_params 0=CONNECTED_MODE=yes" -- and the profile NetworkManager reports,
/etc/sysconfig/network-scripts/ifcfg-xcat-ens4-1, does not contain it afterwards.
configeth writes nicextraparams in configipv4 and then activates the connection. The comment on
the late persistence block states why that write does not survive: the nmcli con reload/up in the
restart phase re-serializes the connection from NetworkManager's in-memory model and drops
anything NetworkManager does not model. The block repairs it after activation, but its gate
requires xcat_uses_nm_keyfile, so it runs for a keyfile store only. el8 never reaches that test,
and openEuler reaches it and fails it because NetworkManager there reports an ifcfg file. Those
are the two families on the ifcfg path and the two that fail.
The block now runs for both stores. xcat_nm_conn_file asks NetworkManager which file holds the
connection rather than composing the name, because NetworkManager suffixes it when a file of the
plain name exists. xcat_persist_nic_extra_param writes the key as the profile spells it -- under
[user] with an xcat. prefix in a keyfile, plain in an ifcfg file -- and appends only when the key
is absent.
xcatlib_nic_extra_param_persist.bats covers both stores with nmcli stubbed. Two behavioural
mutants were run against it: restoring the keyfile-only behaviour fails the three ifcfg
assertions and leaves the keyfile ones passing, and composing the filename fails only the
resolution assertion.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
mock refuses every package of the openeuler-24.03-ppc64le target with
"Could not create dir dist/openeuler-24.03-ppc64le/rpms/SRPMS/.
Error: [Errno 13] Permission denied: 'dist'", so the target builds nothing.
mock 6.8 reloads its uid manager from chrootuid, so chrootuid now also owns
--resultdir and the three log files mock writes beside it. buildrpms.pl passes a
relative resultdir under a source tree owned by root. xcat-dep's
openeuler-24.03-ppc64le.cfg declares chrootuid 1000, for the native dependency
prerequisites that need a non-root build identity, and mock_config_text copied the
target configuration verbatim.
mock_config_text now assigns chrootuid 0 after the inherited lines. An xcat-core
rpm build has no declared non-root identity, and every other target already builds
as root because no other configuration sets the option. The inherited declaration
stays in the file, so the chroot still sees what xcat-dep shipped.
chrootgid is left alone. mock creates the in-chroot mock group with it, and
`groupadd mock -g 0` fails because the root group already holds gid 0: pinning both
took the target from a resultdir failure to "mock --init failed" on all fourteen
packages. root creates the resultdir whatever group it carries.
buildrpms_mock_resultdir_uid.t fails 2 of 11 without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
Every package of xcat-core-build-openeuler24.03-ppc64le #1 died before rpmbuild
started:
ERROR: Could not create dir dist/openeuler-24.03-ppc64le/rpms/SRPMS/.
Error: [Errno 13] Permission denied: 'dist'
30 such lines, 0 srpms. buildrpms.pl passes a relative --resultdir inside a source
tree owned by root, and mock 6.8 creates that directory as chrootuid.
openeuler-24.03-ppc64le.cfg declares chrootuid 1000 for the native dependency
prerequisites, and createmockconfig copied the target configuration verbatim, so
the core build inherited a uid that cannot write there. No openEuler x86_64
configuration declares one, which is why only the ppc64le target fails.
createmockconfig had no unit test because it built its text inline and wrote it
straight to /etc/mock. The rendering moves to XCAT::BuildUtils::mock_config_text,
which takes the base text and returns the rendered text; the script keeps the two
file operations.
buildrpms_mock_resultdir_uid.t drives it directly and fails 2 of its 11 checks, both
on the uid the rendered configuration carries.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
A new page describes the ipxe and xnba netboot methods: the files of the
upstream loader, UEFI Secure Boot through the shim and its limits, the
client test, the loader of nodes without a definition, the move of
nodes to the ipxe method and back, and the known limits of the upstream
loader.
The node guide, the noderes, node, group and nodeset pages list the ipxe
method, and the value lists mark xnba deprecated. The examples that
define an x86 node use netboot=ipxe. The mixed cluster and uninstall
guides name ipxe-xcat, and the DHCP validation matrix gets the iPXE
loader rows, Secure Boot included.
The global UEFI class of Kea gives only the upstream loader, so each
xnba node carries its own first-stage classes. They existed only with
the local xNBA BIOS file. With the xNBA UEFI file alone, a UEFI client
of an xnba node got the upstream loader and then the discovery script,
not xNBA and its node script.
The UEFI first-stage class of an xnba node now also exists with the
local xNBA UEFI file alone.
_run_omshell stops omshell after 10 seconds, but it read the output a
line at a time. A line read waits for a newline, and omshell writes its
prompt without one. An omshell that stalled after a prompt kept makedhcp
waiting past the deadline. The check of an external ISC server does that
read while it holds the DHCP lock.
_run_omshell now reads the output in chunks.
The cases without an xCAT dhcpd.conf now run the whole request. dhcpd
restarts with the new configuration before omshell starts, and the
configuration written last keeps its declarations. A failed restart
changes no host, and after a run that stopped before the restart, the
next run restarts dhcpd first.
makedhcp builds a new configuration when dhcpd.conf is missing or xCAT
did not write it. It replaced each host over OMAPI before dhcpd loaded
that configuration. A dhcpd that still ran an older one then rejected a
host that tests an iPXE feature option. OMAPI had already removed the
old host, so the node lost its reservation.
makedhcp now writes the new configuration and restarts dhcpd first. It
changes no host when that restart fails. The restart marker of an
upgraded configuration now also covers a new one, so the next run
restarts dhcpd first after a run that stopped before the restart.