Daemon
Go
The VM Registry Daemon (vm-registry-daemon) is the central orchestrator running on each host machine. It exposes a gRPC service over a Unix domain socket and manages all local VM operations — image storage, VM lifecycle through libvirt, virtual networking, VMCompose orchestration, and communication with the remote registry and auth servers.
Overview
The daemon is the bridge between the user-facing CLI and the underlying infrastructure. It receives gRPC requests from the CLI, translates them into libvirt API calls, filesystem operations, and HTTP requests to remote servers, then returns structured responses.
CLI ──gRPC/Unix Socket──► Daemon ──libvirt API──► QEMU/KVM
│
├──HTTP──► Registry Server
├──HTTP──► Auth Server
└──Filesystem/S3──► Image StoreRunning the Daemon
cd vm-registry-daemon
go run server/main.go [FLAGS]Configuration Flags
| Flag | Env Variable | Default | Description |
|---|---|---|---|
-socket | VM_REGISTRY_SOCKET_PATH | /var/run/vm-registry.sock | Unix socket path for gRPC |
-registry-url | VM_REGISTRY_SERVER_URL | — | Remote registry server URL |
-auth-url | VM_AUTH_SERVER_URL | — | Remote auth server URL |
-storage | — | filesystem | Storage backend: filesystem or s3 |
-fs-path | VM_REGISTRY_STORAGE_PATH | /var/lib/vm-registry | Local filesystem storage path |
-log-level | VM_REGISTRY_LOG_LEVEL | info | Log verbosity level |
-s3-bucket | — | — | S3 bucket name |
-s3-region | — | us-east-1 | S3 region |
-s3-endpoint | — | — | S3-compatible endpoint URL |
-s3-access-key | AWS_ACCESS_KEY_ID | — | S3 access key |
-s3-secret-key | AWS_SECRET_ACCESS_KEY | — | S3 secret key |
-s3-skip-bucket-creation | — | false | Skip automatic bucket creation |
Examples
go run server/main.go \
-socket /tmp/vm-registry-daemon.sock \
-registry-url http://127.0.0.1:8080 \
-auth-url http://127.0.0.1:4078
go run server/main.go \
-storage s3 \
-s3-bucket vm-images \
-s3-endpoint http://127.0.0.1:9000 \
-s3-access-key admin \
-s3-secret-key adminInternal Structure
The daemon is organized into the following internal packages:
| Package | Responsibility |
|---|---|
internal/service | gRPC service implementations — one file per domain (auth, compose, context, images, vm, network, etc.) |
internal/libvirt | Libvirt wrapper — domain creation, network management, bridge configuration, cloud-init ISO generation, disk handling |
internal/vmfile | VMFile parser and validator — parses YAML, resolves paths, validates schema |
internal/vmcompose | VMCompose parser and validator — parses multi-VM compose files, validates structure |
internal/storage | Storage interface definition for pluggable backends |
internal/config | Configuration loading from flags and environment variables |
internal/client | HTTP client for communicating with the registry and auth servers |
internal/proto | Generated gRPC/protobuf Go code |
internal/logs | Structured logging with gRPC interceptors |
internal/utils | Shared utility functions |
gRPC Service
The daemon implements the VMService gRPC service defined in vm-registry-proto. The service is registered on a Unix domain socket with reflection enabled for debugging with tools like grpcurl.
The gRPC server is configured with:
- 4 GiB max message size for both send and receive — necessary for streaming large disk images during import
- Unary interceptor for request/response logging
- Stream interceptor for streaming call logging
Libvirt Integration
The daemon uses the libvirt.org/go/libvirt and libvirt.org/go/libvirtxml Go bindings for direct interaction with the libvirt hypervisor API. Key capabilities include:
Domain Management
- Creating libvirt domains from image specs (CPU, memory, bootloader, disk)
- Starting, stopping (graceful ACPI shutdown or forced destroy), restarting, and undefining domains
- Listing running and defined domains with resource and status information
Network Management
- Creating virtual networks in all supported modes: NAT, isolated, routed, bridged, open, and macvtap
- Activating, deactivating, and deleting networks
- Bridge interface configuration for bridged networking
- DHCP range configuration for NAT and isolated networks
Cloud-Init
- Generating cloud-init ISO images from user-data, meta-data, and network-config sources
- Attaching cloud-init ISOs to VM domains for guest provisioning at first boot
Disk Management
- Creating overlay disks (copy-on-write) for ephemeral VM storage
- Resizing disk images when
diskSizeoverrides are specified in VMCompose services
Image Storage
The daemon stores images locally in a content-addressable layout:
/var/lib/vm-registry/
├── manifests/
│ └── <repository>/
│ └── <tag>/
│ └── manifest.json
├── blobs/
│ └── sha256/
│ └── <digest>
└── runtime/
└── <vm-name>/- manifests/ — Image manifests indexed by repository and tag, containing references to content-addressed blobs
- blobs/ — Content-addressed storage for disk images and configuration blobs, keyed by SHA-256 digest
- runtime/ — Ephemeral state for running VMs (cloud-init ISOs, overlay disks)
VMFile Processing
When a vmr import command is received, the daemon:
- Receives the VMFile metadata and disk image chunks over a gRPC stream
- Parses and validates the VMFile YAML structure
- Computes the SHA-256 digest of the disk image
- Stores the disk image blob in content-addressable storage
- Creates an image configuration blob from the VMFile spec
- Generates a manifest referencing both blobs
- Stores the manifest under the specified repository and tags
VMCompose Orchestration
When a vmr compose up command is received, the daemon:
- Parses and validates the VMCompose YAML
- Creates any networks defined in the
networkssection that don't already exist - Resolves the service dependency graph using topological sorting
- For each service in dependency order:
- Resolves the image reference to a local manifest
- Applies resource overrides (CPU, memory, disk size)
- Loads cloud-init configuration (inline or from files)
- Creates and starts a libvirt domain with the appropriate network attachments
- Returns the status of all services
Dependencies
| Dependency | Purpose |
|---|---|
google.golang.org/grpc | gRPC server framework |
google.golang.org/protobuf | Protocol Buffer runtime |
gopkg.in/yaml.v3 | YAML parsing for VMFile and VMCompose |
libvirt.org/go/libvirt | Libvirt C API bindings |
libvirt.org/go/libvirtxml | Libvirt XML domain/network generation |
aws-sdk-go-v2 | S3 storage backend |