vm-manager

command module
v0.10.0 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
Per-VM metrics: host (state, attestation, QEMU cpu_seconds and memory_rss_bytes, disk_bytes, install_seconds, boot_to_ready_seconds, the network's byte counters) and guest (summary of the last systemd-report upload, null until one arrived) GET /api/v1/vms/{id}/metrics get_vm_metrics no
The guest's last systemd-report upload in full (REST only: too large for a tool result) GET /api/v1/vms/{id}/report — 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.

Metrics

GET /metrics is the Prometheus exposition (--metrics-enabled, default on). It is served outside the OAuth guard like the probes, because scrapers do not run OAuth flows and the exposition holds no secrets; firewall the path or disable it when that is not acceptable. Host side, per VM: vm_manager_vm_state{vm,name,state} (1/0), vm_manager_vm_attestation, vm_manager_vm_info, vm_manager_vm_install_seconds, vm_manager_vm_boot_to_ready_seconds (plus _duration_seconds histograms), vm_manager_vm_cpu_seconds_total and vm_manager_vm_memory_rss_bytes of the QEMU process, vm_manager_vm_disk_bytes; per network vm_manager_network_bytes_total{network,direction} and vm_manager_network_leases; vm_manager_vms{state} and vm_manager_build_info. Guest side, every entry of the guest's last systemd-report upload becomes a series: io.systemd.Manager.UnitActiveState for sshd.service is vm_guest_io_systemd_manager_unit_active_state_info{vm,object="sshd.service",value="active"} 1, io.systemd.Manager.NRestarts is vm_guest_io_systemd_manager_nrestarts_total{vm,object}, the entry's fields are labels. Each upload replaces the previous one; at most --metrics-guest-series-limit series (default 1000) are kept per VM, the rest are counted in vm_guest_report_series_dropped_total{vm,reason}; vm_guest_report_age_seconds says how stale a guest's data is. internal/metrics documents the mapping and the cardinality policy.

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.
cmd
Package cmd holds the vm-manager CLI.
Package cmd holds the vm-manager CLI.
vm-agent command
vm-agent is the guest binary of vm-manager's attestation protocol (docs/design.md "Boot flow" steps 5 and 7).
vm-agent is the guest binary of vm-manager's attestation protocol (docs/design.md "Boot flow" steps 5 and 7).
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
agent
Package agent runs the guest side of the attestation protocol (docs/design.md "Attestation protocol"): fetch a nonce from the IMDS, have a quote built over it and post the quote.
Package agent runs the guest side of the attestation protocol (docs/design.md "Attestation protocol"): fetch a nonce from the IMDS, have a quote built over it and post the quote.
agent/quote
Package quote builds the TPM 2.0 quote the guest agent posts to the IMDS (docs/design.md "Attestation protocol").
Package quote builds the TPM 2.0 quote the guest agent posts to the IMDS (docs/design.md "Attestation protocol").
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).
metrics
Package metrics is the Prometheus registry of vm-manager: host-side metrics about every VM and the metrics the guests upload with systemd-report, served on /metrics and summarized per VM for get_vm_metrics.
Package metrics is the Prometheus registry of vm-manager: host-side metrics about every VM and the metrics the guests upload with systemd-report, served on /metrics and summarized per VM for get_vm_metrics.
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 Prometheus exposition, the REST API, and the MCP streamable-HTTP endpoint (the latter two optionally behind OAuth).
Package server assembles the single HTTP listener: health endpoints, the Prometheus exposition, the REST API, and the MCP streamable-HTTP endpoint (the latter two 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