Skip to content

Integrate microvm.nix guests - #136

Merged
clhodapp merged 1 commit into
mainfrom
feat/microvm
Oct 25, 2026
Merged

clhodapp merged 1 commit into
mainfrom
feat/microvm

Conversation

@clhodapp

Copy link
Copy Markdown
Contributor

microvm.nix runs no module evaluation itself. A guest is a NixOS evaluation with its guest module (nixos-modules/microvm). Its host module (nixos-modules/host) declares microvm.vms.<name>, and reads from each guest only microvm.declaredRunner, microvm.shares and system.build.toplevel. This adds the two integrations that bring guests into the caisson tree. Both are evaluated by caisson's code, and neither uses upstream's own guest evaluation.

caisson-microvm, native. Type and class caisson-microvm, namespace lib.caisson.caisson-microvm.

  • The configuration. It is declared inside a NixOS host as caisson.caisson-microvm.configurations.<name>, and holds similarly configured guests as caisson.nixos.configurations.<guest>.
  • Options. hypervisor, vcpu, mem, interfaces and shares use upstream's types and defaults, and say what the guests share. The start options are autostart (default false), restartIfChanged (default true) and runtimeMaxSec.
  • The guest module. The default of the class gives caisson/microvm-guest to the nearest NixOS configurations beneath it, through caisson.forNearestChildren (Give configurations their nearest children's defaults #135). That module imports upstream's guest module from the resolved microvm.nix source, recorded as an ecosystem unit. It defines the guest's options from the configuration, read through nearest.caisson-microvm.
  • Slots. slots.<kind> = { count; cidBase; shareRoot; vsockPort; moduleImports; extraModuleImports; } declares the guests <kind>-1 to <kind>-<count> from lib.caisson.configs.nixos.<kind>. Each slot gets the vsock CID cidBase + k. Each also gets its shares, <shareRoot>/<kind>-<k>/in read-only at /work/in and .../out at /work/out. The kind's moduleImports and extraModuleImports are passed to every slot, so a guest kind can reset the selection a host's registry default would give it. A kind that resets lists caisson/microvm-guest itself.

microvm, upstream-compatible. Type microvm, NixOS class, namespace lib.caisson.microvm. A configuration declared inside a host as caisson.microvm.configurations.<name> is the guest itself: caisson's NixOS evaluation with upstream's guest module appended, whose modules set the microvm options as microvm.nix users write them.

caisson/microvm-host. A NixOS module that a host selects to hold guests.

  • The guests. It imports upstream's host module, and defines microvm.vms.<guest> with evaluatedConfig for every guest that belongs to the host, by belongsHere.
  • Start options. It sets the start options, and RuntimeMaxSec on microvm@<guest>.
  • Refusals. It refuses upstream's config and flake forms for those names, and repeated guest names.
  • Operators. caisson.microvm-host.operators.<user> = [ <guest> … ] becomes a polkit rule that lets each user start, stop and restart exactly those guests' units.

Guests are published as nixosConfigurations.<guest>, are no colmena nodes, and inherit none of their host's nearest defaults, such as a disk layout's file systems.

Limits:

  • Homes inside a microvm guest. A configuration declared inside a microvm guest that looks up nearest.nixos, such as a home-manager configuration, finds the host, since the guest's type is microvm.
  • Hosts. A caisson-microvm configuration declared outside a NixOS host is not refused yet.

Tests (pinned world):

  • caissonMicrovmGuestsRunOnTheirHost: two plain guests and two slots in a host's microvm.vms, with toplevels matching the published ones, the start options, CIDs and shares, and values from the configuration.
  • microvmConfigurationIsTheGuest
  • microvmOperatorsGetExactlyTheirUnits
  • microvmSlotKindSelectsItsModules
  • microvmGuestsAreNoNodes: guests of a colmena node on a disk layout are no nodes and get neither the layout's file systems nor the deployment options.
  • everyModuleCaissonAddsIsNamed is extended to the new integrations.

tests/dependencies pins microvm.nix at 4876e2a. Locally, the pinned world, nix-unit, nix flake check --no-build, eval-weight, argument-errors, drift-message and nix fmt pass. A qemu guest's runner builds, with the same drvPath through the host's microvm.vms. No VM boot has run yet.

🤖 Generated with Claude Code

microvm.nix runs no module evaluation itself: a guest is a NixOS
evaluation with its guest module, and its host module declares
microvm.vms.<name> and reads the guest's runner, shares and toplevel.
Two integrations bring guests into the tree, both evaluated by
caisson's code.

caisson-microvm, the native integration, is a configuration declared
inside a NixOS host that holds similarly configured guests. Its
options are what they share: hypervisor, vcpu, mem, interfaces and
shares, typed as upstream types them, and the start options
autostart (false), restartIfChanged (true) and runtimeMaxSec. Its
default gives the nearest NixOS configurations beneath it
caisson/microvm-guest, which imports upstream's guest module and
defines its options from the configuration. slots.<kind> declares
the guests <kind>-1 to <kind>-N from the registered configuration
of the kind, each with its vsock CID and its shares under a directory
of the slot, and passes the kind's moduleImports to them.

microvm, the upstream-compatible integration, is the guest itself: a
NixOS evaluation with upstream's guest module, whose modules set the
microvm options as microvm.nix users write them.

caisson/microvm-host, a NixOS module, defines microvm.vms.<guest>
with evaluatedConfig for every guest that belongs to the host, sets
the start options and RuntimeMaxSec, refuses upstream's config and
flake forms for those names, and turns
caisson.microvm-host.operators.<user> into a polkit rule that lets
those users start and stop exactly their guests' units. Guests are
published as nixosConfigurations.<guest> and are no colmena nodes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clhodapp clhodapp self-assigned this Oct 25, 2026
@clhodapp
clhodapp merged commit 2fcf1b8 into main Oct 25, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant