Virtualization plan: a Library for ISOs and images; VGA console moves to phase 2 with it
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
0fa6ab98e2
commit
e772f7fae2
+78
-9
@@ -100,18 +100,75 @@ destructive ones confirmed by typing the name.
|
|||||||
- **Resources** — edit CPU and memory limits (live for containers; VMs take CPU hotplug and
|
- **Resources** — edit CPU and memory limits (live for containers; VMs take CPU hotplug and
|
||||||
memory balloon live with the agent, else on restart), grow the root disk, add a bind mount
|
memory balloon live with the agent, else on restart), grow the root disk, add a bind mount
|
||||||
(a host path into a container; virtiofs into a VM).
|
(a host path into a container; virtiofs into a VM).
|
||||||
- **Images** — what is cached locally, delete, aliases; **publish** a stopped instance as an
|
- **Library** — ISOs for VMs and images (container templates and VM images). Its own
|
||||||
image (Proxmox's "convert to template").
|
section below.
|
||||||
- **Storage and networks** — the pools with their fill, the bridges with their subnets.
|
- **Storage and networks** — the pools with their fill, the bridges with their subnets.
|
||||||
Read-only in v1 beyond what Create and Install need.
|
Read-only in v1 beyond what Create and Install need.
|
||||||
- **Sensors** — `instance.<name>.cpu`, `.memory`, `.running` from Incus's state, like the
|
- **Sensors** — `instance.<name>.cpu`, `.memory`, `.running` from Incus's state, like the
|
||||||
`container.*` sensors, so Alerts gets an "instance down" default and widgets can show one.
|
`container.*` sensors, so Alerts gets an "instance down" default and widgets can show one.
|
||||||
|
|
||||||
|
## Library: ISOs and images (asked for 2026-10-09)
|
||||||
|
|
||||||
|
Proxmox has a storage view with **ISO Images** and **CT Templates**. Incus has the same two
|
||||||
|
things under other names, and the tab gives them one home, a **Library** sub-tab, per machine
|
||||||
|
like everything else.
|
||||||
|
|
||||||
|
| Proxmox calls it | Incus calls it | What it is here |
|
||||||
|
|---|---|---|
|
||||||
|
| ISO Images | an ISO file attached to a VM as a `disk` device (added as a ROM device; VMs only), or a custom storage volume of type `iso` | **A directory of `.iso` files on the machine that Ham Lab indexes** — no copy into the pool |
|
||||||
|
| CT Templates | **images** — the `images:` remote (linuxcontainers.org), the local image store, anything imported or published | **The local image store**, with the remote as the catalogue to pull from |
|
||||||
|
|
||||||
|
### ISOs
|
||||||
|
|
||||||
|
- **One ISO directory per machine**, chosen in the Install dialog and changeable later.
|
||||||
|
Default is under Ham Lab's data directory; on `grid` it should be the existing
|
||||||
|
**`/tank/software/isos/`** — 105 GiB already there (`linux/`, `windows/`, `truenas/`,
|
||||||
|
`virtio_drivers/`, `pi/`, `hackberry/`, `sipeed/`), scanned recursively.
|
||||||
|
- **Getting an ISO in:** upload from the browser (the Files tab's `PUT /api/files/upload`
|
||||||
|
with its progress bar, reused), **download from a URL** as a followed task with an optional
|
||||||
|
checksum (the usual way — an ISO starts as a link), or **import from a path** already on the
|
||||||
|
machine. Rename, delete (refused while a VM has it attached, naming the VM).
|
||||||
|
- **Using one:** attach to / detach from a VM as a ROM device by path, with `boot.priority`
|
||||||
|
set so it boots first; **New VM from ISO** makes an empty VM (`incus init --empty --vm`)
|
||||||
|
with the ISO attached, starts it and opens the console. After install, Detach is one click
|
||||||
|
and boot order falls back to the disk.
|
||||||
|
- **Honest limit:** an ISO install is an interactive graphical installer, so it needs the
|
||||||
|
**VGA console in the browser** (`spice-html5` over Incus's VGA console websocket).
|
||||||
|
Installers that run on a serial console (Debian with `console=ttyS0`, Alpine, Arch) work
|
||||||
|
through the text console before that exists. Windows needs the virtio drivers ISO attached
|
||||||
|
as a second ROM device as well — Incus's documented path is `distrobuilder repack-windows`
|
||||||
|
to bake them in; the drivers are already in `virtio_drivers/` on `tank`. So **the ISO shelf
|
||||||
|
and the VGA console ship together, in phase 2**, moved up from phase 3.
|
||||||
|
- ISO *volumes* (`incus storage volume import <pool> <iso> <name> --type=iso`) are the
|
||||||
|
alternative: read-only, attachable to several VMs at once, but they copy the file into the
|
||||||
|
pool. Not the default here — the directory honours the library that already exists and
|
||||||
|
keeps 105 GiB out of a 300 GiB pool. Offered as an option only if a need shows up.
|
||||||
|
|
||||||
|
### Images (container templates and VM images)
|
||||||
|
|
||||||
|
- **The catalogue:** browse `images:` filtered to this machine's architecture, by type
|
||||||
|
(container / VM), with the common ones pinned. **Download** copies one into the local
|
||||||
|
store (`incus image copy images:debian/13 local: --alias debian-13`) so a later Create is
|
||||||
|
instant and works without the internet. Images used by Create are cached by Incus anyway;
|
||||||
|
this is just the explicit version, Proxmox's "Templates → Download".
|
||||||
|
- **The local store:** every image here with alias, type, arch, size, origin (remote,
|
||||||
|
published, imported), when it was last used, and **which instances were made from it**
|
||||||
|
(Incus records the base image on each instance). Alias, delete (refused while an
|
||||||
|
instance's base — Incus knows), "New instance from this image".
|
||||||
|
- **Import:** a unified tarball or metadata + rootfs pair (a container template from
|
||||||
|
anywhere, including the phase-3 Proxmox conversions), or a **qcow2 / raw disk with
|
||||||
|
metadata Ham Lab writes** for a VM image — Home Assistant OS, OPNsense, a vendor cloud
|
||||||
|
image — by upload, URL, or a path on the machine. Same three ways in as ISOs.
|
||||||
|
- **Publish:** a stopped instance becomes an image with an alias — Proxmox's "convert to
|
||||||
|
template", the one thing the Images section of v1 always had.
|
||||||
|
- **Where they live:** Incus's image store, in the pool, so the pool's fill on the Storage
|
||||||
|
view includes them and says so.
|
||||||
|
|
||||||
## Not in v1, with reasons
|
## Not in v1, with reasons
|
||||||
|
|
||||||
| Thing | Why not yet |
|
| Thing | Why not yet |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **VGA console in the browser** | Incus hands the VM's SPICE socket over a websocket; drawing it needs `spice-html5` in the UI. Doable (the Incus UI does it), but text console + shell cover every Linux guest. Phase 3. |
|
| **VGA console in the browser** | Incus hands the VM's SPICE socket over a websocket; drawing it needs `spice-html5` in the UI. Doable (the Incus UI does it); text console + shell cover every Linux guest until then. **Phase 2, with the ISO shelf** — an ISO install is useless without it. |
|
||||||
| **Windows VMs** | Incus runs them (ISO repacked with virtio drivers by `distrobuilder`), but without a VGA console in the browser they are unusable from the tab. After the above. |
|
| **Windows VMs** | Incus runs them (ISO repacked with virtio drivers by `distrobuilder`), but without a VGA console in the browser they are unusable from the tab. After the above. |
|
||||||
| **GPU passthrough to a VM** | Removes the card from the host and from whatever uses it there (Jellyfin on `grid`). Offered only with that warning, later. Sharing a GPU into a *container* (`gpu` device) leaves the host its card and is how `r720-jellyfin` used to run. Phase 3. |
|
| **GPU passthrough to a VM** | Removes the card from the host and from whatever uses it there (Jellyfin on `grid`). Offered only with that warning, later. Sharing a GPU into a *container* (`gpu` device) leaves the host its card and is how `r720-jellyfin` used to run. Phase 3. |
|
||||||
| **Clustering / live migration** | Incus clusters, but these machines differ in size and one is arm64, with no shared storage. Not planned. |
|
| **Clustering / live migration** | Incus clusters, but these machines differ in size and one is arm64, with no shared storage. Not planned. |
|
||||||
@@ -178,9 +235,10 @@ confs), 118 GiB of `vzdump` archives, and three raw VM disks. Latest of each:
|
|||||||
|
|
||||||
- **LXC:** feasible and scriptable. Unpack the rootfs (`tar --zstd -xpf … --numeric-owner`),
|
- **LXC:** feasible and scriptable. Unpack the rootfs (`tar --zstd -xpf … --numeric-owner`),
|
||||||
read `etc/vzdump/pct.conf` for arch/ostype, drop it, write `metadata.yaml`, pack, `incus
|
read `etc/vzdump/pct.conf` for arch/ostype, drop it, write `metadata.yaml`, pack, `incus
|
||||||
image import`, launch. Unprivileged uid shifting is Incus's job after that. An import
|
image import`, launch. Unprivileged uid shifting is Incus's job after that. The result is
|
||||||
action in the tab (pick an archive on this machine) is plausible once the script works by
|
an image in the Library, so a restored container is launched from there like any other
|
||||||
hand. x86-64 archives only run on x86-64 machines; the picker says so.
|
template. An import action in the tab (pick an archive on this machine) is plausible once
|
||||||
|
the script works by hand. x86-64 archives only run on x86-64 machines; the picker says so.
|
||||||
- **VMs:** the raw disks import directly (`incus-migrate`, or an empty VM with the disk
|
- **VMs:** the raw disks import directly (`incus-migrate`, or an empty VM with the disk
|
||||||
imported into its root volume). The `.vma.zst` archives need Proxmox's `vma` extractor (or
|
imported into its root volume). The `.vma.zst` archives need Proxmox's `vma` extractor (or
|
||||||
the Python port) to become raw disks first. Most of these are the same `powerpanel` box
|
the Python port) to become raw disks first. Most of these are the same `powerpanel` box
|
||||||
@@ -191,9 +249,9 @@ confs), 118 GiB of `vzdump` archives, and three raw VM disks. Latest of each:
|
|||||||
|
|
||||||
| Phase | What | Effort |
|
| Phase | What | Effort |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **1 — detection, Install, the tab** | `internal/incus` (detection, CLI wrapper, JSON types, `incus monitor` for live state, the preseed builder and subnet picker), `internal/api/virt.go` (routes below), `Virtualization.tsx` (the three page states; list, detail, create dialog, snapshot panel), rail entry `virt`, terminal integration, sensors. **Tested by clicking Install on `grid` first, then `core`** — two different pool drivers, both with Docker present. Then the Mac for the arm64 path. `gate` for the unavailable state. | 2–3 sessions |
|
| **1 — detection, Install, the tab** | `internal/incus` (detection, CLI wrapper, JSON types, `incus monitor` for live state, the preseed builder and subnet picker), `internal/api/virt.go` (routes below), `Virtualization.tsx` (the three page states; list, detail, create dialog, snapshot panel), rail entry `virt`, terminal integration, sensors, and the Library's **Images** shelf (browse and download from `images:`, local store, import, publish). **Tested by clicking Install on `grid` first, then `core`** — two different pool drivers, both with Docker present. Then the Mac for the arm64 path. `gate` for the unavailable state. | 2–3 sessions |
|
||||||
| **2 — operations** | Snapshot schedules UI, nightly exports with retention and the per-machine export directory, limits editor, bind mounts, the LAN-bridge step, instance alert default, cloud-init presets. | 1–2 sessions |
|
| **2 — operations** | The Library's **ISO** shelf (directory, upload/URL/path, attach, New VM from ISO) **with the VGA console** (`spice-html5`), snapshot schedules UI, nightly exports with retention and the per-machine export directory, limits editor, bind mounts, the LAN-bridge step, instance alert default, cloud-init presets. | 1–2 sessions |
|
||||||
| **3 — the rest** | Proxmox import, publish-as-image, GPU device for containers, VGA console (`spice-html5`), GPU passthrough to a VM with its warning. | as wanted |
|
| **3 — the rest** | Proxmox import (archives become Library images), GPU device for containers, Windows via `distrobuilder repack-windows`, GPU passthrough to a VM with its warning. | as wanted |
|
||||||
|
|
||||||
### API sketch
|
### API sketch
|
||||||
|
|
||||||
@@ -212,6 +270,17 @@ POST /api/virt/instances/{name}/exec → terminal {id} (incus exec -
|
|||||||
POST /api/virt/instances/{name}/snapshots {name}; POST …/{snap}/restore; DELETE …/{snap}
|
POST /api/virt/instances/{name}/snapshots {name}; POST …/{snap}/restore; DELETE …/{snap}
|
||||||
PUT /api/virt/instances/{name}/schedule {cron, expiry}
|
PUT /api/virt/instances/{name}/schedule {cron, expiry}
|
||||||
POST /api/virt/import {path} task (export tarball, or phase-3 Proxmox archive)
|
POST /api/virt/import {path} task (export tarball, or phase-3 Proxmox archive)
|
||||||
|
|
||||||
|
GET /api/virt/isos the ISO directory, scanned: name, size, attached-to
|
||||||
|
PUT /api/virt/isos/dir {path} change this machine's ISO directory
|
||||||
|
POST /api/virt/isos/fetch {url, sha256?} task; uploads reuse PUT /api/files/upload
|
||||||
|
DELETE /api/virt/isos/{name} refused while attached
|
||||||
|
POST /api/virt/instances/{name}/iso {iso, boot_first} attach; DELETE …/iso detach
|
||||||
|
POST /api/virt/instances/from-iso {name, iso, cpu, memory, disk, network} task → console
|
||||||
|
GET /api/virt/images/remote?q=&type= the `images:` catalogue for this arch
|
||||||
|
POST /api/virt/images/download {alias} task (incus image copy images:… local:)
|
||||||
|
POST /api/virt/images/import {path | url, alias, type} task (tarball, or qcow2/raw + metadata)
|
||||||
|
GET /api/virt/instances/{name}/vga websocket: Incus VGA console → spice-html5 (phase 2)
|
||||||
```
|
```
|
||||||
|
|
||||||
Everything is per machine and reaches a node through the existing `/api/nodes/{name}/…`
|
Everything is per machine and reaches a node through the existing `/api/nodes/{name}/…`
|
||||||
|
|||||||
Reference in New Issue
Block a user