Wheelhouse docs

install.sh#

Puts a wheelhouse-agent on a host that can reach a router's API. It installs into /opt/wheelhouse, keeps secrets in /etc/wheelhouse, and binds 127.0.0.1:8090.

bash
./install.sh --api-url https://127.0.0.1 --api-key "$(cat key)"

Subcommands#

CommandWhat it does
installInstall, or A/B upgrade if one is already there. The default, and what a leading flag implies.
verifyHealth-check the running agent.
rollbackRestore the previous binary and health-check it.

A leading --flag is treated as install --flag, because the documented first run has no verb.

Flags and environment#

Each flag has an environment variable of the same meaning; the flag wins.

FlagVariableDefaultMeaning
--api-url URLAPI_URL(required)The router's API.
--api-key KEYAPI_KEY(required)The router's API key.
--admin-token TKNADMIN_TOKENemptyOptional break-glass credential.
--bind-addr ADDRBIND_ADDR127.0.0.1:8090Listen address.
LOCAL_BIN../agent/wheelhouse-agentA prebuilt binary to install instead of building one.

An unknown flag is a one-line refusal. Missing --api-url or --api-key is refused with the hint that names where to find the key on the router.

ADMIN_TOKEN is empty by default on purpose: accounts are the real credential, and the break-glass token is opt-in rather than a shipped default password. When it is not given, /etc/wheelhouse/admin-token is removed rather than left stale.

What it writes#

PathMode
/opt/wheelhouse/wheelhouse-agent0755
/opt/wheelhouse/wheelhouse-agent.oldthe previous binary
/opt/wheelhouse/wheelhouse-agent.newtransient staging path
/opt/wheelhouse/ui/0755
/etc/wheelhouse/0700
/etc/wheelhouse/api-key0600
/etc/wheelhouse/admin-token0600, only when given
/config/wheelhouse0700 — the data directory, the same as the appliance

Secrets are written by creating the file empty at 0600 and then filling it, never by a redirect into a file the umask decides the mode of.

The data directory stays at /config/wheelhouse even here: accounts, tokens and the audit log belong on the partition that survives an image upgrade, and putting them somewhere else in a laboratory would mean testing a different layout from the one that ships.

The A/B swap#

  1. Build, or copy LOCAL_BIN, to wheelhouse-agent.new — so a failed build never clobbers a working binary.
  2. Stop the service.
  3. Copy the current binary to wheelhouse-agent.old.
  4. Move .new into place.
  5. Start the service, wait two seconds, health-check.
  6. On failure, roll back automatically and health-check again. If that fails too, it stops and says manual intervention is required.

rollback does steps 2 through 6 by hand, and refuses when there is no .old to go back to.

Starting and stopping#

If systemd knows the unit, systemctl is used. Otherwise the script backgrounds the agent itself with secrets passed by file — never on the command line — and records the pid in /opt/wheelhouse/agent.pid, with output in /opt/wheelhouse/agent.log.

Stopping prefers systemctl, then that pid file, and only as a last resort matches a command line anchored to the binary's own path. An earlier version ran pkill -f wheelhouse-agent, which matched a journalctl, an editor open on the unit file, and the script itself when run from a directory of that name.

The health check#

bash
curl -skf -m 5 "https://127.0.0.1:<port>/health" || curl -sf -m 5 "http://127.0.0.1:<port>/health"

HTTPS first, plain HTTP as the fallback. The unit runs the agent with a self-signed certificate, so probing only HTTP made a healthy agent look broken and rolled back a good binary.

/health is unauthenticated precisely so this works with no credential — and it answers {"status":"ok"} and nothing else.

The first password#

On the first start with an empty data directory the agent creates the admin account and logs a generated password once:

bash
journalctl -u wheelhouse-agent | grep "shown once"

Sign in, change it. Any non-empty password is accepted; the length is yours to choose.

Building from source#

With no LOCAL_BIN, the script builds from agent/ with the Go toolchain. Without either Go or a prebuilt binary it refuses rather than installing nothing.

See also#

Checked against#

install/install.sh, install/wheelhouse-agent.service, agent/main.go (handleHealth, bootstrapAdmin), docs/deploy.md "Developer install (lab only)".

Updated 2026-09-02 tools install lab development