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.
./install.sh --api-url https://127.0.0.1 --api-key "$(cat key)"Subcommands#
| Command | What it does |
|---|---|
install | Install, or A/B upgrade if one is already there. The default, and what a leading flag implies. |
verify | Health-check the running agent. |
rollback | Restore 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.
| Flag | Variable | Default | Meaning |
|---|---|---|---|
--api-url URL | API_URL | (required) | The router's API. |
--api-key KEY | API_KEY | (required) | The router's API key. |
--admin-token TKN | ADMIN_TOKEN | empty | Optional break-glass credential. |
--bind-addr ADDR | BIND_ADDR | 127.0.0.1:8090 | Listen address. |
| — | LOCAL_BIN | ../agent/wheelhouse-agent | A 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#
| Path | Mode |
|---|---|
/opt/wheelhouse/wheelhouse-agent | 0755 |
/opt/wheelhouse/wheelhouse-agent.old | the previous binary |
/opt/wheelhouse/wheelhouse-agent.new | transient staging path |
/opt/wheelhouse/ui/ | 0755 |
/etc/wheelhouse/ | 0700 |
/etc/wheelhouse/api-key | 0600 |
/etc/wheelhouse/admin-token | 0600, only when given |
/config/wheelhouse | 0700 — 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#
- Build, or copy
LOCAL_BIN, towheelhouse-agent.new— so a failed build never clobbers a working binary. - Stop the service.
- Copy the current binary to
wheelhouse-agent.old. - Move
.newinto place. - Start the service, wait two seconds, health-check.
- 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#
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:
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#
- Every flag — what the script passes through.
- Files and directories — the full layout.
- Ports and listeners — 8090 against 8443.
- The
.deb— the path that actually ships. sign.sh— verifying a binary you moved by hand.- Developer install
Checked against#
install/install.sh,
install/wheelhouse-agent.service,
agent/main.go (handleHealth, bootstrapAdmin),
docs/deploy.md "Developer install (lab only)".