Skip to content

cluster-register - #1129

Merged
cgalibern merged 4 commits into
opensvc:mainfrom
cgalibern:cluster-register
Sep 24, 2026
Merged

cgalibern merged 4 commits into
opensvc:mainfrom
cgalibern:cluster-register

Conversation

@cgalibern

Copy link
Copy Markdown
Contributor

No description provided.

The api had no way to register a node: an operator had to have a shell on
it, to run "om node register" there.

Add POST /node/name/{nodename}/action/register, taking the collector user,
password and app, and answering 204. A request for a peer is proxied to
it, as the other node actions are. The requester must be granted the root
role.

The credentials travel to the node named in the path, which registers
itself: the collector mints a registration id for a nodename, so a node
cannot register on behalf of another. Without a user, the node registers
with the id it already holds, as "om node register" does.

The handler registers in process rather than by running the register
command, unlike the node actions next to it. An argv is readable by any
user through the process table and stays in the exec session records,
which is what the credential file the caller uses set out to avoid. That
makes the call synchronous, and it covers the initial asset, package and
disk push the registration sends, so it is bounded by a 5 minutes
deadline.

The registration id is not answered back: it is the credential the node
authenticates with on the collector from then on.

Api version 4.3.0.
Registering a cluster meant a shell on every node, running "om node
register" there, and handing that command a password on its command line.

Add "o[mx] cluster register", posting to every cluster node the endpoint
that registers it. Each node registers itself, because that is the only
arrangement the collector allows. A node that fails does not stop the
ones after it: the nodes that worked are registered for good.

The collector credentials reach it, and "om node register", as
--credential, naming a file holding the <username>:<password> of a
collector user, read from the OSVC_COLLECTOR_CREDENTIAL environment
variable when the option is not set. A password passed as a flag value is
readable by any user through the process table and stays in the shell
history, which is why --token and --credential already name files. The
credential is parsed where the command is typed, so a malformed one is
reported once instead of once per node.

The --user and --password of "om node register" are kept, so the commands
written against the previous release keep working, but they are hidden
from the help, and a --credential wins over them.

Beware, the credential is forwarded to every cluster node, which is what
lets each one register itself.
…ctor

Registering a cluster through the api meant posting the register endpoint
of every node, one at a time, and knowing which nodes there are.

Add POST /cluster/register, which forks a 'om cluster register' in the
background. That command posts to every cluster node, so each one
registers itself, which is the only arrangement the collector allows.

The optional credential is the <username>:<password> of a collector user,
and it reaches the forked command through its environment, never on its
command line: /proc/<pid>/cmdline is world readable, /proc/<pid>/environ
is not. It is parsed before the fork, so a malformed one is answered as a
400 instead of being found in a log afterwards. Without it, each node
registers with the id it already holds.

The response is sent when the command has been forked, not when the nodes
are registered: a node registration covers the initial asset, package and
disk push it sends, and the command does that for every node in turn. A
node that fails does not stop the ones after it, so the outcome is per
node, in the forked command log.

The requester must be granted the root role.

Api version 4.4.0.
…action

The Aikido review of the pull request found the registration of a node
answered for work it did not wait for, and pointed at three places.

The endpoint registered synchronously, under a five minutes deadline the
work never honoured: Node.Register hands its context to the final checks
alone, and runs the login, the asset, package and disk pushes and the
sysreport without it. The daemon therefore kept pushing inventories, and
could still write node.uuid, after the request was gone.

Meanwhile the command calling it waited on the default 30 seconds client
timeout, which the initial package inventory alone outlives on any real
node. A node registering fine was reported as a transport failure, and
the loop moved on to the next node while the first was still working, in
a command documented as sequential.

Fork the register, as every node action next to it does, and answer the
session and exec ids naming what was forked. There is no deadline left to
misrepresent, and nothing for a client timeout to race. The outcome of a
registration is in the log of the node that ran it, and in the ExecSuccess
and ExecFailed events carrying the exec id.

The credentials stay out of the command line: apiExec takes the
environment entries to add to the fork, so the collector credential
reaches the command through OSVC_COLLECTOR_CREDENTIAL, as it already does
for the cluster register. /proc/<pid>/cmdline is world readable, and the
command string is published on the bus and kept in the exec store.

Refuse a half credential with a 400. A user without a password reached
the password prompt of the register command, on a daemon with no terminal
to prompt on. A password without a user names nobody to authenticate as,
and was dropped: the node registered with the id it already held, which
is not what the caller asked for.

The third finding was the ox node register the pull request offered a
--credential, while it had no command behind it: nodeaction reached its
nil RemoteFunc guard, as it did for om node register --node. Both post
the register endpoint now, so a selection of nodes registers.

Api version 4.5.0: the endpoint answers 200 and a NodeActionAccepted in
place of 204, and takes a session id.
@cgalibern
cgalibern merged commit c0dec33 into opensvc:main Sep 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant