nodeset boot clears nodetype.provmethod when the image of the node is a
netboot or statelite image. The helper restores the image attributes
after the replay of an osimage state only, so a node in boot loses its
image assignment and the case still reports IPXE_SHIM_OK.
The nodeset stub now clears provmethod on boot unless the osimage row
resolves to install or sysclone, as destiny.pm does. Two tests start a
node in boot with a netboot and a statelite image and assert that the
image attributes and the pending chain survive. A control test holds
the stub to the product behavior for an install image.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
When the forward nodeset osimage wrote the image attributes and then
failed, the restoration replayed a saved shell, standby or runcmd state
while the node still had the arch of the image. nodeset then wrote the
Genesis kernel and initrd of that arch. The chdef after the replay
corrected the database, not the boot files.
restore_state now writes provmethod, os, arch and profile back before
the replay. After the replay it writes them again only for an osimage
state, which sets them from the image row, and then writes currchain.
A failed chdef still makes the case fail without IPXE_SHIM_OK.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
When the forward nodeset osimage writes the image attributes and then
fails, the node keeps the arch of the image. ipxe_secureboot_shim.sh
replays the saved shell, standby or runcmd state before it writes the
saved arch back, so nodeset writes the Genesis kernel and initrd of the
image arch. The chdef that follows corrects the database, not those
boot files.
The nodeset stub now records the Genesis kernel and initrd that a
shell, standby or runcmd state selects from the current node arch, and
can fail nodeset osimage after it updates the attributes. Two cases
start an x86_64 node at shell and at runcmd=bmcsetup with a ppc64le
image, and assert the x86_64 kernel and initrd. Both fail against the
current helper.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
nodeset osimage= sets chain.currchain to boot and copies os, arch and
profile from the osimage row into the node. The cleanup replayed only
chain.currstate, and restored profile only when provmethod was empty.
A node at runcmd=bmcsetup lost the osimage action queued after it, and
a node whose image row differed from its own values kept the values of
the row, while the case printed IPXE_SHIM_OK.
The helper now reads currchain with the other attributes before the
first mutation. After the replay it writes back provmethod, os, arch,
profile and currchain as it read them, on both paths. A failed write
fails the case without IPXE_SHIM_OK.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
nodeset osimage= sets chain.currchain to boot and copies os, arch and
profile from the osimage row into the node. The cleanup of
ipxe_secureboot_shim.sh replays only chain.currstate, and restores
profile only when provmethod was empty. A node at runcmd=bmcsetup with
an osimage action queued after it loses that action, and a node whose
image row differs from its own os, arch or profile keeps the values of
the row. The case still prints IPXE_SHIM_OK.
The stubs now keep the node attributes and osimage rows in a store, and
the tests assert the values the node ends with. Five tests fail on the
current helper.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The bats stub returned one exit code for every "chdef netboot=", and the
helper calls chdef twice: once to set the method to ipxe, and once to put
the saved method back. With the stub failing both, "a netboot method that
cannot be put back fails the case" passed on the FORWARD failure, so
removing restore_rc=1 from the restoring branch left all 18 tests green.
The test named a defect it could not detect.
The stub now counts its netboot calls and fails the one the test names,
so the forward chdef succeeds. The test asserts that forward call is in
the call log, and matches the message only the restoring branch prints.
Removing restore_rc=1 now fails test 8 and no other.
docs/source/advanced/ipxe/index.rst said both methods run the same boot
scripts, which stopped being true when the shim line became conditional
on the method. It now says what differs, and states that Secure Boot
reaches netboot=ipxe only: xnba.efi is unsigned, and grub2 nodes are out
of scope.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
ipxe_secureboot_shim.sh reads every attribute and the nodeset state before the
first mutation, refuses a state it cannot put back, and replays the saved state
verbatim.
read_attr keeps the exit status of lsdef instead of the status of the sed that
follows it, so a lookup that failed no longer reads as an attribute that is
unset. must_read ends the case on a failed lookup, before the chdef and the
nodeset that change the node. This is what stops the restoration clearing a
provmethod or a netboot method the node really had.
The restoration replays the whole string nodeset stat reported, so a state that
carries an argument goes back with it. A state the helper cannot replay ends the
case while the node is untouched: install, netboot and statelite are deprecated
and the restoring nodeset rejects them, and iscsiboot, image, winshell and
sysclone read rows this case never saved. The restoring chdef also puts back
nodetype.profile, which nodeset osimage= overwrites from the osimage row.
xCAT-test/bats/ipxe_secureboot_shim_restore.bats covers it. Against the previous
commit the four refusal cases exit 0 and print IPXE_SHIM_OK after calling nodeset
osimage= on the node.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
restore_state in ipxe_secureboot_shim.sh matched the saved nodeset state against
boot, offline, shell and standby. nodeset stat reports chain.currstate verbatim,
so runcmd=bmcsetup, osimage=<name>, runimage=<task> and the deprecated install,
netboot and statelite all fall past that list. The helper then restored nothing
and still printed IPXE_SHIM_OK, so the node kept the installation the case
configured and the next case on that node measured it.
The lookups hide the same failure one layer down. lsdef and nodeset run in a
pipeline, so the exit status comes from sed or head and is always zero, and an
attribute that is unset prints the same empty string as a lookup that failed.
The helper clears the provmethod and the netboot method it reads as unset, so a
failed lookup makes it delete a value the node really had.
The tests drive the helper through nine states and lookups. Against the unfixed
helper, all four refusal cases exit 0 and print IPXE_SHIM_OK after calling
nodeset osimage= on the node, and the provmethod case prints
"provmethod=unset" for a provmethod the stub holds set.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
requested_firmware was called as
requested_firmware($confdata->{vm}->{$node}->[0]->{othersettings}). An rvalue
dereference chain autovivifies its intermediate links, so that read makes
$confdata->{vm}->{$node} exist, as an arrayref holding an empty hashref, for a
node with no vm row. A later truth test on that row then answers yes for a node
that is not a VM.
vm_othersettings reads the column one link at a time and returns undef at the
first link that is absent, so the read leaves $confdata as it was. Both call
sites use it.
Three checks in kvm_uefi_firmware.t hold this down, and all three fail when
vm_othersettings is changed back to the dereference chain: the read creates no
vm table, creates no row for the node, and leaves confdata equal to its
starting value.
build_xmldesc and build_diskstruct still autovivify the same row through their
own older reads of vm.storagemodel and vm.host. That is unchanged by this
commit and is measurable: the confdata both routines leave for a node with no
vm row is identical with and without the firmware code.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
guest_arch_profile reaches the firmware selection only for riscv64, so an
x86_64 KVM guest always comes up on SeaBIOS. A node that must boot the UEFI
shim has no way to ask for UEFI.
vm.othersettings takes a sixth key, firmware:efi. requested_firmware reads it,
and guest_arch_profile then puts firmware="efi" on <os>. libvirt selects the
firmware files from that attribute and writes <loader> and <nvram> itself. The
guest also moves to q35, because every x86_64 OVMF descriptor targets pc-q35-*
and libvirt finds no efi firmware for the i440fx machine it defaults to. q35
has no IDE controller, so the disks and the optical drive move to scsi. A
machine type the node names for itself still wins. A firmware value other than
efi is refused by name.
No node asks for a firmware by default, so a guest that does not ask comes out
as before, on SeaBIOS with ide disks. <bios useserial='yes'/> stays in place
for the UEFI guest, which keeps its boot on the serial console.
kvm_guest_arch.t, kvm_diskstruct_bus.t and kvm_createstorage_model.t extract
routines from this file by name and eval a copy, so each one names
requested_firmware now.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
build_xmldesc reaches its UEFI path only for riscv64, so no test covers an
x86_64 guest that asks for UEFI. The existing kvm unit tests cannot cover it
either: they read kvm.pm, extract four routines with a regex and eval a copy,
which keeps passing when the original changes.
kvm_uefi_firmware.t loads the plugin itself, with Perl stubs for the database,
the monitoring dispatcher, the thread helper and the libvirt binding. It calls
build_xmldesc and reconfigvm, and reads the domain XML they return.
process_request already set $parser, $node, $confdata and $updatetable before
it called the domain builder. They are package variables now, so the test sets
them the same way. The plugin reads them unchanged.
Six checks fail on this commit. The guest states no firmware and no machine
type, its disks stay on a bus q35 cannot carry, the rewritten guest asks for no
firmware, and a firmware value libvirt cannot select is accepted in silence.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The case accepted IPXE_SHIM_SKIPPED, so a cell whose compute node is not
declared netboot=ipxe passed it without reading a boot script. Four of the six
confs that carry the case declare netboot=xnba, so four cells reported a pass
for a shim line nothing had measured.
The case now asserts IPXE_SHIM_OK and declares arch:x86_64, which keeps it off
another architecture through xcattest rather than through a token that passes.
The helper sets netboot=ipxe when the node is declared another way, and puts the
method back before the nodeset that restores the state. A netboot method that
cannot be put back is reported like the provmethod and the nodeset state. The
two conditions that used to skip now fail and name what the case could not read.
xCAT-test/bats/ipxe_secureboot_shim_restore.bats fails 5 of 9 without this
change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
The case asserts output =~ IPXE_SHIM_(OK|SKIPPED), so the helper's skip path
passes it. The skip is not rare: the case is in rhels_x86_daily_flat.bundle,
which six confs use, and four of them declare netboot=xnba on their compute
node. Those four cells pass the case without reading a boot script.
Five tests capture it. The lsdef stub now reports the netboot method and the
arch from variables, and the chdef stub can fail the netboot call alone. The
tests require the helper to set the netboot method it needs, to measure, to put
the method back before the restoring nodeset, to report a netboot that cannot
be put back, and never to exit 0 without IPXE_SHIM_OK.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
restore_state dropped the exit status of chdef and nodeset, and the helper
printed IPXE_SHIM_OK after it. A node left with provmethod set and nodeset
osimage reads as a pass, and the next case on that node runs against the
state this one set.
restore_state now reports which command failed and returns non-zero, and the
helper exits non-zero in place of the pass token. An EXIT trap holds the
restoration, armed immediately before the nodeset call that changes the state,
so no later branch can leave the node behind. A skip above that line changes
nothing and calls neither command.
Two assertions of five in ipxe_secureboot_shim_restore.bats fail without this
change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
ipxe_secureboot_shim.sh calls nodeset to reconfigure one node for
installation, reads the UEFI script, and then puts the nodeset state back.
restore_state ignores the exit status of chdef and nodeset, so the case prints
IPXE_SHIM_OK and returns 0 while the node is still configured for
installation. The next case on that node measures the state this one left.
The test drives the helper with lsdef, nodeset and chdef stubbed, and records
every call. Two assertions of five fail: with either restoration command
returning non-zero the helper exits 0 and prints IPXE_SHIM_OK.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
process_request walks xcat/ipxe/nets and xcat/xnba/nets in one loop and wrote
the shim line into the UEFI script of both. netboot=xnba is out of scope: no
key signs xnba.efi, and its loader does not know the shim command, so the line
stops the discovery of a node that never asked for Secure Boot.
The loop now carries the method name beside the directory, and the shim line
goes only into the script of the ipxe method. xnba.pm already gates the node
scripts the same way.
One assertion of nine in secureboot_genesis_shim.t fails without this change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
mknb writes the UEFI discovery scripts of both netboot methods in one loop,
over xcat/ipxe/nets and xcat/xnba/nets. The shim line reaches both. The loader
of xnba does not know the shim command, so the line stops a legacy xNBA
discovery even with Secure Boot off.
secureboot_genesis_shim.t now reads the xnba script of the same run that reads
the ipxe one. One assertion of nine fails: the xnba UEFI script names
/tftpboot/xcat/ipxe/x86_64-sb/shimx64.efi.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
setstate writes the Genesis kernel into the UEFI script of a node for the
shell, discover, standby and runcmd destinies. It asked for a shim with the os
of the node, so a management node that ran copycds named the shim of that
install source. That shim trusts the vendor certificate of the distribution,
which signs no Genesis kernel, and the node stops at the same Security Policy
Violation.
shim_url_path takes the kernel of the boot script. A Genesis kernel skips the
install source and takes the shim of ipxe-xcat, which reads the MOK list. An
osimage kernel keeps the install source first. mknb already named the loader
shim, because it passes no os.
Two assertions of twelve in secureboot_ipxe_node_shim.t fail without this
change.
Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
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>