2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-05 04:27:55 +00:00
Commit Graph

10707 Commits

Author SHA1 Message Date
Daniel Hilst 75d9a3a6d5 fix(xcat-core): the respawned monitor can be lost, or take 30s to come back
Three defects found by running the respawn against a live xcatd on an MN rather than only
against its unit tests.

A monitor whose child dies between xfork() returning and the assignment to $pid_MON is
lost for good. ssl_reaper matches $CHILDPID against $pid_MON, so a child reaped in that
window is compared against a stale value and missed, and $pid_MON is then left naming a
pid that no longer exists. The service loop reads !$pid_MON to decide whether to respawn,
so it never respawns again -- the same permanently dead xcatiport this whole change exists
to prevent, reached by a different route. Block SIGCHLD across the fork and the assignment
at both fork sites; the child unblocks on the same line, since it needs to reap its own
children. Reproduced with a widened window before the fix and confirmed closed after.

Recovery took 30 seconds on an idle daemon. The respawn only gets a turn when the service
loop comes round, and the loop parks in $bothwatcher->can_read(30) when there is nothing
to serve, so the full select timeout was being added to the respawn delay. Wait in 5s hops
while the monitor is down and at the usual 30s otherwise, so an idle daemon pays a few
extra wakeups only while xcatiport is actually dead. Measured on the MN afterwards: a
killed monitor returns in 5s, then 10s, then 21s across three kills in a row -- the
backoff, visible in wall-clock time -- reclaiming the port each time, with the SSL listener
holding the same pid throughout.

The tunables are read from %ENV and were compared before being validated, so an empty or
misspelt XCATD_MON_RESPAWN_* put "Argument isn't numeric" in the daemon log at every start.
Anything that is not a plain non-negative integer is now treated as unset.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-01 20:02:18 -03:00
Daniel Hilst 49b0c26efb fix(xcat-core): the install monitor's respawn pacing cannot be tested inside xcatd
The backoff that decides when to re-fork the install monitor is arithmetic over a handful
of counters, but it lives inline in xcatd among the daemon's globals, its signal handlers
and its fork. xcatd needs the database, SSL, the plugin tree and /var/run/xcat before it
will run, so nothing in a unit test can execute that arithmetic; a test can only match
patterns against the script's source and hope the shape it finds behaves. That is how a
retry budget which ran out and could never be refilled passed a green test run.

Move the pacing to xCAT::RespawnUtils as pure functions: each takes the current state and
the current time and returns the next state, reading no clock, no globals and no files.
Passing the time in is what makes the schedule checkable over a virtual clock instead of
in real seconds, and returning a new state rather than mutating one is what makes it safe
to call from the SIGCHLD handler -- the result is built before the caller installs it, so
a signal arriving partway through cannot leave the pacing half-updated.

The behaviour is unchanged from the previous commit and stays covered by
xCAT-test/unit/xcatd_monitor_respawn.t, which now executes these functions instead of
grepping for them: the delay doubles from XCATD_MON_RESPAWN_MIN_INTERVAL (5s) to
XCATD_MON_RESPAWN_MAX_INTERVAL (300s) and holds there without ever refusing a retry, and a
monitor that stayed up XCATD_MON_RESPAWN_HEALTHY seconds (60s) resets the backoff when it
later dies. policy() now also refuses a floor below one second, which would double to
itself and give a fork storm rather than a backoff, and a ceiling under the floor.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-01 20:02:18 -03:00
Daniel Hilst f22aed308a fix(xcat-core): xcatd stops respawning the install monitor and never resumes
The respawn of the install monitor was paced by a retry budget that, once spent, made
the daemon stop trying for good. That put xcatiport back in the state the respawn was
added to fix: with no monitor alive there is nothing left to reset the counter, so the
port stays dead until the whole daemon is restarted, and a port that frees up a minute
later is never picked back up. It only reached that state more slowly than before.

Pacing itself is needed. do_installm_service dies when it cannot bind the port, so an
unguarded re-fork spins as fast as fork allows while something else holds it, and keeps
re-entering that function's USR2 socket-takeover handshake. Replace the budget with an
exponential backoff that has a ceiling but no end: the delay doubles from
XCATD_MON_RESPAWN_MIN_INTERVAL (default 5s) to XCATD_MON_RESPAWN_MAX_INTERVAL (default
300s) and stays there. A monitor that cannot start therefore costs one fork per five
minutes for as long as that lasts, and is back within five minutes of the port becoming
free, with no restart and no operator action.

A monitor that ran for XCATD_MON_RESPAWN_HEALTHY seconds (default 60) plainly got the
socket and served, so its eventual death resets the delay: an isolated death is retried
at once and the backoff only builds up during a real streak of failures to start. The
ceiling is reported once per streak rather than on every attempt, and says that xcatd is
still retrying instead of that it has stopped.

The pacing lives in a marked mon-respawn-policy region, free of forking and of daemon
state, so xCAT-test/unit/xcatd_monitor_respawn.t drives the real code rather than a copy
of it.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-01 20:02:18 -03:00
Daniel Hilst 715fbed7a8 fix(xcat-core): respawn the xcatd install monitor when it dies
Re-fork the install monitor from the main service loop when $pid_MON has been cleared
and xcatiport is still configured, so a single death of that child no longer leaves
the port dead until the whole daemon is restarted. The forked child closes the SSL
listener and the UDP control socket before re-entering do_installm_service, so it
serves only the install monitor.

Rate limit the respawn. do_installm_service dies when it cannot bind the port after
its own retries, which is exactly the case where an unguarded re-fork would spin as
fast as fork allows and keep re-entering that function's USR2 socket-takeover
handshake against whatever still holds the socket. Consecutive attempts are separated
by XCATD_MON_RESPAWN_INTERVAL seconds (default 5) and capped at XCATD_MON_RESPAWN_MAX
(default 10), after which xcatd logs that it is giving up on the port rather than
retrying forever. A monitor that stayed up long enough to outlast the whole retry
budget resets the counter, so an unrelated death much later gets a full budget again.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
2026-09-01 20:02:17 -03:00
Daniel Hilst 0589bdbc70 Merge pull request #7782 from VersatusHPC/fix/template-install-device
fix(template): honour installnic when the kickstart names the install device
2026-09-01 18:35:45 -03:00
Vinícius Ferrão 10d1d92d79 fix(template): honour installnic when the kickstart names the install device
noderes.installnic names the adapter that deploys the operating system. The
kickstart network line ignored it and named the adapter from mac.mac alone, so
a node that sets installnic got a kernel command line that obeys installnic and
a kickstart that configures a different adapter. On a node with more than one
adapter the installer then brings up the wrong one and cannot reach the
repository.

Name the device from the shared resolution, which gives the interface name when
installnic or primarynic names one, and the address otherwise. A node that sets
neither attribute keeps the address it has today.

The unique local address still comes from the hardware address, because
autoulaaddress builds the address from it.
2026-09-01 11:09:00 -03:00
Vinícius Ferrão 96d351c8ff refactor(template): share the install device resolution
The order that names the install device is noderes.installnic, then
noderes.primarynic, then mac.mac. gen_net_boot_params owns that order for the
netboot kernel parameters. Only the Ubuntu template reused it. Every other
install template reads mac.mac on its own.

Move the reuse into install_device_params so that any install template can
share it. subiquity_install_netcfg keeps its own name and its own return
value, because netplan needs the pair of a name and an address. Behaviour
does not change.
2026-09-01 11:08:59 -03:00
Vinícius Ferrão 7d3cd9bd6d fix(netboot): use the HTTP tftp alias 2026-09-01 10:50:24 -03:00
Vinícius Ferrão ba6b880a5c refactor(install): make RISC-V EFI fix-up testable 2026-09-01 10:50:24 -03:00
Vinícius Ferrão 825fbb8d2b refactor(netboot): expose install image policies 2026-09-01 10:50:24 -03:00
Vinícius Ferrão 96b4e62fce refactor(dhcp): expose ISC client boot policy 2026-09-01 10:50:23 -03:00
Vinícius Ferrão 6df52f9e8b style(mknb): keep the riscv64 comments to the local facts
Five comments in the discovery path explained a consequence chain or
justified the code to a reviewer rather than stating what is not visible
locally: the payload protocol the code below already shows, a rationale
for the missing boot loader message, the two Genesis compression
variants, the HTTP and TFTP entry pair, and the :noboot divergence from
the PXELINUX files. Say the non-obvious part once.

Comments only; no executable line changes.
2026-09-01 10:50:23 -03:00
Vinícius Ferrão 5d1010bc97 feat(dhcp): boot RISC-V UEFI HTTP clients
Firmware configured for UEFI HTTP boot sends client architecture 28
(0x001c) and only accepts an offer whose boot file is a URL and whose
reply carries the HTTPClient vendor class; it ignores the PXE offer that
answers architecture 27. riscv64 nodes therefore could not boot at all
from firmware set up that way.

Answer them with the same grub2 image over HTTP. The URL has to name the
management node address of the network the request came in on, so the
class belongs to the subnet, like the POWER OPAL and xNBA network classes
next to it, and it is only offered while the boot loader is actually
published. The ISC backend renders the matching subnet branch.

This covers every client without a reservation, which is the discovery
case. A node that nodeset has configured keeps its per-node boot loader
over TFTP, as on the other architectures.
2026-09-01 10:50:22 -03:00
Vinícius Ferrão f945775317 feat(mknb): fetch the Genesis discovery payload over HTTP
The grub2 discovery configuration loaded the Genesis kernel and initramfs
over TFTP, a lockstep protocol that acknowledges every block and runs one
server process per client. Fetching the same 79 MiB Genesis image from a
node on the lab network took 61.5 s over TFTP and 1.2 s over HTTP, and a
whole cluster discovering at once queues on the TFTP server.

Write two entries instead. The default one sets root to the HTTP server
of the management node on that network and loads the same files from
below the TFTP root, the way nodeset does for netboot=grub2-http; the
second keeps the TFTP paths for a management node that does not serve the
TFTP root over HTTP, and "set fallback=1" moves to it when GRUB cannot
fetch the payload over HTTP. site.httpport is honoured.
2026-09-01 10:50:22 -03:00
Vinícius Ferrão f8b9fd8489 feat(copycds): publish the grub2 boot loader of the installation media
riscv64 nodes boot through UEFI and grub2 only, and xCAT builds no boot
loader: /tftpboot/boot/grub2/grub2.riscv64 has to come from the xcat-dep
grub2-xcat package or be copied by hand, which is a step an admin only
finds out about when a node times out in firmware.

The EL riscv64 media carry exactly that image as EFI/BOOT/grubriscv64.efi,
so copycd publishes it after a successful media copy, and says so. An
image the management node already has is never replaced, and the media of
every other architecture is untouched.
2026-09-01 10:50:22 -03:00
Vinícius Ferrão dcbaa51b75 fix(xCAT-server): stop the EL10 installer reserving a crash kernel riscv64 cannot use
EL10 defines no default crash kernel reservation for riscv64, so the
installer's kdump add-on falls back to writing the literal
"crashkernel=auto" into the boot loader arguments of the installed
system. EL10 kernels dropped support for that value: nothing is
reserved, but the string is on the command line, so kdump.service passes
its condition and then fails on every installed riscv64 node.

Turn the add-on off in the riscv64 templates. Nodes come up with kdump
inactive instead of failed, and a node that should take crash dumps gets
a real reservation the usual way, through linuximage.addkcmdline or
bootparams.addkcmdline.
2026-09-01 10:50:21 -03:00
Vinícius Ferrão 60afa553ab feat(xCAT-server): reserve a crash kernel for riscv64 diskless images
The kdump branch of the diskless kernel command line has a default
reservation for ppc64 and x86 only. On any other architecture an image
with linuximage.dump set but no linuximage.crashkernelsize got dump= and
no crashkernel= at all, so the kernel reserved nothing and kdump could
never run. EL has no default reservation for riscv64 either
(kdumpctl get-default-crashkernel is empty there), so nothing else fills
the gap.

Give riscv64 the same treatment as the architectures around it and
default to 256M. An explicit crashkernelsize still wins, and images
without dump are unchanged.
2026-09-01 10:50:21 -03:00
Vinícius Ferrão bef5bd5eef feat(xCAT-server): kickstart EL10 riscv64 nodes around the anaconda boot loader gap
The EL10 anaconda has no RISC-V EFI platform: on riscv64 it asks for the
x86 UEFI boot loader packages (grub2-efi-x64, shim-x64), which do not
exist, and registers the UEFI boot entry as \EFI\<distro>\shimx64.efi,
so a kickstart install stops at the missing packages and, once tolerated,
leaves a system the firmware cannot boot.

Add riscv64 templates for the rocky10/rhels10 compute and service
profiles that are the shared templates plus %packages --ignoremissing and
a %post fix-up, riscv64 package lists that add grub2-efi-riscv64 and
efibootmgr to the shared lists, and the fix-up itself
(post.rhels10.riscv64): it copies \EFI\<distro>\grubriscv64.efi to the
removable-media path \EFI\BOOT\BOOTRISCV64.EFI and re-points the UEFI
boot entry at grubriscv64.efi, so the installed node boots from disk with
or without usable NVRAM. Reinstalling a node replaces that entry instead
of adding another one.

The %post of a kickstart is a single shell script, into which xCAT
splices every #INCLUDE, and post.rhels10/post.rhels8 end it with
"exit 0"; the fix-up is therefore included ahead of them. The shared
templates and other architectures are unchanged.
2026-09-01 10:50:21 -03:00
Vinícius Ferrão 4f26b38d81 build(server): make perl-DB_File a weak dependency of xCAT-server
perl-DB_File is only used by the Confluent client
(lib/xcat/Confluent/Client.pm). EL10 dropped libdb, EPEL re-adds it only
on its own architectures, and riscv64 has no perl-DB_File at all, so a
hard Requires makes xCAT-server uninstallable on a riscv64 management
node. Ask for it weakly: dnf installs it where it exists and skips it
where it does not; the Confluent client stays optional.

The dependency generator also turns Confluent/Client.pm's "use DB_File"
into a hard perl(DB_File) requirement regardless of the Recommends, so
that one generated requirement is excluded as well, appended to whatever
filter the build root already set.

Weak dependencies need rpm 4.12, so both only apply on a build host that
has it (EL8 and later, or SUSE 15 and later); older build hosts keep the
hard requirement they have today.
2026-09-01 10:50:20 -03:00
Vinícius Ferrão 3917fd8345 feat(xCAT-server): add EL10 riscv64 osimage profiles
Provide the compute and service profiles for rocky10 and rhels10 on
riscv64: netboot pkglist/exlist/postinstall files and the service
otherpkgs lists for netboot and install. They mirror the x86_64 profiles
(every package resolves in the Rocky 10 riscv64 BaseOS/AppStream/CRB
repositories and the minimal-environment group exists there), with the
kbd keymap exclude spelled correctly, the duplicate man exclude dropped,
and goconserver pulled from the rh10/riscv64 dependency repository.
2026-09-01 10:50:20 -03:00
Vinícius Ferrão 2ef44d5d7f feat(xCAT-server): install and netboot EL10 riscv64 nodes
EL riscv64 media lay out the installer kernel and initrd under
images/pxeboot exactly like x86 and aarch64 media, but anaconda.pm only
looked there for those two families and geninitrd.pm refused riscv64
outright ("unknow arch"). Treat riscv64 like x86/aarch64 in both
places and recognise riscv64 kernels when a driver disk updates the
installer kernel. There is no riscv64 SUSE media, so geninitrd keeps the
unsupported-architecture error for sles/suse rather than reading the x86
SUSE layout.

Diskless images get a riscv64 default network driver list (virtio,
Intel, Realtek, Broadcom and Mellanox) and take the resolver libraries
from lib64, which is where riscv64 EL puts them.
2026-09-01 10:50:19 -03:00
Vinícius Ferrão 033b16d522 feat(mknb): write grub2 discovery configs for riscv64
mknb only knew how to publish a discovery boot configuration for x86
(PXELINUX and xNBA) and POWER (petitboot). Any other architecture got a
Genesis kernel and initramfs under /tftpboot/xcat and nothing that would
make a firmware boot them, so riscv64 discovery could not start.

riscv64 nodes boot through UEFI and grub2. Write one grub2 configuration
per network, /tftpboot/boot/grub2/grub.cfg-<network hex prefix>, using
the same network keys as the PXELINUX files. A net-booted grub2.riscv64
searches grub.cfg-01-<mac>, grub.cfg-<8 hex ip> and then shorter prefixes
of the ip, so the per-node files that nodeset writes keep priority and
the network file is only reached by clients without a node configuration.
The file is regenerated from the published Genesis artifacts (lzma
preferred over gzip), guarded by $grub_cpu so other grub2 architectures
can share it later, carries the xcatd endpoint, the serial console and
BOOTIF=$net_default_mac, and is dropped for networks served by a
:noboot interface. It is written by name rather than into an existing
file, because on a /32 network nodeset's hard link for the node carries
the same name.

Publishing a Genesis image now also drops the other compression variant
of that architecture, so a leftover genesis.fs.<arch>.lzma can no longer
be paired with a freshly published kernel by this configuration or by
--configfileonly. And since these configurations are only reachable
through grub2.<arch>, which xCAT does not build, a missing boot loader is
reported instead of leaving the nodes to time out in firmware.

xcatconfig now also runs mknb riscv64 when xCAT-genesis-base-riscv64 is
installed, and the usage text lists the architecture.
2026-09-01 10:50:19 -03:00
Vinícius Ferrão bd87aa9ed9 feat(nodediscover): default discovered riscv64 nodes to grub2
Discovery left noderes.netboot untouched for any architecture outside
x86, ppc and armv7l, so a discovered riscv64 node had no boot method and
nodeset failed to find a plugin for it.

Move the default-netboot ladder into _default_netboot(), which returns
the method to set or undef, and teach it that riscv64 nodes boot through
UEFI and grub2. The existing x86, PowerNV, ppc and onie rules are
unchanged; aarch64 is deliberately left as it was. The platform of the
discovery request is only read when the request carries it, so a node
that reports none does not gain the key, which would end up stored as
discovery data.
2026-09-01 10:50:19 -03:00
Vinícius Ferrão 9549e660f9 feat(dhcp): boot RISC-V 64-bit UEFI clients with grub2
RISC-V 64-bit UEFI firmware identifies itself with DHCP option 93
client-system-architecture 27 (0x001b, IANA processor architecture
types). Neither DHCP backend knew the value: Kea handed such clients no
boot file and ISC dhcpd fell through to the /yaboot catch-all.

Add an xcat-riscv64 Kea client class and an ISC subnet branch that send
them boot/grub2/grub2.riscv64, the same shape as the aarch64 entries.
The UEFI HTTP boot id (0x001c) is left alone: it needs a URL boot file
and the HTTPClient vendor class, which is a separate change.
2026-09-01 10:50:19 -03:00
Daniel Hilst 4a0d9e0bb0 Merge pull request #7801 from VersatusHPC/refactor/dhcp-omapi-key-rendering
refactor(dhcp): share OMAPI key configuration
2026-08-31 20:39:06 -03:00
Daniel Hilst aa447fe247 Merge pull request #7780 from VersatusHPC/feat/confluent-switch-topology
feat(confluent): export the switch topology of each node
2026-08-31 17:43:52 -03:00
Vinícius Ferrão 75715971b7 refactor(dhcp): share OMAPI key configuration 2026-08-31 16:10:14 -03:00
Daniel Hilst 0a93aba2b0 Merge pull request #7786 from VersatusHPC/feat/policy-user-groups
feat(policy): allow Unix group rules
2026-08-31 15:55:34 -03:00
Daniel Hilst e872fd20cf Merge pull request #7775 from VersatusHPC/fix/anaconda-driver-disk-kernel-arg
fix(anaconda): load the driver disk that is added to the initrd
2026-08-31 12:12:09 -03:00
Daniel Hilst bee09454f7 Merge pull request #7777 from VersatusHPC/fix/dhcp-infiniband-twin-entry
fix(dhcp): register the InfiniBand identity of a node that boots over IPoIB
2026-08-31 11:46:30 -03:00
Daniel Hilst 2abe22e203 Merge pull request #7791 from VersatusHPC/refactor/nfs-export-workflow
refactor(svrutils): centralize NFS export setup
2026-08-31 11:27:41 -03:00
Daniel Hilst ed537cd88f Merge pull request #7793 from VersatusHPC/refactor/nm-autoconnect
refactor(netboot): share NetworkManager autoconnect setup
2026-08-31 11:26:25 -03:00
Daniel Hilst ebba87379c Merge pull request #7795 from VersatusHPC/refactor/svrutils-linuximage-defaults
refactor(svrutils): centralize linuximage defaults
2026-08-31 11:23:20 -03:00
Daniel Hilst 3563bda58d Merge pull request #7796 from VersatusHPC/fix/rinv-pending-uefi-build-id
fix(rinv): report pending UEFI build ID separately
2026-08-31 11:20:11 -03:00
Vinícius Ferrão c4b7301fe6 refactor(dhcp): centralize dynamic-range rejection 2026-08-30 23:08:58 -03:00
Vinícius Ferrão a966cdba61 refactor(svrutils): centralize linuximage defaults 2026-08-30 22:41:26 -03:00
Vinícius Ferrão 4824e836ce fix(rinv): report pending UEFI build separately
The IMM pending_build_id property is not guaranteed to identify the primary UEFI bank. Keep it out of the active version value and expose it as a separate firmware inventory record.

Recovered from original commit b79c005061 by Jarrod Johnson.

Co-authored-by: Jarrod Johnson <jarrod.b.johnson@gmail.com>
2026-08-30 22:22:39 -03:00
Vinícius Ferrão 7032b75c94 refactor(netboot): share NetworkManager autoconnect setup 2026-08-30 21:53:29 -03:00
Vinícius Ferrão b5e08b243d refactor(svrutils): centralize NFS export setup
Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com>
2026-08-30 20:24:46 -03:00
Vinícius Ferrão e8d361ed0a refactor(debian): remove dead NFS export helpers
Remove the unreferenced Debian-local copies of setupNFSTree and setupStatemnt. Debian, Anaconda, and SLES callers already use xCAT::SvrUtils, and xCAT plugin dispatch does not expose these private symbols.

Signed-off-by: Vinícius Ferrão <2031761+viniciusferrao@users.noreply.github.com>
2026-08-30 20:24:45 -03:00
Vinícius Ferrão 2f798c20ea feat(policy): allow Unix group rules
Co-authored-by: Samveen <samveen@samveen.in>
2026-08-30 17:22:51 -03:00
Vinícius Ferrão 8fd34c04ff fix(anaconda): load the driver disk that is added to the initrd
xCAT appends dracut driver disks to the installer initrd as /dd.img. EL6 auto-loads that embedded image, while Anaconda 7 and newer require inst.dd=/dd.img on the kernel command line.

Record successful injection beside the generated initrd so nodeset --noupdateinitrd reuses the same decision as a normal nodeset. Clear the marker when rebuilding, validate the temporary archive paths, and do not create it when the disk cannot be copied, archived, or appended.
2026-08-29 18:28:00 -03:00
Vinícius Ferrão b7aa8eaa0f refactor(xcatd): keep command response state in CmdLog
Own collection, sensitivity, finalization, and reset as one request-scoped state object so xcatd only forwards callbacks and appends the finalized text.
2026-08-29 17:41:03 -03:00
Vinícius Ferrão 916091bfec refactor(xcatd): expose command log response handling 2026-08-29 17:15:23 -03:00
Vinícius Ferrão fc9a94edb6 Merge pull request #7765 from VersatusHPC/refactor/genimage-shared-os-version-parser
refactor(genimage): reuse shared OS version parser
2026-08-29 16:45:41 -03:00
Vinícius Ferrão c878dbf808 Merge pull request #7747 from VersatusHPC/fix/template-default-httpport
fix(template): omit the default HTTP port from installer URLs
2026-08-29 16:45:16 -03:00
Daniel Hilst 50257ff136 Merge pull request #7748 from VersatusHPC/fix/mellanox-mlx5-netdriver
fix(genimage): resolve Mellanox drivers from the target kernel
2026-08-28 18:11:29 -03:00
Daniel Hilst 1ba53dc7f8 Merge pull request #7754 from VersatusHPC/fix/centos8-minor-version-detection
fix(anaconda): read the CentOS Linux minor version from the release package
2026-08-28 17:38:16 -03:00
Vinícius Ferrão 999f18eacd Merge pull request #7737 from VersatusHPC/fix/cmdlog-response-classifier
fix(xcatd): classify secret responses by the shared secret set
2026-08-28 17:34:56 -03:00
Daniel Hilst a9a2c1f74e Merge pull request #7732 from VersatusHPC/fix/noderange-preauth
fix(xcatd): refuse the noderange ^file operator on unauthenticated requests
2026-08-28 17:32:33 -03:00