The fleet view¶
The admin role¶
Admin is granted explicitly and never by default — agents add <name> --admin, or
agents admin <name> afterwards. It is a role, and any number of agents may hold it; a fleet
may also hold none, since uid 0 on each host is an operator regardless.
agentctl agents admin <name> # grant; takes nothing from anyone
agentctl agents admin <name> --revoke # remove it from exactly the agent named
Every admin holds the identical scope: full authz at agentd, the overlay-write ACL on the fleet
repo, cross-agent reads, and the cockpit's fleet surface. There is no primary admin, so
notify admin reaches every one of them. The full model is in
The admin role.
The fleet mini-app¶
The fleet view is a cockpit mini-app (fleet), auto-activated for a viewer holding the admin
role. It paints from the SSE stream the cockpit already carries (/events), so it adds no
collection of its own. The gateway refreshes per-agent metadata only while somebody is watching
it.
Cross-host reads¶
Agents dial in to the web-view gateway, which op-relays top --json into each one over the
connection the agent already opened. That needs no SSH, no passwordless sudo on the targets and
no operator laptop switched on, and it crosses NAT that an inbound SSH does not. One gateway
therefore shows agents from every host in a single grid, grouped by host.
Where a host's health comes from¶
Two carriers report it, and the gateway folds both into one reading per host:
| Carrier | Runs as | Reports |
|---|---|---|
The host itself — agentctl-host-dial.service, one per host, no agents required |
root | load, disks, unit states, the /opt/agentctl git remote the map groups host families on, and the three gateway ports |
| Each agent on the host — its own dial-in | that agent's uid | everything an unprivileged uid can read |
A confirmed reading always beats a blank one, whichever carrier supplied it. The host's own carrier answers on connect and whenever the gateway asks while somebody is watching the fleet view, throttled to one collection every 2 s.
Two consequences an operator sees:
- A host with zero agents reports full health, not a bare name. A gateway host, or one adopted minutes ago, appears with real load, disks and unit states.
- Host families group correctly without an admin agent on the box. The git remote the grouping keys on, and the gateway ports, are root-only reads — the host's own carrier is what supplies them. A host whose connector is down reports neither, and is drawn as a family of one beside the siblings it shares an origin with.
If a host still renders as a bare name, check its connector:
systemctl status agentctl-host-dial # on that host
Linking two hosts¶
This is CLI-only, there is no join wizard. The primitives:
agentctl fleet reachable # on the new host: is the shared remote reachable? repo empty?
agentctl fleet seed # on the existing host, only if the shared repo is still empty
agentctl fleet adopt # on the new host: fetch + reset onto the shared ledger
agentctl fleet sync # either side, between join steps: pull the shared repo
agentctl apply # either side: converge to the pulled ledger
See Multi-host fleet § Joining a new host for the full ordered runbook, command by command.