VM — Appliance-VM Front-End (libvirt/QEMU)

  • Area: infra/net/
  • Path: infra/net/vm
  • Slug: koder-vm (binary kvirt)
  • Kind: Thin libvirt/QEMU front-end (Go) — the permanent appliance-VM scope of the Koder runtime strategy
  • Version: v0.1.0 (CHANGELOG: infra/net/vm/CHANGELOG.kmd)
  • RFC: infra-RFC-001-koder-runtime-strategy §"Axis C.2"

Role in the stack — and why it is NOT kbox

The runtime strategy (infra-RFC-001) splits host workloads by contract, not by "container vs VM":

  • OCI run-to-lifecycle (image → boots → runs → exits): namespaced containers

    AND Firecracker microVMs share this contract → Box (kbox run --runtime=namespace|microvm).

  • Stateful appliance VM (own disk image, BIOSUEFI, consoleRDP/WinRM,

    snapshot-as-disk): does NOT fit kbox run <oci-image>Koder VM (kvirt).

QEMU/KVM is therefore a permanent, closed-scope boundary — not a self-hosted gap to close — for three workload classes:

  1. Windows guest — Flutter Windows build via k.win WinRM.
  2. Arbitrary-kernel testingklinux ISO build chroot, kernel-module testing.
  3. Cross-architecture emulation — arm guest on amd host edge cases.

Koder VM is deliberately small: a thin wrapper over virsh that adds the Stack integrations, not a libvirt re-implementation. It must not grow to duplicate kbox.

Shared substrate (the C.0 layer — zero plumbing duplication)

A reuse-first.kmd walk (SDKGO-005) confirmed kbox's cross-cutting plumbing is mostly already shared SDK. Koder VM reuses it rather than cloning it:

Concern Shared package Status
Lifecycle verbs + host-instances registry engines/sdk/go/hostinst New — co-designed with Koder VM as the real 2nd consumer (reuse-first "promote on the 2nd consumer"). kbox repoint tracked as BOX-152.
Observability (OTLP traces) engines/sdk/go/obs Reused. kvirt ops trace to the same collector as kbox (KODER_VM_OTLP_ENDPOINT).
Auth (Koder ID JWT) engines/sdk/go/auth Consumed directly if/when an API surface is added — no local skeleton.

engines/sdk/go/hostinst defines Kind (container|vm), State, Instance, Lister/Lifecycle interfaces, and a Registry that merges backends into one "what's running on this host" view spanning containers + VMs. Koder VM's libvirt client implements Lifecycle; kvirt list lists through the registry.

Surfaces

Surface Form Notes
kvirt CLI Go binary Linux amd64 + arm64. Verbs: start, stop [--force], destroy, list [--json], console, snapshot. Standard flags --version--help (probe-safe per `specsbinaries-and-cli/standard-flags.kmd`).

Status

v0.1.0 ships the thin libvirt front-end + the shared hostinst substrate it co-defines. Named-domain conveniences (kvirt start win10, kvirt exec klinux build) map onto defined libvirt domains; the kbox→hostinst repoint that completes the unified host view is BOX-152.