From faf444d8cea165bb48692b68b07a5044a0e63f6d Mon Sep 17 00:00:00 2001 From: Mitchell-Johnson Date: Sun, 11 Oct 2026 14:36:06 -0700 Subject: [PATCH] =?UTF-8?q?VIRTUALIZATION.md:=20storage=20decision=20revis?= =?UTF-8?q?ed=20=E2=80=94=20a=20Disk=20location=20picker,=20plain=20files?= =?UTF-8?q?=20on=20grid's=20root=20disk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- VIRTUALIZATION.md | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/VIRTUALIZATION.md b/VIRTUALIZATION.md index 8e6f4f5..92caaa8 100644 --- a/VIRTUALIZATION.md +++ b/VIRTUALIZATION.md @@ -1,20 +1,17 @@ # Virtualization tab — plan (2026-10-09; phase 1 built the same day) -**Status:** phases 1 and 2 are **deployed to all five machines as v0.1.0-188** (2026-10-09). -Incus runs on `grid` (installed from the tab); the other machines show Install or, on `gate`, -unavailable. Phase 2 verified live on `grid` through the hub: ISO fetched by URL with its -sha256 checked, **New VM from ISO** booted Alpine with Secure Boot off, **the VGA console -drew it in a real browser** (headless Chromium, 1280×800 canvas, keyboard and mouse live), -a virtiofs mount appeared in a running VM, an export tarball landed in `virt/exports/` and the -nightly cron line is written, `instance.*` sensors flow and the "VM or container down" alert -default is in. Two things found and fixed on the way: spice-html5 wants the `binary` -websocket subprotocol agreed; and it opens one websocket per SPICE channel, so the bridge -holds **one console operation per VM** and gives each channel its own data websocket on it -(Incus refuses a second operation as "already connected"). **Left from phase 2:** the LAN -bridge step (`br0` on the uplink — needs a live test on a machine that can afford to drop -off the network for a moment, which is a decision, not a build), cloud-init presets beyond -"Use my SSH keys", and a backup line for `grid`'s `virt/exports/` (see `hamlet/docs/backups.md`). -`t-alpine` on `grid` is the live example; delete it from the tab when done. +**Status:** phases 1 and 2 are **deployed to all five machines as v0.1.0-196** (2026-10-11). +Incus runs on `grid` with **plain-files storage on its root disk** (`local`, see decision 1, +revised 2026-10-11 — the file-backed ZFS pool and the test VM are gone); the other machines +show Install or, on `gate`, unavailable. A **Disk location** picker is on both create forms, +with add/remove of locations. Phase 2 verified live on `grid` through the hub on 2026-10-09: +ISO fetched by URL with its sha256 checked, New VM from ISO booted Alpine with Secure Boot +off, the VGA console drew it in a real browser (headless Chromium; needed the `binary` +websocket subprotocol and one console operation per VM with a data websocket per SPICE +channel), a virtiofs mount appeared in a running VM, an export tarball landed and the nightly +cron line is written, `instance.*` sensors flow and the "VM or container down" alert default +is in. **Left:** the LAN bridge step (his call, needs him near the NanoKVM), cloud-init +presets beyond "Use my SSH keys", a backup line for `grid`'s `virt/exports/`. A tab for creating, watching, consoling into and deleting **LXC containers and KVM virtual machines**, the way Proxmox does with `pct` and `qm` — **per machine, like every other @@ -236,12 +233,18 @@ like everything else. ## Layout decisions Ham Lab makes per machine (overridable in the Install dialog) -1. **Storage.** The instance pool's backing lives in Ham Lab's folder: Install creates a - sparse `virt/pool.img` and hands it to Incus as the pool's `source` (zfs or btrfs by the - detection above), or `virt/pool/` as a `dir` pool where neither is available. Sized from - the disk's free space, shown and editable. Bulk data is **bind-mounted in**, not stored in - the pool. The driver, path and size are recorded in `virt.json` so the page can say where - the data is and Install can rebuild the pool from the file after a reinstall. +1. **Storage — revised 2026-10-11.** The create forms carry a **Disk location** picker: a + list of the machine's Incus storage pools, each described by where its bytes land, with + "+ add a location" (any folder on the machine becomes a plain-files pool). On `grid` the + one location is `local`: plain files under `virt/pool/` on the root NVMe, each VM's disk + its own sparse file sized on its own, each container a directory, nothing pre-sized. + *The first design* (a ZFS pool inside one sparse file, handed to Incus as the pool's + source, for instant snapshots and clones) was built, ran for two days, and was taken out + at Mitchell's instruction: one pre-sized file holding every disk is an opaque middle + layer with a number on it that reads as a reservation, and "zfs · hamlab-virt" on the page + read as the NAS pool. The Install dialog still offers zfs/btrfs-in-a-file for a machine + that wants instant snapshots; the labels now say exactly what each is. Bulk data is still + **bind-mounted in**, not stored in the pool. 2. **Bridge subnet, computed.** Incus's `auto` picks a random `10.x.y.0/24`, and **this LAN is `10.0.0.0/8`** — every host has a /8 on its NIC, so any 10.x bridge collides. Ham Lab reads the machine's routes and picks the first free /24 from `192.168.0.0/16`,