nodesensors and nodeconfig printed an error and exited 0, so
`nodesensors n1 && next-step` ran next-step after the read it guarded had
already failed.
nodesensors had three of these: the per-node branch never set the exit code,
the top-level branch beside it read `exitcode |= exitcode`, and a normal
return from main() fell off the end of the file. nodeconfig accumulates with
|= all through its read path except the last line, which assigned, so a
failed bmc configuration read was discarded by the system read after it.
The fixed branches now match how nodehealth and client.py spell the same
thing.
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.
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.
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.
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.
Try to propogate form factor of member disk to array.
Also, even if cannot detect m.2, assume a two-member vroc array of nvme is m.2. Not guaranteed, but most likely. This is to deal with lack of DMI information indicating the physical form factor.
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.
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.
By copying, we leave the /etc/hosts with original ownership/permissions/etc.
Otherwise we create a new /etc/hosts, which is subject to new permissions and such.
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.
SATA drives do not directly have a busaddr.
However, at some point the PCI bus comes up in the udev hierarchy as a KERNELS value.
If that matches a detected M.2 slot, then accept the storage as M.2.