From 363ff02bda5912036ed72b17acb608e71e19f913 Mon Sep 17 00:00:00 2001 From: Mitchell-Johnson Date: Wed, 23 Sep 2026 20:17:22 -0700 Subject: [PATCH] Drop the external demo: the Widgets tab is the demo The hamlab-demo site, its Widgets-tab button, the demo_url config key and the make publish target that fed it are all gone, along with the public read-only token it needed. The example stays in examples/external-demo as something to read. The installer one-liner already comes from Gitea releases. Co-Authored-By: Claude Opus 5 --- Makefile | 17 ++--------------- PLAN.md | 10 +++++++--- examples/external-demo/README.md | 12 ++++++------ install.sh | 2 +- internal/api/server.go | 5 ++--- internal/config/config.go | 3 --- web/src/Gallery.tsx | 3 +-- web/src/Shell.tsx | 2 +- web/src/api.ts | 2 +- 9 files changed, 21 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 4959e43..2e36cc7 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ VERSION ?= $(shell git describe --tags --always 2>/dev/null || echo dev) GO ?= go PREFIX ?= /usr/local/bin -PUBLISH ?= /home/core/apps/hamlab-demo/site # every architecture a release carries; arm is ARMv6 hard-float, so it covers every Raspberry Pi ARCHES ?= amd64 arm64 arm 386 riscv64 @@ -10,7 +9,7 @@ LDFLAGS = -s -w -X main.version=$(VERSION) # static, no cgo: the same file runs on glibc, musl (Alpine) and anything else with a Linux kernel GOBUILD = CGO_ENABLED=0 GOOS=linux GOARM=6 $(GO) build -trimpath -ldflags "$(LDFLAGS)" -.PHONY: all web build go dev cross release publish gitea-release deploy push-nodes push-nodes-force test clean +.PHONY: all web build go dev cross release gitea-release deploy push-nodes push-nodes-force test clean all: build @@ -61,9 +60,7 @@ gitea-release: release deploy: build cross ./bin/hamlab install --prefix $(PREFIX) @sleep 1; $(PREFIX)/hamlab push-nodes || true - @# The public installer must never lag the fleet: it would offer everyone an older build, and - @# "upgrade" a current machine backwards. Publish only where this hub serves the download site. - @if [ -d $(PUBLISH) ]; then $(MAKE) --no-print-directory publish; fi + @echo "deployed $(VERSION); 'make gitea-release' publishes it for everyone else" # push the installed binary to every managed machine (what deploy does last) push-nodes: @@ -75,13 +72,3 @@ push-nodes-force: clean: rm -rf bin dist internal/web/dist web/dist - -# Put the release where `curl -fsSL https://hamlab-demo.bigham.dev/install.sh | sh` finds it: -# the static site beside the demo page (nginx, public through NPM). Binaries first, VERSION -# last, so nobody is ever pointed at files that aren't there yet. -publish: release - mkdir -p $(PUBLISH)/dl - cp dist/hamlab-linux-* dist/SHA256SUMS $(PUBLISH)/dl/ - cp dist/install.sh $(PUBLISH)/dl/install.sh && cp dist/install.sh $(PUBLISH)/install.sh - cp dist/VERSION $(PUBLISH)/dl/VERSION - @echo "published $(VERSION): curl -fsSL https://hamlab-demo.bigham.dev/install.sh | sh" diff --git a/PLAN.md b/PLAN.md index 35cc28c..62b1fd8 100644 --- a/PLAN.md +++ b/PLAN.md @@ -186,7 +186,12 @@ something long in one, switch away and back, refresh — it's all still there. a URL), status sensors (services, updates, ZFS, SMART), a widget library, custom widgets on the Dashboard tab (briefly renamed "Monitors" 2026-09-19, back to "Dashboard" 2026-09-20 at Mitchell's request; the view id and URL were always `dashboard`), and a - frameable `/embed/widget` for Glance and friends. The stock Dashboard modules and the Disks + frameable `/embed/widget` for Glance and friends. (An external demo page was deployed at + `hamlab-demo.bigham.dev` and linked from the Widgets tab 2026-09-19; **both removed + 2026-09-23** at Mitchell's request — the Widgets tab shows the same thing against the + machine you are signed in to, so the second copy earned nothing and cost a public + read-only token, which was revoked with it. `examples/external-demo/` stays as an example + to read.) The stock Dashboard modules and the Disks tab read the sensor API too (`sampleAdapter.ts`); `/api/metrics` is retired. Also per-service and per-container sensors (memory and CPU from cgroups), tokens limited to ID patterns, and `/api/fleet/sensors/query` for the whole fleet in one request. @@ -406,8 +411,7 @@ something long in one, switch away and back, refresh — it's all still there. still default to private. No token is needed by anything any more (the read-only one was revoked; only `hamlab-publish`, which creates releases, remains). Gitea resolves `releases/download/latest/`, so `install.sh` and `HAMLAB_URL` now point straight - at the newest release and never need changing; the rolling copy on - `hamlab-demo.bigham.dev` stays as a mirror. What is public is the source, the history, + at the newest release and never need changing. What is public is the source, the history, `BUGS.md` and this file — which describes the lab and names the console's hostname. - **Auth hardening** — WebAuthn passkeys (phone Face ID), TOTP fallback, optional NPM access list restricting to WireGuard/LAN. diff --git a/examples/external-demo/README.md b/examples/external-demo/README.md index 34b5c5d..fcfdc8a 100644 --- a/examples/external-demo/README.md +++ b/examples/external-demo/README.md @@ -12,10 +12,10 @@ window.HAMLAB = { base: 'http://10.0.0.234:8100', token: '(null) const [err, setErr] = useState('') const rate = useRefreshMs() @@ -61,7 +61,6 @@ export default function Gallery({ demoUrl }: { demoUrl?: string }) { {needle ? `${shown.length} of ${sensors.length}` : sensors.length} sensors on this machine · live · tap a tile to copy its ID setFind(e.target.value)} placeholder="find — gitea, temp, enp3s0…" spellCheck={false} autoCapitalize="off" /> - {demoUrl && External demo ↗} {!needle &&

Widget types

} diff --git a/web/src/Shell.tsx b/web/src/Shell.tsx index 17ae190..e155e0d 100644 --- a/web/src/Shell.tsx +++ b/web/src/Shell.tsx @@ -269,7 +269,7 @@ export default function Shell({ me: hubMe, onLoggedOut }: { me: Me; onLoggedOut: {view === 'space' && } {view === 'machines' && { switchMachine(n); setView('dashboard') }} />} {view === 'dashboard' && } - {view === 'widgets' && } + {view === 'widgets' && } {view === 'docker' && } {view === 'alerts' && m.name)} titleOf={(n) => titleOf(n === hubMe.host ? null : n, machines, hubMe.host)} />} {view === 'top' && } diff --git a/web/src/api.ts b/web/src/api.ts index ba7ac12..31b35c7 100644 --- a/web/src/api.ts +++ b/web/src/api.ts @@ -55,7 +55,7 @@ async function req(method: string, path: string, body?: unknown, local = fals } export interface UpdateStatus { current: string; latest: string; arch: string; behind: boolean; checking: boolean; installing: boolean; enabled: boolean; auto: boolean; url: string; notes?: string; published?: string; checked?: string; error?: string } -export interface Me { demo_url?: string; addr?: string; host: string; user: string; account?: string; update_available?: string; version: string; load: string; uptime: number; reboot_needed?: boolean; fingerprint?: string; arch?: string } +export interface Me { addr?: string; host: string; user: string; account?: string; update_available?: string; version: string; load: string; uptime: number; reboot_needed?: boolean; fingerprint?: string; arch?: string } export interface PushResult { name: string; ok: boolean; version?: string; error?: string } // What a machine is called on screen: the hostname it reports, which follows a rename within // a poll. The name it was added under stays its identity — the URL, its accent colour, and