From 4dc25fdd13dc81a256706c80a9e9199ea064d9d9 Mon Sep 17 00:00:00 2001 From: Mitchell-Johnson Date: Thu, 24 Sep 2026 13:03:38 -0700 Subject: [PATCH] PLAN: Usage, Jobs and the ZFS tab are done Co-Authored-By: Claude Opus 5 --- PLAN.md | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/PLAN.md b/PLAN.md index 39cccca..e1bd64e 100644 --- a/PLAN.md +++ b/PLAN.md @@ -276,6 +276,28 @@ something long in one, switch away and back, refresh — it's all still there. a dashboard could silently reset the sampling rate for the whole machine, overriding the fleet refresh rate set in Settings. The sampler now has one source: `refreshMs` in the UI prefs, which the hub fans out, remembered per machine as `sampler_ms`. +- **ZFS tab, with scheduled snapshots** — **shipped 2026-09-24** (`internal/storage/snapshots.go`, + `internal/api/zfs.go`, `ZFS.tsx`). Pools, datasets and snapshots moved out of Disks — + Disks is the hardware, ZFS is the filesystem on top of it — and the tab gained what it was + split out for: **snapshot schedules**. Hourly, daily, weekly or monthly, per dataset, + optionally recursive, with a **retention period** and a floor that keeps the newest few + whatever their age. A missed window (the machine was off) runs once on return rather than + being skipped. + **The naming is zfSnap's, deliberately.** `grid` has run zfSnap v1.11.1 from root cron at + 02:30 with a 6-week TTL since before this repo existed, and it works. So rather than + invent a second convention for two tools to disagree over, this writes and reads exactly + what zfSnap does — `tank@2026-09-24_02.30.01--6w`, **retention encoded in the name**. Three + consequences: Ham Lab shows and expires the snapshots zfSnap already took; the two can run + side by side without fighting, since both only remove what has passed the expiry written + into its own name; and changing a schedule never re-dates old snapshots, because each + carries the rule it was taken under. The page **detects the existing cron job** + (zfSnap, zfs-auto-snapshot, sanoid, or a bare `zfs snapshot`) and says so, warning if a Ham + Lab schedule is running as well. + **Nothing is destroyed unseen.** Every schedule answers *what would it delete?* with the + list, sizes and dates, before Run now touches anything; only names that parse as a stamp + and a TTL are candidates, so a snapshot taken by hand is invisible to it; and a snapshot + deleted by hand needs its full name typed back. The scheduler is a 30 s tick in the daemon, + and `Run now` calls the same code, so the button and the timer cannot drift apart. - **Skins** — 13 since 2026-09-19 (`themes.ts`: a palette is one `mk(…)` line): Dark, Light, Cyberpunk, Retro, **HUD** (hairlines of cyan on near-black, corner ticks, thin type), Nord, Gruvbox, Catppuccin + Latte, Dracula, Tokyo Night, Solarized Dark + Light; @@ -511,32 +533,6 @@ something long in one, switch away and back, refresh — it's all still there. - *Not app work, but the trigger:* nothing here blocks starting the migration except the inventory. Do that first. -- **Rename the Space tab** — asked for 2026-09-23, not started. "Space" is vague; the tab - is WizTree for a disk or pool. Candidates: **Usage**, **Disk Usage**, **Storage**. Note - `Disks` already exists and `Storage` would muddle with it, so Usage is probably the one. - The rename touches the rail label, the `View` id, the hash route (`#//space`, - which people may have bookmarked — decide whether to keep `space` as the id and change - only the label), the footer's page name and `Space.tsx`'s own strings. - -- **ZFS gets its own tab, under Disks** — asked for 2026-09-23, not started. Today ZFS is a - section inside `Disks.tsx`: pools with health, capacity, fragmentation, scrub controls, a - dataset tree and per-dataset snapshot lists with "Snapshot now". Moving it out makes room - for what is actually wanted: **scheduled snapshots with a retention policy**, configured - from the console rather than by hand. What exists to build on — `grid` runs `zfSnap` - nightly at 02:30 from root cron with 6-week expiry (`zfsnap-cron-6w-daily.sh`, predates - this repo), and Ham Lab's Cron tab can already read, write and run root crontabs, so the - job can be managed rather than reinvented. Decide: does Ham Lab drive `zfSnap`/`zfs-auto- - snapshot` if present, or write and own its own timer? Per-dataset policies or one for the - pool? And it must show what a retention rule *will* delete before it runs. - -- **Rename Cron to something generic** — asked for 2026-09-23, not started. Mitchell's - reasoning: the Services tab is systemd but "Services" is the right generic name for it, - so the scheduling tab should be named for the job it does, not the tool. **Scheduled** or - **Jobs**. The tab already covers more than cron — `/etc/crontab`, `/etc/cron.d`, user - crontabs, `run-parts` directories *and* systemd timers — so the generic name is the - honest one. Same rename surface as the Space tab: rail label, `View` id, hash route, - footer name. - - **A Virtualization tab** — asked for 2026-09-23, not started, and **large**. Run and manage **LXC containers and virtual machines** from the console, the way Proxmox does — which is the comparison Ham Lab has invited since its first line. Nothing exists yet.