PLAN: the updater shipped; what is left is where a public download lives
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
68bf3bb218
commit
1599ac65ef
@@ -372,6 +372,32 @@ something long in one, switch away and back, refresh — it's all still there.
|
|||||||
a thin line and a name strip on the first level — instead of nested boxes with headers,
|
a thin line and a name strip on the first level — instead of nested boxes with headers,
|
||||||
which on Linux's single-child folder chains was a staircase of headers around nothing.
|
which on Linux's single-child folder chains was a staircase of headers around nothing.
|
||||||
Not done: delete from here, a size-over-time history, per-user column choices.
|
Not done: delete from here, a size-over-time history, per-user column choices.
|
||||||
|
- **Updater** — **shipped 2026-09-23** (`internal/selfupdate`, `internal/api/update.go`,
|
||||||
|
the Updates card in `Settings.tsx`, `scripts/gitea-release.sh`). A Ham Lab asks one URL
|
||||||
|
what the newest build is and installs it on request. `update.url` in `config.json` is
|
||||||
|
either a Gitea/Forgejo repo API base (`…/api/v1/repos/<owner>/<repo>`, whose newest
|
||||||
|
release names the version and carries the binaries as assets) or any static directory
|
||||||
|
holding `VERSION`, `SHA256SUMS` and `hamlab-linux-<arch>` — which is exactly what
|
||||||
|
`make release` writes and what `install.sh` already downloads, so the demo site, a
|
||||||
|
folder on a NAS and a Gitea release are all the same thing to it. `"off"` never looks.
|
||||||
|
`update.token` is sent when the source is behind a login, so a **private** Gitea serves
|
||||||
|
its own fleet without the instance being opened to the world. The binary is verified
|
||||||
|
against `SHA256SUMS` before it goes anywhere near the running one, then takes the same
|
||||||
|
path `POST /api/self-update` always did (runs `version`, runs `check` against this
|
||||||
|
machine's config, atomic replace keeping `hamlab.prev`, re-exec in place) — that path is
|
||||||
|
now one shared method, `installBinary`. Version ordering is `install.sh`'s `vnum()` rule
|
||||||
|
ported to Go and tested against it, so the daemon and the installer never disagree about
|
||||||
|
which of two builds is newer; the commit count since the tag counts, the hash does not.
|
||||||
|
Checked ~90 s after boot and daily (`update.check: "never"` switches that off), never
|
||||||
|
installed unasked — an update restarts the daemon and drops open terminals, and the
|
||||||
|
dialog says so. Settings → **Updates**: installed, published, when it last looked, the
|
||||||
|
source, the release notes, Check for updates, Install; the rail badges Settings when a
|
||||||
|
newer build is out (`update_available` rides on `/api/me`). Publishing is
|
||||||
|
`make gitea-release` → `scripts/gitea-release.sh`, which creates the release and uploads
|
||||||
|
the five architectures, `SHA256SUMS`, `install.sh` and `VERSION`; it is deliberately
|
||||||
|
**not** part of `make deploy`, because deploy pushes this build to the machines this hub
|
||||||
|
owns while publishing offers it to every install anywhere, and one tag per deploy would
|
||||||
|
be noise. Re-publishing a version needs `--force`.
|
||||||
- **Auth hardening** — WebAuthn passkeys (phone Face ID), TOTP fallback, optional NPM
|
- **Auth hardening** — WebAuthn passkeys (phone Face ID), TOTP fallback, optional NPM
|
||||||
access list restricting to WireGuard/LAN.
|
access list restricting to WireGuard/LAN.
|
||||||
- **Files tab** — **shipped 2026-09-18** (`internal/files`, `Files.tsx`): browse from
|
- **Files tab** — **shipped 2026-09-18** (`internal/files`, `Files.tsx`): browse from
|
||||||
@@ -400,32 +426,27 @@ something long in one, switch away and back, refresh — it's all still there.
|
|||||||
|
|
||||||
## To do
|
## To do
|
||||||
|
|
||||||
- **A public download page, and an updater that uses it** — asked for 2026-09-22, not
|
- **Somewhere public to download from** — asked for 2026-09-22, half done. The **updater**
|
||||||
started. Today a release is *published* but not *offered*: `make publish` writes five
|
shipped 2026-09-23 (above) and reads releases from Gitea, but `git.bigham.dev` runs with
|
||||||
architectures, `SHA256SUMS`, `VERSION` and `install.sh` into
|
`REQUIRE_SIGNIN_VIEW=true`, so those releases are reachable only with a token. That is
|
||||||
`/home/core/apps/hamlab-demo/site/dl/` (public at `https://hamlab-demo.bigham.dev`), and
|
fine for this fleet — each machine carries a read-only `read:repository` token — and no
|
||||||
the only way in is `curl -fsSL https://hamlab-demo.bigham.dev/install.sh | sh`. Updating
|
use at all to a stranger running the `install.sh` one-liner, who still gets the rolling
|
||||||
an existing install is a *hub* pushing its own binary to machines it manages
|
copy on `hamlab-demo.bigham.dev`. What is left is deciding where a public download
|
||||||
(`POST /api/self-update`, `hamlab push-nodes`, the Update buttons on the Machines page) —
|
actually lives:
|
||||||
which does nothing for an install that no hub of mine owns. Two halves:
|
- **Lower the wall on Gitea.** `REQUIRE_SIGNIN_VIEW=false` and per-repo visibility does
|
||||||
- **The page.** A human-facing page at the download site: current version and when it was
|
the rest: every repo there is private and stays hidden, and only a repo marked public
|
||||||
built, a row per architecture with its size and checksum, the one-line install, and how
|
is visible. That is how Gitea is meant to be configured, and it is the one change that
|
||||||
to update. Today `/dl/` is a bare directory listing. It should be generated by
|
makes "releases on my Gitea" literally true. It is an instance-wide posture change on
|
||||||
`make publish` from the same VERSION and SHA256SUMS the release already writes, so it
|
a public hostname, so it is Mitchell's call — the same trade was declined once before
|
||||||
cannot drift from the binaries beside it, and it should say plainly that the binaries
|
(`docs/docker.md`, the demo site's `install.sh` is hosted outside Gitea for exactly
|
||||||
are unsigned and served over TLS from my own box.
|
this reason).
|
||||||
- **The updater.** A Ham Lab anywhere asks the download site what the current version is,
|
- **Or keep the wall and keep the demo site** as the public face: `make publish` already
|
||||||
says so in the UI when it is behind (the About card, and probably a rail badge like
|
writes the rolling `dl/` directory there, and a generated index page (version, built
|
||||||
Alerts has), and updates itself on request: fetch the binary for its own architecture,
|
when, a row per architecture with size and checksum, the one-line install, and that
|
||||||
check it against `SHA256SUMS`, then the same path `POST /api/self-update` already
|
the binaries are unsigned and served from his own box) would finish the "page" half
|
||||||
takes — verify it runs, install atomically, re-exec in place. Decisions to make when it
|
without touching Gitea at all.
|
||||||
is built: where the check lives (a `update_url` in `config.json`, defaulting to the
|
- Either way the release notes and version history live on Gitea, and the updater does
|
||||||
public site, so someone else's install can point elsewhere or switch it off); how often
|
not care which of the two it is pointed at.
|
||||||
it asks (daily is plenty, and it must be possible to say never); whether it ever updates
|
|
||||||
unattended (default no — an update restarts the daemon and drops open terminals); and
|
|
||||||
whether a hub offers to update its machines from the site when it is itself behind.
|
|
||||||
Downgrades are already refused by the installer's `vnum()` comparison; the updater
|
|
||||||
should use the same rule.
|
|
||||||
|
|
||||||
- **Deprecate copyparty** — asked for 2026-09-23, not started. `copyparty` on `grid`
|
- **Deprecate copyparty** — asked for 2026-09-23, not started. `copyparty` on `grid`
|
||||||
(`copyparty.service`, `:3923`, `/etc/copyparty.conf`, serving all of `/tank` as user
|
(`copyparty.service`, `:3923`, `/etc/copyparty.conf`, serving all of `/tank` as user
|
||||||
|
|||||||
Reference in New Issue
Block a user