Learn that a release exists#
You will end up with a job somewhere else that tells you when a newer Wheelhouse version is published.
Before you start#
- A machine that is not the router and can reach the download host.
- Somewhere to send a message: an existing monitoring system, a mailbox, a chat webhook.
Step 1 — Know what you are running#
In the web interface: the Updates panel says This router runs 0.9.1, or Up to date. This router runs 0.9.1.; the Version panel beside it names the product and its version.
From another machine, with no credential: GET /health answers anyone who can reach the port
with {"status":"ok","version":"…"}, the agent's version:
curl -sk https://<router>:8443/health |
python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])'That is the version the router compares with the channel. GET /api/version, which needs a
token, answers something else: the base system's own version.
At the console: the banner above every login prompt gives the Wheelhouse version and the host
name on its header line. wheelhouse-agent --version answers before any configuration is read or
any secret file opened, so a router whose agent will not start still says what it runs.
Step 2 — Poll the channel index#
The download host carries a machine-readable channel index. stable.json names the newest
release tag; beta.json names the newest pre-release tag, a release candidate such as
v1.2.3-rc1. The router's Channel setting chooses which of the two it reads. Poll the
channel you actually run. /latest/ and stable.json follow the newest stable tag, and
publishing a release candidate moves neither, so a beta tester watching either of them never
sees the candidate.
curl -s https://releases.rhymelikedi.me/stable.json |
python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["version"], d["notes"])'{
"channel": "stable",
"version": "0.9.1",
"tag": "v0.9.1",
"released": "2026-09-18T12:00:00Z",
"base": "https://releases.rhymelikedi.me/v0.9.1/",
"notes": "https://releases.rhymelikedi.me/v0.9.1/CHANGELOG.md",
"checksums": "SHA256SUMS",
"signature": "SHA256SUMS.asc",
"signed": false,
"artifacts": [
{"name": "wheelhouse-0.9.1-amd64.iso", "kind": "iso", "arch": "amd64",
"size": 512483328, "sha256": "…"}
]
}The fields are stable. version is the comparison key; base plus an artefact name forms the
download address; sha256 is what to check; signed says whether signature is real. Fields
may be added, so a consumer must ignore what it does not recognise. The channel index needs no
licence key; the release directories it points into do.
Step 3 — Compare it with what you run#
A small script on the monitoring host. It reads the running version from the router's /health,
which needs no credential, and complains when the channel moves ahead of it.
#!/bin/sh
set -eu
channel=https://releases.rhymelikedi.me/stable.json
have=$(curl -fsSk https://edge:8443/health | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')
want=$(curl -fsS "$channel" | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')
[ "$have" = "$want" ] && exit 0
notes=$(curl -fsS "$channel" | python3 -c 'import json,sys; print(json.load(sys.stdin)["notes"])')
echo "edge runs $have; $want is published. Notes: $notes"
exit 1Run it from cron and let the non-zero exit be the alert, or pipe the message into whatever you already use. The check is a string comparison, not a version comparison — which is enough for "these differ, go and look" and not enough to decide which is newer.
Step 4 — Read the release notes before you upgrade#
CHANGELOG.md is published beside the files on the download host, and the router's Updates panel
shows the same notes under What’s new once it has checked them against the published
checksums. Security fixes are called out in a Security section there. There is still no
advisory feed and no published patch cadence — the changelog is where a security fix is
announced, and nothing pushes it to you.
What the router does with the same index#
The agent reads the index of the channel it is set to, on the schedule the licence refresher
uses, and checks it against the SHA256SUMS published beside it, and the release notes against
their entry in that file, before showing a word of them. Both come from the same host, so that
proves agreement, not authenticity, and the panel says so in words rather than showing a tick.
Reading the index sends nothing about the router: no licence key, no fingerprint, no host name,
and not even a version in the User-Agent. When the index names a release newer than the one
running, the router also fetches that release's checksum file and release notes from its release
directory, and those two requests carry the licence key, because the release host serves a
release directory only to a licensed router.
To stop all of it, turn off Check daily; then no request is ever made. For automation, the
same setting is PUT /api/admin/updates, and on disk it is "enabled": false in
<data-dir>/updates.json.
Check it worked#
Run the script by hand against a version you know is old and confirm it complains, then against the current one and confirm it is silent. A monitoring check that has never fired is not the same as a monitoring check that works.
Undoing it#
Remove the cron entry.
See also#
- Upgrade the whole system
- Upgrade the agent only
- Download and verify
- Scrape the agent — the metrics endpoint carries build information for a dashboard