systemd
systemd (over SSH): an application controller type, version 1. A controller of this type is written under controllers.application with type: systemd.
Its connectivity test identifies the system it reaches by the host’s SSH key fingerprint, so that a second controller for the same system is warned of.
Connection
In the controller’s connection:
host(string, required): the host’s name or address, reached over SSH from the site’s orchestratorsport(int, default22): the SSH porthost_key_sha256(string): the host’s SSH key fingerprint, SHA256:… as ssh-keygen -l prints it, pinned at registration as the controller’s identity: the connectivity test shows the key the host presents until it is setsystemctl(string, default/usr/bin/systemctl): the path of systemctl, as the sudo rules name itstate_dir(string, default.local/state/qfence): where on the host the newest generation of each plan and unit is recorded, relative to the user’s home unless absoluteconnect_timeout(duration, default10s): how long connecting and the SSH handshake may take; each call is bounded by its own deadlinemax_concurrent_calls(int, default4): commands in flight on the host at once; more wait within their deadline
Auth methods
The controller’s auth.method is one of these. A field marked secret comes only from the secret auth.credentials_ref names; the others are set in auth.config, or in that secret.
ssh_key
A dedicated user and its private key; its sudo rules name each unit qfence manages and nothing else.
user(string, required): the dedicated user qfence logs in as, e.g. qfenceprivate_key(pem, required, secret): the user’s private key, in OpenSSH or PEM formpassphrase(string, secret): the private key’s passphrase, if it has one
Capabilities
The controller enables each it uses in its capabilities list.
unit.active
HEALTHY, and ready, while the unit is active; UNHEALTHY when it is inactive, failed or missing; UNKNOWN when the host does not answer. Read without sudo.
Category: observation; bound as health or readiness; resource unit.
unit.stop
Mask the unit, then stop it, so nothing starts it again until it is unfenced, a reboot included; unfence unmasks and starts it. An application-level fence: it never proves a site.
Category: actuator; bound as fence; fencing level application; resource unit.
Validation checks: sudo.units, unit.maskable.
unit.restart
Restart the unit where it runs: local recovery at the owner site (ADR 0005 §6). A masked (fenced) unit is not restarted.
Category: actuator; bound as recovery; resource unit.
Its recovery policy, in the recovery binding’s params (ADR 0005 §6):
max_attempts(int, default3): restarts at most, within window, before recovery escalateswindow(duration, default10m): the period max_attempts is counted overbackoff(duration, default30s): the wait before the second restart, doubling for each one aftergrace(duration, default60s): how long after a restart health is not countedflag_after_episodes(int, default3): episodes of recovery within flag_period that raise an attention itemflag_period(duration, default24h): the period flag_after_episodes is counted over
Validation checks: sudo.units.
command.check
Run a command on the host, as the user, as an argument vector with no shell: exit 0 passes, any other exit fails, and a command that times out or cannot run is UNKNOWN. Health and readiness only.
Category: observation; bound as health or readiness; resource controller.
Per binding, in its params:
command(list of strings, required): the program and its arguments, each passed as it is: no shell expands, splits or redirects themtimeout(duration, default10s): how long the command may run before it is killed, with what it started, and the check is UNKNOWN
units.list
The host’s service units, by name, with their state.
Category: discovery; resource unit.
Addresses
Every address the type contacts. A secret’s scope (-scope-host) is checked against each that receives credentials.
connection.host(portconnection.port, receives credentials): the host, over SSH