Bring up the fleet
By the end of this you will have six Debian trixie VMs on your workstation, each
running golemd against real apt, real systemd, and a real filesystem.
And every byte of that will have crossed an ssh forward carrying a bearer token, because there is no other way in. This is where you prove that rather than take it on faith.
Commands are nushell, one per line, run from the repo root inside the devenv shell. All of them are safe to re-run.
Before you start
cargo build --workspacecargo build --release -p golemctlThe workspace build gives fleet its emetc compiler and its
target/debug/golemctl. The release build is what puts golemctl on the devenv
shell’s PATH (enterShell prepends target/release), which step 7 depends on.
Two waits are worth knowing about before you think something has hung:
- The first
fleet upon a machine downloads Debian’s ~340 MB genericcloud image, then waits out cloud-init on each guest. Minutes. - The first
fleet deployrunsnix build .#golemd-static. Minutes again, unless cachix already has it.
Prove the posture
-
Boot six guests.
Terminal window fleet upPer host you get two lines:
Booting scaly (ssh 2259, golemd loopback-only)…scaly up pid=482913Read
golemd loopback-onlyliterally.2259is scaly’s forwarded ssh port, and for a guest booted this way it is the only port qemu forwards. There is no golemd port in the line because there is no golemd port. -
Install the daemon.
Terminal window fleet deployBuilding static golemd (musl)…binary: /home/you/personal-repos/golem/.fleet/result-golemd-static/bin/golemdDeploying golemd to scaly…scaly: golemd up {'host': 'scaly', 'latest_revision': 1}That
latest_revision: 1is theinitrevision golemd writes on first boot — an empty scroll, nothing applied yet. -
Look at the fleet.
Terminal window fleet statusA table, one row per VM:
up,golemd reachable,last revisionof#1, and dashes undercontent-idandglyphsbecause nothing has been applied. Every one of thosereachablecells was answered through an ssh forward the harness opened and tore down for that single request. -
Try the port that used to exist.
Terminal window curl -m 5 http://127.0.0.1:8859/statuscurl: (7) Failed to connect to 127.0.0.1:8859 after 0 ms: Could not connect to serverExit 7, refused before a packet leaves the machine. Having the fleet up changes nothing.
8859is the port scaly’s name-derived slot earns (8800 + 59) and it is still recorded in.fleet/state.json, but the only host-to-guest forward qemu creates is ssh — plus whatever you ask for with--publish, which has nothing to do with golemd. The forward that once pointed at 8859 was deleted when the loopback bind made it unreachable by construction, so there is no longer a port to knock on — not a dead one, none. -
Open a forward yourself, and get refused twice.
Terminal window let ssh_opts = ["-i" ".fleet/id_ed25519""-p" "2259""-o" "StrictHostKeyChecking=no""-o" "UserKnownHostsFile=/dev/null""-o" "ExitOnForwardFailure=yes"]ssh -f -N -L 17501:127.0.0.1:7474 ...$ssh_opts golem@127.0.0.1curl -s -w ' [%{http_code}]\n' http://127.0.0.1:17501/statuscurl -s -w ' [%{http_code}]\n' -H 'Authorization: Bearer wrong' http://127.0.0.1:17501/statuscurl -s -w ' [%{http_code}]\n' -H $"Authorization: Bearer (open .fleet/golem-token | str trim)" http://127.0.0.1:17501/statuspkill -f "17501:127.0.0.1:7474"The three curls, in order:
{"kind":"unauthorized","message":"missing or invalid bearer token — golemd requires Authorization: Bearer <token> (see --auth-token-file)"} [401]{"kind":"unauthorized","message":"missing or invalid bearer token — golemd requires Authorization: Bearer <token> (see --auth-token-file)"} [401]{"host":"scaly","latest_revision":1} [200]Reaching the socket buys nothing. The tunnel is the confidentiality and the host authentication; the token is the authorization; both are required and neither substitutes for the other. See Trust model.
-
Render the inventory.
Terminal window fleet inventoryIt prints one path:
.fleet/inventory.tomlunder your checkout. Open it if you like. Each guest is an[hosts.<name>]table carryingssh,ssh_port, the fleet key and host-checking options asssh_args, andtoken_file. Nourl, because there is nothing to dial. -
Drive it with no flags and no environment.
Terminal window golemctl fleet status· kaiju rev 1 nothing applied· manta rev 1 nothing applied· orbit rev 1 nothing applied· scaly rev 1 nothing applied· talos rev 1 nothing applied· zulip rev 1 nothing appliedSix lines, alphabetical, and not one flag or environment variable. golemctl looked at
--inventory, then$GOLEMCTL_INVENTORY, then./fleet.toml, then./.fleet/inventory.toml— and the harness writes its file at the end of that chain deliberately, so being in the repo root is the whole configuration. Each of those six lines is a separate ssh forward, opened and closed, presenting the token that host’stoken_filenamed.
That is the posture proved end to end. Everything from here on rides it.
To reach one guest without the inventory, at a bare ssh:// target, see
the single-host spelling.
Reading the fleet while it works
fleet statusfleet logs scaly -ffleet ssh scalyfleet logs and fleet ssh are plain ssh into the guest and are untouched by
the auth layer — golemd’s token gates golemd’s HTTP surface, not your shell.
Tear down
fleet down scaly # stop the VM, keep its disk — a later `up` resumes itfleet reset # kill every VM, wipe all per-VM datafleet reset --purge # also drop the cached image and keypair.fleet/golem-token survives all three. What each verb keeps and drops is laid
out in The fleet harness.
When it breaks
✗ HOST unreachable: ssh to golem@127.0.0.1 exited 255 before the forward opened — Connection refused
The guest is not running, or .fleet/inventory.toml names a port that no longer
belongs to it. fleet status says which; re-run fleet inventory after every
up, down, or reset, because it is a snapshot of the state file rather than
a live view.
✗ HOST unreachable: … on one host while the others answer
That guest’s golemd is down or was never deployed. fleet logs HOST still
works — it is plain ssh — so read the journal there. fleet deploy --hosts HOST
reinstalls and restarts it.
unauthorized — set GOLEM_AUTH_TOKEN or GOLEM_AUTH_TOKEN_FILE (or an inventory host's token_file) to golemd's configured secret
The guests hold a different secret than .fleet/golem-token. Almost always a
half-finished rotation: run fleet deploy against every host, not just the one
that failed.
A verb hangs about ten seconds per host, then reports an ssh error The forward never came up. The message carries ssh’s own stderr. Stopped VM or stale inventory, same fixes as above.
no inventory at … — golemctl looks at --inventory, then $GOLEMCTL_INVENTORY, then ./fleet.toml, then ./.fleet/inventory.toml
You are outside the repo root, or you never ran fleet inventory.
error: the fleet token file … is empty
Delete it and redeploy everywhere. A truncated secret is refused rather than
silently degraded into an unauthenticated request.
Where to next
- A failing unit — break one leaf of a nine-unit tree on purpose and watch its siblings settle anyway.
- A registry on the fleet — a real container registry on a VM, reachable from the others.
- The fleet harness — QEMU, cloud-init,
name-derived ports, and what is inside
.fleet/.