vm-manager

command module
v0.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

README

vm-manager

Prototype. An MCP + REST server that provisions cloud-provider-like VMs (IMDS, vTPM with measured boot, immutable mkosi-built OS, Kubernetes as a sysext layer) on a KVM host, so agents on the Giant Swarm agent platform can hand them to the CAPI based cluster-manager.

Sibling of agent-manager and model-manager.

API at a glance

The same operations are exposed twice from one process: REST/JSON under /api/v1 (contract: api/openapi.yaml, served at /api/v1/openapi.yaml) and MCP tools over streamable HTTP at /mcp (through muster: x_vm-manager_<tool>). Both call the same service and return the same JSON. Errors are {"error":{"code","message"}} with a stable code; MCP tool errors carry the same code.

Operation REST MCP tool Writes
Host capabilities: kernel, CPUs, memory, /dev/kvm, /dev/vhost-vsock, qemu / swtpm / systemd versions, OVMF image, storage providers, ready + missing GET /api/v1/host get_host no
List the bootable images (id, version, UKI, disk, Kubernetes sysext versions, PCR policy) GET /api/v1/images list_images no
Describe one image (<id>_<version> or bare id = newest) GET /api/v1/images/{ref} get_image no
List the virtual networks with gateway and leases GET /api/v1/networks list_networks no
Describe one network GET /api/v1/networks/{name} get_network no
List every VM record, oldest first GET /api/v1/vms list_vms no
Fetch one VM: state, IP, attestation, last error GET /api/v1/vms/{id} get_vm no
Tail of the serial console (lines, default 100) GET /api/v1/vms/{id}/console?lines= get_vm_console no
The guest's last systemd-report upload (host metrics: later release) GET /api/v1/vms/{id}/metrics get_vm_metrics no
The current boot's attestation verdicts GET /api/v1/vms/{id}/attestation get_vm_attestation no
Create a network (name, cidr, dns_search_domain); IMDS always on POST /api/v1/networks create_network yes
Delete a network; conflict while a VM is attached DELETE /api/v1/networks/{name} delete_network yes, destructive
Create a VM (name, image, kubernetes_version, cpus 2, memory_mib 2048, disk_gib 20, network default, user_data, ssh_authorized_keys, hostname, metadata, require_attestation true, wait_for ready) POST /api/v1/vms create_vm yes
Boot a stopped or failed VM from its disk POST /api/v1/vms/{id}/start start_vm yes
Power a VM down (ACPI, then SIGTERM/SIGKILL after --stop-timeout) POST /api/v1/vms/{id}/stop stop_vm yes
Stop, then start POST /api/v1/vms/{id}/reboot reboot_vm yes
Stop if running, remove disk, vTPM state, lease and record DELETE /api/v1/vms/{id} delete_vm yes, destructive
Run a command as root in the guest over ssh (command array) POST /api/v1/vms/{id}/exec exec_vm yes, destructive
Expose a guest TCP port on a host loopback address (port) POST /api/v1/vms/{id}/forward forward_port yes

Request bodies use the tool argument names (snake_case); resources come back as the service records them (camelCase). Error codes: not_found, invalid_request, conflict, unsupported, timeout (a wait_for milestone was not reached; the VM keeps running), vm_failed (the VM failed before the milestone; lastError and the console say why), internal_error.

Lifecycle

A VM needs a network: create_network, or the network named default that serve creates at startup from --network-subnet. create_vm allocates a disk on the storage provider, a vTPM, a lease and a vsock id, boots the installer (installing; sysinstall copies the image onto the disk), reboots into the installed disk (booting), attests from the initrd when require_attestation is set (attesting) and is ready once the guest's service manager sent READY=1 over vsock; running means the process is up but READY never arrived within --boot-timeout. wait_for picks how long create_vm blocks: none returns at once and get_vm follows the progress; installed, attested or ready block for that milestone, bounded by --install-timeout and --boot-timeout. user_data is CAPI's bootstrap Secret as Ignition JSON: the IMDS serves it at /user-data only after a verified attestation quote from the initrd (immediately after the installed boot starts when require_attestation is false), so a VM created without user_data boots the bare OS. stop_vm / start_vm / reboot_vm move a VM between stopped and running states (attestation and the user-data gate reset on every installed boot); delete_vm removes the VM with its disk; delete_network succeeds once no VM is attached. vm-manager does not reattach to QEMU across its own restarts: on shutdown every VM is stopped gracefully, on startup such VMs are stopped with a note in lastError.

Running

make build
./vm-manager serve                       # 127.0.0.1:8080, anonymous
./vm-manager serve --listen 0.0.0.0:8080 --enable-oauth --oauth-base-url https://vmm.example \
  --dex-issuer-url https://dex.example/dex --dex-client-id ... --dex-client-secret ... \
  --oauth-trusted-audiences agent-platform

Every flag has an environment fallback named in vm-manager serve --help (VM_MANAGER_LISTEN, VM_MANAGER_STATE_DIR, VM_MANAGER_IMAGE_DIR, VM_MANAGER_NETWORK_SUBNET, ...). State lives under --state-dir ($XDG_STATE_HOME/vm-manager, else ~/.local/state/vm-manager), images under --image-dir (default <state-dir>/images); /healthz and /readyz are always open.

vm-manager runs on the KVM host itself (a laptop, a GitHub Actions runner, a bare-metal node), not in a pod: GET /api/v1/host tells you whether the host is ready and what is missing (/dev/kvm, swtpm, the systemd storage provider, ...).

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package api publishes the vm-manager API contract.
Package api publishes the vm-manager API contract.
Package cmd holds the vm-manager CLI.
Package cmd holds the vm-manager CLI.
Package e2e holds the T3 boot end-to-end tests of docs/design.md "Testing strategy": real QEMU on KVM, swtpm, OVMF and the mkosi image from images/.
Package e2e holds the T3 boot end-to-end tests of docs/design.md "Testing strategy": real QEMU on KVM, swtpm, OVMF and the mkosi image from images/.
internal
api
Package api exposes the domain services twice from one process: REST/JSON under /api/v1 for the portal and cluster-manager, and MCP tools for muster.
Package api exposes the domain services twice from one process: REST/JSON under /api/v1 for the portal and cluster-manager, and MCP tools for muster.
apierr
Package apierr holds the sentinel errors every domain package wraps so the API layer can map them to one HTTP status and one stable error code for REST and MCP alike (internal/api statusFor).
Package apierr holds the sentinel errors every domain package wraps so the API layer can map them to one HTTP status and one stable error code for REST and MCP alike (internal/api statusFor).
host
Package host reports what the KVM host offers vm-manager: kernel and hardware, the devices and tools the QEMU runtime needs, the firmware the images boot with, and the systemd services the provisioner talks to.
Package host reports what the KVM host offers vm-manager: kernel and hardware, the devices and tools the QEMU runtime needs, the firmware the images boot with, and the systemd services the provisioner talks to.
identity
Package identity carries the authenticated caller through a request: who the OAuth layer validated (subject, email, groups).
Package identity carries the authenticated caller through a request: who the OAuth layer validated (subject, email, groups).
images
Package images is the catalog of guest images vm-manager can boot: the base DDIs and UKIs produced by images/ (see images/README.md), the Kubernetes sysext versions served next to them and the PCR policy recorded for each image.
Package images is the catalog of guest images vm-manager can boot: the base DDIs and UKIs produced by images/ (see images/README.md), the Kubernetes sysext versions served next to them and the PCR policy recorded for each image.
imds
Package imds implements the Giant Swarm instance metadata service: the HTTP side of the contract systemd-imdsd in the guest is configured for by the hwdb record the image ships (HwdbFile, generated from Keys by HwdbRecord).
Package imds implements the Giant Swarm instance metadata service: the HTTP side of the contract systemd-imdsd in the guest is configured for by the hwdb record the image ships (HwdbFile, generated from Keys by HwdbRecord).
network
Package network is vm-manager's rootless software-defined network.
Package network is vm-manager's rootless software-defined network.
runtime/proc
Package proc starts and supervises the long-running host processes the VM runtime is made of: QEMU (internal/runtime/qemu) and swtpm (internal/tpm).
Package proc starts and supervises the long-running host processes the VM runtime is made of: QEMU (internal/runtime/qemu) and swtpm (internal/tpm).
runtime/qemu
Package qemu is the process-level VM runtime: it turns a Spec into the qemu-system-x86_64 argument list, starts and supervises the process, and gives the caller the three channels back into a running VM: QMP, the serial console log and the AF_VSOCK READY notification.
Package qemu is the process-level VM runtime: it turns a Spec into the qemu-system-x86_64 argument list, starts and supervises the process, and gives the caller the three channels back into a running VM: QMP, the serial console log and the AF_VSOCK READY notification.
server
Package server assembles the single HTTP listener: health endpoints, the REST API, and the MCP streamable-HTTP endpoint (optionally behind OAuth).
Package server assembles the single HTTP listener: health endpoints, the REST API, and the MCP streamable-HTTP endpoint (optionally behind OAuth).
storage
Package storage hands out the disk volumes VMs boot from.
Package storage hands out the disk volumes VMs boot from.
tpm
Package tpm runs the software TPM behind each VM.
Package tpm runs the software TPM behind each VM.
varlink
Package varlink is a minimal Varlink client for the systemd services vm-manager talks to (io.systemd.StorageProvider today, io.systemd.Metrics later).
Package varlink is a minimal Varlink client for the systemd services vm-manager talks to (io.systemd.StorageProvider today, io.systemd.Metrics later).
varlink/varlinktest
Package varlinktest is an in-process fake Varlink service for tests, in the spirit of net/http/httptest.
Package varlinktest is an in-process fake Varlink service for tests, in the spirit of net/http/httptest.
vm
Package vm is the VM service: the lifecycle state machine, its persistence and the orchestration of storage, swtpm, the virtual network, the two QEMU boot phases and the metadata service (docs/design.md "Host architecture", "Boot flow").
Package vm is the VM service: the lifecycle state machine, its persistence and the orchestration of storage, swtpm, the virtual network, the two QEMU boot phases and the metadata service (docs/design.md "Host architecture", "Boot flow").
vm/vmtest
Package vmtest holds in-memory fakes of the host services behind vm.Service (runtime, swtpm, storage, networks, notify, image catalog) so the VM state machine and the API surfaces can be tested without QEMU.
Package vmtest holds in-memory fakes of the host services behind vm.Service (runtime, swtpm, storage, networks, notify, image catalog) so the VM state machine and the API surfaces can be tested without QEMU.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL