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

3395 Commits

Author SHA1 Message Date
Jarrod Johnson 5025c904e8 Ensure keepalive are sent while following
keepalives would be postponed by incoming keepalives.

Fix this by tracking keepalive on transmit only, not on receive.
2026-09-04 12:01:01 -04:00
Jarrod Johnson 2f49ab602d Fix incorrect attribute on asyncio task 2026-09-03 13:42:43 -04:00
Markus Hilger 497a7abffb Do not cache an SDR that failed to build
init_sdr assigned self._sdr before initialize() ran, so a failure left the
half built object in the cache. The next call saw a non-None _sdr and handed
back that partial repository rather than trying again.

The visible symptom is a first call raising and the second appearing to
succeed. The real cost is on a bmc where the read fails once: the client
keeps the incomplete sdr for the life of the session and every later sensor
lookup answers from it without complaint.
2026-09-03 02:15:22 +02:00
Jarrod Johnson 7afbbca691 Merge pull request #291 from Obihoernchen/fix/multi-nic-refusal
Say which interfaces a multi-homed BMC has, rather than crash
2026-09-02 10:29:29 -04:00
Jarrod Johnson d4c5fd850a Merge pull request #290 from Obihoernchen/fix/report-failures-not-crashes
Let a failed request report itself
2026-09-02 10:16:16 -04:00
Jarrod Johnson 26c69e6cc0 Merge pull request #289 from Obihoernchen/fix/health-optional-collections
Handle Redfish services that omit optional collections
2026-09-02 10:13:26 -04:00
Jarrod Johnson fb0ecb50f7 Merge pull request #288 from Obihoernchen/fix/parse-fractional-seconds
Read a fractional second as a fraction
2026-09-02 10:12:03 -04:00
Jarrod Johnson 626d9ba15f Merge pull request #287 from Obihoernchen/fix/ipmi-identify-refusal
Say that IPMI cannot read an identify state
2026-09-02 10:10:35 -04:00
Markus Hilger 9012888cc0 Report a refused XCC web login instead of returning None
get_webclient falls off its end when /api/login answers anything but 200, so
it returned None. wc() passes that back, and thirty of the thirty-four call
sites use it unchecked, so a refused login arrived as "'NoneType' object has
no attribute 'grab_json_response'" from wherever it landed.

Raised where the failure is known, and with the status: 404 is firmware with
no web api, or a Redfish-only capture of one, while 401 is credentials it
will not take. Neither was distinguishable before.

The other four call sites are the inventory reads, and they always did check.
They answer partially when the web interface is out of reach, which is why
nodeinventory still says something useful. They ask through wc_if_available
now, so that tolerance is stated rather than resting on a None.
2026-09-01 23:52:49 +02:00
Markus Hilger 7a7bd758a4 Let a failed request report itself
Two places where the code that exists to explain a failure fails instead, and
the caller is shown the second failure rather than the first.

_do_web_request builds its message from the response body when that body is
not the JSON error document the spec asks for. An html 404 page is exactly
that, the body is bytes, and str + bytes raised TypeError. The status and the
body never reached anyone.

LenovoFirmwareConfig raised a bare Exception when python-lxml and
python-eficompressor are absent. Confluent has no handler for one, so a
missing dependency showed as "Unexpected Error" and hid a message that
already said what to install.

Neither changes what fails, only what the caller is told.
2026-09-01 23:52:49 +02:00
Markus Hilger 1d8dcae6b0 Refuse plainly when a BMC lists no interfaces at all
Same function, one line above. EthernetInterfaces is optional, and when it is
absent the None went into a request and raised TypeError from the url library
rather than saying what was missing.

Kept beside the ambiguous case because the two are one question asked twice.
2026-09-01 23:52:25 +02:00
Markus Hilger 6909d1b5df Say which interfaces a multi-homed BMC has, rather than crash
Dedicated plus shared is how BMCs are built, so several NICs is ordinary.
_get_bmc_nic_url only reaches the count when the address the session came in
on matches none of them, which is what a tunnel or a NAT does, and it then
raised the bare PyghmiException base class.

Confluent has no handler for the base class, so it fell through to the
generic one and showed "Unexpected Error" plus a traceback, for a machine
doing nothing wrong. UnsupportedFunctionality now, which the redfish plugin
already reports plainly and which stays inside PyghmiException.

The message said "does not have exactly one interface" without saying how
many, which ones, or what to do. Every caller takes a name, so it lists the
candidates, and the empty case reads differently from the ambiguous one.
2026-09-01 23:52:25 +02:00
Markus Hilger 26151c506f Read power and boot from a service that has no system
A Redfish service may publish no Systems collection, and power and cooling
equipment does exactly that. sysurl is then None, and get_power and
get_bootdev handed it straight to a request, raising TypeError from inside
the url library.

sysinfo already guarded the same field. Both now ask through _system_url and
get a refusal naming what is missing. DMTF publish three services of this
shape, which is why they sit commented out in inventory-dmtf.yaml.
2026-09-01 23:51:32 +02:00
Markus Hilger 5d5ad821f4 Read health from a service that publishes no PCIe
PCIeDevices and PCIeFunctions are optional, and get_health indexed both
without checking. _get_adp_urls in the same file already spells it
.get('PCIeDevices', []), so these two were the outliers.

Power and cooling equipment has no PCIe at all. The KeyError escaped the
health read and reached the user as "Unexpected Error" with a traceback
behind it. Reproduces offline against DMTF's public-rackmount1 mockup.
2026-09-01 23:51:32 +02:00
Markus Hilger 2e7ce63b51 Read a fractional second as a fraction
parse_time read the digits after the decimal point as whole milliseconds, so
'.5' became 5ms instead of 500ms. Only a three digit fraction came out right,
and a BMC may write either.

'.5', '.50' and '.500' are all 500ms now, '.125' is 125ms. Every other format
parse_time accepts is untouched.
2026-09-01 23:51:00 +02:00
Markus Hilger 492bfeb974 Say that IPMI cannot read an identify state
nodeidentify against an IPMI BMC printed the node name, nothing after it, and
exited 0. A script checking the exit code carries on with an empty value,
which is worse than being turned down.

IPMI can set the identify light and has no command to read it back, so aiohmi
has no get_identify. The empty state was a way of not saying so.

The comment above that branch called identify "read-only", which is the
opposite of the truth.
2026-09-01 23:51:00 +02:00
Markus Hilger 0d2b23de2f Run on a Python that has no crypt module
crypt left the standard library in 3.13 and both imports of it here are
unconditional, so the server does not start on a 3.13 distro that ships no
crypt shim of its own.

legacycrypt and crypt_r both reach the same libcrypt call, tried in that
order because legacycrypt is pure ctypes while crypt_r wants a compiler.
Both were checked byte for byte against the stdlib for the $6$ salts used
here, and a hash written under the stdlib verifies under either, so stored
crypted.* attributes keep working.

Recommends rather than Requires, and only above 3.12: el9 and el10 still
ship the stdlib module, and some 3.13 distros package no candidate at all,
where a hard dependency would make the rpm uninstallable.
2026-09-01 06:03:16 +02:00
Jarrod Johnson aec404e134 Normalize scan to async
Also, for lots of pending nodes, yield between nodes for responsiveness
2026-08-28 15:51:13 -04:00
Jarrod Johnson 054ca63600 Fix macmap offload startup concurrency
State of offloader was never checked after acquiring the lock.

Fix by checking with the lock held.

Also, neaten up by putting all the offload startup inside the function to start it up.
2026-08-28 13:23:16 -04:00
Jarrod Johnson 687b8e47e4 Rework ownership/permission staging and cleanup
Directories are left as 'boring' confluent directories to enable staging.

Then the ownership/permssions on directories are fixed up.

Then after completion, make sure ownership is back to boring before asking rmtree.
2026-08-27 11:46:33 -04:00
Jarrod Johnson 6d1733817e Fix empty kernelargs handling 2026-08-25 15:04:47 -04:00
Jarrod Johnson fff6875d33 Limit host based key types used by ansible
By default, ansible prefers to try host based authentication, which is good.

But when it doesn't work, it tries every key attempt, which is normally fine.

However, SSH counts key attempts the same as passwords, so hardening that restirct password attempts are fouled before it can even get to try a public key.  Thus let host based only consume one attempt.
2026-08-25 10:59:29 -04:00
Jarrod Johnson 8a57216803 Block user from naming group/node the same thing
If a node and a group have the same name, things can get very confusing and hard to deal with.
2026-08-25 10:47:39 -04:00
Jarrod Johnson 3496f90fb7 Make sure a child can't except out of a forked child
If an exception were incurred in child in fork, the code could break out.
2026-08-25 09:05:04 -04:00
Jarrod Johnson aa9b7ea4ca Yield cooperatively during nodelist change 2026-08-24 16:52:13 -04:00
Jarrod Johnson f5d7c271b5 Fix issue with non-systemd startup 2026-08-21 07:15:52 -04:00
Jarrod Johnson 8a2d5016f3 Rework the systemd notification.
Confluent didn't act 'healthy' toward systemd delaying restart needlessly.

Worse, in a collective it could never show as started if the quorum didn't come back.

Pull the startup to before collective init, and indicate watchdog liveness during that time.
2026-08-20 12:40:55 -04:00
Jarrod Johnson 23445b3a5e Rework vtbuffer management
Only start vtbufferd on first use.

Do not restart more frequently than once every 30 seconds.
2026-08-20 08:33:35 -04:00
Markus Hilger ef9afa7d72 Fix advanced settings
Disabled this by accident when doing the async fixes.
Upstream pyghmi passess this as well.
2026-08-20 00:41:34 +02:00
Jarrod Johnson 8b67b20e8a Remove stray print statement 2026-08-19 14:11:02 -04:00
Jarrod Johnson cf14bda3b7 Wrap up SOL exception more neatly 2026-08-19 13:46:44 -04:00
Jarrod Johnson 3463bd24c1 Avoid spawning redundant macmap workers 2026-08-19 13:43:29 -04:00
Jarrod Johnson 42fd63763e Defer more asyncio Lock creation
Must be created after loop is running for python 3.9.
2026-08-19 13:21:32 -04:00
Jarrod Johnson 2bd931658c Defer creating locks until loop is running
In python 3.9, this pattern was causing issues.
2026-08-19 13:13:20 -04:00
Jarrod Johnson a9da8ab3d3 Fix httpapi getaddrinfo
Another area that failed to get the positional arguments converted to keyword.
2026-08-19 11:24:41 -04:00
Jarrod Johnson 193cced1a6 Remove disused socket imports 2026-08-19 11:21:42 -04:00
Jarrod Johnson a0d99a15ce Fix use of positional arguments in getadrrinfo
The new getaddrinfo needs this as a keyvalue pair.
2026-08-19 11:05:41 -04:00
Jarrod Johnson ec64a6d46c Change to asyncio based name lookup in various places 2026-08-19 10:28:55 -04:00
Jarrod Johnson 31647a52e1 Remove disused RLock and simplify code. Fix name lookup stalls on connection. 2026-08-19 09:56:28 -04:00
Markus Hilger c13a434246 Say when a named log source answered with nothing
An ipmi node named no source at all, so -s dropped every event, and a
log with no entries can never be named by one.
2026-08-19 15:10:55 +02:00
Markus Hilger 9cdcbe4046 Look elsewhere when the manager publishes no log services
The early return sat before the fallback, so the one layout it was
written for was the one it could not reach.
2026-08-19 15:10:55 +02:00
Markus Hilger caa857ead0 Gather every event log a platform keeps, wherever it keeps it
A read only ever looked at the manager's log services, and fell back to the
system's when the manager published none.  A platform that keeps an event log
in both places had the second one invisible: an AMI MegaRAC keeps power unit
and thermal events in a chassis log that nothing read, 103 records that no
command could reach.

Clearing deliberately does not follow.  It stays where it was, so a log that
only a read reaches is never destroyed by one, and clearing a platform that
keeps its only event log on the system still works.

The name test now ignores spacing, since a build that calls its post code log
"BIOS POST Code Log" was read as an event log and merged 2719 post codes in.
2026-08-19 15:10:55 +02:00
Jarrod Johnson 3fa1236d34 Merge pull request #278 from Obihoernchen/fix/configurable-endpoints
configurable sockapi path and ipmi port
2026-08-19 08:33:06 -04:00
Jarrod Johnson c87bdc5a40 Merge pull request #274 from Obihoernchen/openbmc-support
Various fixes and features for AMI MegaRAC and OpenBMC BMCs
2026-08-19 08:22:26 -04:00
Markus Hilger 9e811dd81c Leave it to OpenBMC to say which of its logs are not events
Reading an event log skipped every log service whose id or name said journal,
dump, post code, host logger or crash, on every implementation.  Those names
are bmcweb's: the AMI and Lenovo bmcs call theirs SEL, EventLog, AuditLog and
PlatformLog.  bmcweb does need the distinction, keeping its event log under the
system while a clear would destroy its dumps, so it gets a handler that names
the words and generic names none, reading whatever a platform publishes.
2026-08-18 22:58:48 +02:00
Markus Hilger 811d48ed42 Ask only MegaRAC for the parameters part it insists on
Generic added an UpdateParameters part to every multipart firmware push,
because the specification has one carried.  Only the AMI firmware was seen to
insist on it, so name it in that handler and let generic send what the caller
passed.
2026-08-18 22:58:48 +02:00
Jarrod Johnson 985aff2c1a Allow ipv4 address extraction on web open with fe80::
If using fe80::, ask for more viable global addresses automatically.
2026-08-18 16:44:47 -04:00
Markus Hilger eaa1a8bfc7 Let a console work through a forwarded ipmi port
A bmc behind a forward answers Activate Payload with the port it listens on
itself, and the advertised-port check refused that, so a console failed where
command traffic worked. The advertised port is never sent to, so the check now
applies only on the default port. A bmc on another port advertising a third one
is no longer refused outright, which nothing here could have served anyway.
2026-08-16 21:37:50 +02:00
Markus Hilger fd92209d4d Read a port off the manager address over ipmi too
The plugin connected to 623 whatever the address said, with a TODO in place of
the parsing. It now reads one as the redfish plugin does, minus the brackets,
which getaddrinfo rejects.

IpmiConsole keys its endpoint mapping on host and port so several bmcs behind
one address stay distinct, and unregisters only an entry it actually claimed.
2026-08-16 21:37:50 +02:00
Markus Hilger 5b132438f5 Let the api socket path be set rather than fixed
_unixdomainhandler hardcoded /var/run/confluent/api.sock in four places and
derived its directory from a fifth. It is now threaded through SockApi like
the other bind settings, defaulting to the same path. That lets a service run
on a temp socket as an ordinary user, which is what a test needs.
2026-08-16 21:37:50 +02:00