Portable install: the binary installs itself; static builds on five architectures; root via sudo, doas or uid 0; every package manager; older systemd; no lsblk

- hamlab install / uninstall (internal/setup): systemd or OpenRC, elevates through
  sudo or doas, runs as the invoking user, sets or generates the password, names only
  journal groups that exist, waits for /healthz, reports an active firewalld/ufw.
  --purge and the data chown never touch a directory that isn't Ham Lab's alone.
- install.sh: curl-able bootstrap (arch detection, SHA256SUMS, offline beside the
  binaries, noexec /tmp fallback). make release builds dist/ for amd64, arm64, arm
  (ARMv6), 386, riscv64. Every build is CGO_ENABLED=0; the native one used to link glibc.
- internal/priv replaces every literal `sudo -n`: uid 0, sudo or doas.
- Updates acts on dnf, zypper, pacman and apk as well as apt; dnf shows installed versions.
- Services falls back to the plain systemctl table before systemd 246 and says so on
  hosts without systemd. Disks falls back to /sys/block without lsblk.
- Listener binds with IP_FREEBIND, so a LAN address that isn't up at boot is no failure.
- Self-update: the new build must pass `check` against the live config, is put in
  place by atomic rename, and the daemon re-execs itself (same under any supervisor).
- State and config writes are fsynced; a corrupt state.json is set aside, not fatal.
- Terminal shutdown no longer empties the saved list, so names come back after a
  restart by design rather than by winning a race.
- Config default is ~/.config/hamlab; an existing ~/apps/hamlab is still found.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-18 23:00:20 -07:00
co-authored by Claude Fable 5.1
parent 91b7f4f009
commit 488d929733
26 changed files with 1617 additions and 178 deletions
+14
View File
@@ -204,6 +204,20 @@ something long in one, switch away and back, refresh — it's all still there.
`bin/hamlab-linux-arm64`, `install.sh` installs it beside the binary as
`hamlab-arm64`, and the hub picks the sibling matching a node's `/api/me.arch` when
pushing — the Mac mini (Fedora Asahi, aarch64, node `mac`) updates like the rest.
- **Portability + install** — **shipped 2026-09-18** (`internal/setup`, `internal/priv`,
`install.sh`, `make release`): the binary installs itself (`hamlab install` /
`uninstall`; systemd or OpenRC; root, sudo or doas), all builds static on amd64, arm64,
arm, 386 and riscv64, `install.sh` as the curl-able bootstrap with checksums. Every
privileged call goes through `priv` instead of a literal `sudo -n`. Updates tab acts on
dnf, zypper, pacman and apk as well as apt. Services list falls back to the plain
table on systemd < 246; Disks falls back to `/sys/block` without `lsblk`. Listener
uses `IP_FREEBIND`. Self-update: pre-flight `check` against the live config, atomic
replace, exec in place. Config default moved to `~/.config/hamlab` (existing
`~/apps/hamlab` still found by the installer and the CLI). Tested in
containers: Debian 12, Ubuntu 22.04, Fedora 40, Rocky 8, openSUSE Leap 15.5, Alpine
3.18/3.20 (OpenRC + doas, non-root), plus the four lab hosts. Not done: an OpenRC
backend for the Services tab; runit/s6/sysvinit service files; public hosting for
`install.sh` (the Gitea repo is private, so the one-liner needs `HAMLAB_TOKEN`).
- **Auth hardening** — WebAuthn passkeys (phone Face ID), TOTP fallback, session
list + revoke, optional NPM access list restricting to WireGuard/LAN.
- **Files tab** — **shipped 2026-09-18** (`internal/files`, `Files.tsx`): browse from