Declare the persistent volumes a selected microvm archetype requires #25

Closed
opened 2026-07-31 06:07:02 +01:00 by allod-agent · 0 comments
Member

Give a dev microVM the persistent disks it needs to be usable, so selecting the microvm runtime produces a machine that keeps its home directory and its Nix state across a restart instead of failing to evaluate.

Primary goals:

  • Declare the required persistent paths per archetype — a dev microVM requires the user's home and /nix/var/nix, declared in one place in the builders rather than restated per machine.
  • Derive each volume image path from a framework-owned root plus the machine name — no per-machine placement data, and no second declaration to keep in sync with the guest's own entry.
  • Fail on an incomplete set, not on a downstream symptom — a required path without a volume is an archetypes-side error naming the path, rather than allod/vm's lower-level store-volume assertion.
  • Delete the check placeholderruntime-module-selection currently supplies its own /nix/var/nix volume so the microvm branch can be forced at all; real declarations make that redundant and it must not be left shadowing them.

Current state and specifics

allod/archetypes selects the guest module from the inventory runtime fact as of allod/archetypes#23, but declares no volumes. Composing microvmGuest without a /nix/var/nix entry fails on allod/vm modules/microvm-store.nix:121-127: /nix/var/nix must have a declared persistent microvm.volumes entry. So the runtime is selectable and no machine can use it — the fail-closed state that PR chose deliberately, and the gap this issue closes.

Placement has exactly one home. allod/nexus docs/microvm-host.md:81-88 records why: a volume image "has no source/destination split the way a credential does: its host path can only live in the guest's own microvm.volumes[].image, because that is the string QEMU renders into -drive file= and the same field the launcher preflights." The host-side placement option that once existed was removed in nexus commit 16bd9c7. nexus.microvm now exposes only hostPlaintextRoot and per-machine credentialSources (nix/microvm/host.nix:315-353).

Deriving the path is already the established pattern rather than a new idea. allod/nexus checks/microvm/fixtures.nix:32,43 computes volumeImageFor = name: "${volumeRoot}/${name}/nix-state.img" from volumeRoot = "/var/lib/allod-microvm-volumes". allod/vm checks/examples.nix:34 uses the same shape. A per-machine placement fact would be data that is always a function of the machine name, and the docs above call out that a second declaration would only ever be "typed twice and kept in sync by an assertion, or derived from the option and then compared against itself."

The framework declares the paths; the deployer supplies the bytes. Nothing here creates, formats, labels, truncates or relabels an image — allod/strategy dev plan microvm-framework-adoption.md contract 13 keeps autoCreate = false on every entry and leaves image creation an explicit provisioning action before a VM is enabled. The launcher already refuses a missing, non-regular or inaccessible image before QEMU starts.

Scope

In scope: the required-path set per selected microvm archetype, the derived microvm.volumes entries with autoCreate = false and neededForBoot on the corresponding fileSystems entries, an overridable framework-owned image root, the archetypes-side error for an incomplete set, removal of the runtime-module-selection placeholder, and paired sabotage fixtures for each new assertion.

Out of scope and tracked elsewhere in the same arc: runtime credential delivery and the guest credential root; guest networking and the TAP interface; the extendModules host integration that supplies credentialFiles from the Nexus host option; exporting the runtime through vmFacts; and the nested-boot store-lifecycle tests that settle contract 6a, which the dev plan already requires before any real machine selects this runtime.

This is public work. Every value it introduces is framework-owned and derived — a mount point set, an image root, and a name-keyed path. The private side substitutes its own machine data through the existing deploy redirect, exactly as it already does for addresses and host keys; no absolute path tied to a real host is written here.

Part of allod/strategy#20

Give a dev microVM the persistent disks it needs to be usable, so selecting the microvm runtime produces a machine that keeps its home directory and its Nix state across a restart instead of failing to evaluate. Primary goals: - **Declare the required persistent paths per archetype** — a dev microVM requires the user's home and `/nix/var/nix`, declared in one place in the builders rather than restated per machine. - **Derive each volume image path from a framework-owned root plus the machine name** — no per-machine placement data, and no second declaration to keep in sync with the guest's own entry. - **Fail on an incomplete set, not on a downstream symptom** — a required path without a volume is an archetypes-side error naming the path, rather than allod/vm's lower-level store-volume assertion. - **Delete the check placeholder** — `runtime-module-selection` currently supplies its own `/nix/var/nix` volume so the microvm branch can be forced at all; real declarations make that redundant and it must not be left shadowing them. ### Current state and specifics `allod/archetypes` selects the guest module from the inventory `runtime` fact as of allod/archetypes#23, but declares no volumes. Composing `microvmGuest` without a `/nix/var/nix` entry fails on allod/vm `modules/microvm-store.nix:121-127`: `/nix/var/nix must have a declared persistent microvm.volumes entry`. So the runtime is selectable and no machine can use it — the fail-closed state that PR chose deliberately, and the gap this issue closes. Placement has exactly one home. `allod/nexus` `docs/microvm-host.md:81-88` records why: a volume image "has no source/destination split the way a credential does: its host path can only live in the guest's own `microvm.volumes[].image`, because that is the string QEMU renders into `-drive file=` and the same field the launcher preflights." The host-side placement option that once existed was removed in nexus commit `16bd9c7`. `nexus.microvm` now exposes only `hostPlaintextRoot` and per-machine `credentialSources` (`nix/microvm/host.nix:315-353`). Deriving the path is already the established pattern rather than a new idea. `allod/nexus` `checks/microvm/fixtures.nix:32,43` computes `volumeImageFor = name: "${volumeRoot}/${name}/nix-state.img"` from `volumeRoot = "/var/lib/allod-microvm-volumes"`. `allod/vm` `checks/examples.nix:34` uses the same shape. A per-machine placement fact would be data that is always a function of the machine name, and the docs above call out that a second declaration would only ever be "typed twice and kept in sync by an assertion, or derived from the option and then compared against itself." The framework declares the paths; the deployer supplies the bytes. Nothing here creates, formats, labels, truncates or relabels an image — `allod/strategy` dev plan `microvm-framework-adoption.md` contract 13 keeps `autoCreate = false` on every entry and leaves image creation an explicit provisioning action before a VM is enabled. The launcher already refuses a missing, non-regular or inaccessible image before QEMU starts. ### Scope In scope: the required-path set per selected microvm archetype, the derived `microvm.volumes` entries with `autoCreate = false` and `neededForBoot` on the corresponding `fileSystems` entries, an overridable framework-owned image root, the archetypes-side error for an incomplete set, removal of the `runtime-module-selection` placeholder, and paired sabotage fixtures for each new assertion. Out of scope and tracked elsewhere in the same arc: runtime credential delivery and the guest credential root; guest networking and the TAP interface; the `extendModules` host integration that supplies `credentialFiles` from the Nexus host option; exporting the runtime through `vmFacts`; and the nested-boot store-lifecycle tests that settle contract 6a, which the dev plan already requires before any real machine selects this runtime. This is public work. Every value it introduces is framework-owned and derived — a mount point set, an image root, and a name-keyed path. The private side substitutes its own machine data through the existing deploy redirect, exactly as it already does for addresses and host keys; no absolute path tied to a real host is written here. Part of allod/strategy#20
vnprc closed this issue 2026-07-31 11:57:39 +01:00
Sign in to join this conversation.
No description provided.