Skip to main content

Module hostcmd

Module hostcmd 

Source
Expand description

host add: the SSH orchestration that wires the pure pieces in hostspec.rs/registry.rs onto a real box.

Everything here that actually talks to a host (ssh_run, ssh_pipe_file, ssh_append_unique, host_add) is exercised end to end by the controller against docker/test-host, not by a unit test — there is no live host in CI. What IS unit-tested is every pure seam: parsing user@host, building the ssh argument vector, the remote shell commands those transport fns run, and the client-side path resolution (keydir, registry path, ~/.ssh/config upsert).

Structs§

HostAddArgs
HostAdoptArgs
Inputs for host adopt.
SshSpec
The control-channel SSH target: the operator’s interactive key, never the forced-command key that host add goes on to install.

Enums§

HostStatus
One host’s status, as probe_status diagnoses it. Reachable carries exactly what the host’s own selfcheck reported; Broken is a real ssh connection that came back unhealthy (selfcheck errored); Unreachable is no connection at all — the graduated diagnosis status needs to tell “the box is off” from “the box is up but git-ark is broken on it”.
KeyPlan
What pick_or_plan_keygen decided for the client’s control key: reuse an existing one, or generate a fresh one. Both carry the PRIVATE key path — its public half is always <path>.pub, the standard ssh-keygen naming.

Functions§

client_keydir
client_ssh_config_path
format_status_row
Render one status row. PURE — probe_status does the SSH; this only formats what it found. mirror (from the registry entry, not carried on HostStatus) appends a ★ mirror marker.
host_add
Probe, wire, verify, and register a host. Fails before mutating anything on the host if the probe/capability check doesn’t pass; re-running for the same name is idempotent (re-streams the binary/config, never duplicates the authorized_keys/~/.ssh/config entries).
host_adopt
Adopt an already-deployed host into the client registry — the recovery path (a lost registry) and the way to bring in a host wired before the registry existed. Reconstructs the registry entry from the host’s deployed surface over the control channel, verifies with selfcheck, and registers it.
host_discover
Scan the local /24 for hosts answering on port, printing each reachable ip:port — labeled (known: <name>) when the IP already appears in a registered host’s ssh_target. Finding nothing is success (exit 0), not an error; a probe is a bare TCP connect, no auth, no data.
host_list
Print the registry, one line per host as name ssh_target triple, sorted by name. Registry::list() is in insertion order (only save sorts on disk), so sort a copy here — an empty/missing registry prints nothing.
host_list_json
host list --json: the client contract for resolving a host name to its push alias and backend. Emits a flat JSON array of [HostRow].
host_remove
Remove name from the registry and drop its ~/.ssh/config alias block. A name not in the registry is reported, not an error — there’s nothing to retry.
host_setup_key
Generate a client SSH key (if none exists) and copy it to target via ssh-copy-id, so a box without key auth set up can get to “sshable” without leaving git-ark. This is the operator’s own CONTROL key, never the forced-command key host add goes on to install — setup-key never touches an existing key, only creates one when none exists.
mirror_check
Preflight the GitHub token against a repo’s mirror config: read the committed .git-ark.yml github block, check the token’s auth/scopes and its access to the target repo, and print a report — catching a token lacking org access or the workflow scope before a real push does.
mirror_set
Reassign the GitHub mirror to name: load the registry, require the host exists, read the token from GIT_ARK_GITHUB_TOKEN (never argv), and enforce the singleton via designate_mirror.
mirror_show
Print the current mirror host’s name, or none.
parse_forced_command_config
Extract the --config <path> from a git-ark forced-command line in an authorized_keys body. The path ends at the first quote or whitespace.
parse_target
Split an ssh target user@host into (user, host). git-ark hosts always run under a dedicated user, so a bare hostname (no @) is rejected rather than guessed at.
pick_or_plan_keygen
Decide which client key host setup-key should use. PURE: existing is the set of candidate basenames the caller found actually present in ssh_dir — this only picks among them. Reuses the first preferred name present (ed25519 > ecdsa > rsa); plans to generate id_ed25519 when none exist. Never plans to overwrite an existing key.
probe_status
Probe host over the control channel: run its own selfcheck and parse the result. Never errors — a dead or misconfigured host is a HostStatus variant, not a Result::Err, so status() can report the whole fleet even when part of it is down.
registry_path
The host registry path: GIT_ARK_HOSTS overrides (tests, alternate profiles); else <keydir>/hosts.toml.
remove_ssh_config_block
Remove the Host git-ark-<name> block from existing, if present. Every other block is preserved untouched. Used by host remove to drop the client ~/.ssh/config alias once a host leaves the registry.
route
Fan a repo’s git push git-ark out across host_names: verify every name is registered, then (re)materialize the git-ark remote in repo_path with one push URL per host, so a single git push git-ark reaches all of them. Idempotent — re-running (even with a different host_names) removes and rebuilds the remote rather than accumulating stale push URLs alongside new ones.
ssh_append_unique
Append line to remote_file on the host, idempotently (see append_unique_script).
ssh_pipe_file
Stream bytes to remote_path on the host, then chmod mode. Used for the binary, config.toml, and secrets.toml — the proven pattern of piping over the same control-channel ssh rather than requiring scp.
ssh_run
Run cmd on spec over the control channel, returning stdout. Non-zero exit is an error carrying stderr.
status
Print a fleet health/liveness/drift dashboard: one row per registered host, probed over the control channel. Never fails the process on a dead/broken host — that’s the point of the dashboard — only on a genuine local error (e.g. an unreadable registry).
triple_from_uname
Map uname -s / uname -m output (two lines) to a git-ark release triple.
upgrade
Push binary to names (or every registered host, with all) over the control channel and re-verify each with selfcheck. The binary is read once and streamed unchanged to every target. A per-host failure is printed and does not abort the rest — the fleet-wide --all case must finish attempting every host before this returns a non-zero error, so a script driving it can detect a partial upgrade without losing the hosts that did succeed.
upsert_ssh_config_block
Insert or replace the Host git-ark-<name> block within existing (the current contents of ~/.ssh/config), keyed by its Host line. Every other block is preserved untouched; a prior block for this name is replaced in place (idempotent re-runs of host add), otherwise the new block is appended.