You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
propolis currently only runs on Linux (KVM) and macOS (Hypervisor.framework) via libkrun. There is no Windows support. This issue tracks adding a Hyper-V backend to enable running OCI container images as microVMs on Windows.
Native Windows hypervisor — ships with Windows 10/11 Pro and Server editions
HCS (Host Compute Service) — well-maintained Go bindings via hcsshim, used by Docker Desktop and containerd
LCOW support — HCS natively supports Linux Containers on Windows (running Linux guests on Hyper-V)
No CGO required — hcsshim is pure Go, unlike the libkrun backend
Alternatives considered
Alternative
Why not
Hyperlight
No OS in guest, no filesystem, no networking, no OCI support, no Go SDK. Fundamentally different execution model (function sandbox, not container VM).
QEMU + WHPX
Too heavyweight. Full device emulation stack adds significant complexity and binary size.
WSL2 + KVM
KVM support in WSL2 is unreliable — works in some WSL versions, regressed in others. Not shippable.
Firecracker
Linux/KVM only, no Windows support.
Proposed Implementation
Backend: hypervisor/hyperv/
Implements the hypervisor.Backend interface from #1:
//go:build windowstypeBackendstruct {
// KernelPath is the path to the Linux kernel to boot.KernelPathstring// InitRDPath is the optional path to an initrd image.InitRDPathstring
}
func (b*Backend) Name() string { return"hyperv" }
func (b*Backend) PrepareRootFS(ctx context.Context, rootfsPathstring, initCfgInitConfig) (string, error) {
// 1. Write /.propolis_init.json to rootfs (generic init config)// 2. Convert flat rootfs directory to VHDX disk image// 3. Return path to VHDX
}
func (b*Backend) Start(ctx context.Context, cfgVMConfig) (VMHandle, error) {
// 1. Create LCOW utility VM via hcsshim// 2. Attach root VHDX// 3. Configure networking (hvsock transport)// 4. Add filesystem mounts (Plan 9 shares)// 5. Start VM// 6. Return hcsHandle wrapping uvm.UtilityVM
}
Key components
Rootfs → VHDX conversion
The OCI image extraction pipeline produces a flat directory. Hyper-V needs a VHDX disk image. Options to investigate:
virtdisk.dll Windows API (CreateVirtualDisk, AttachVirtualDisk)
hcsshim's internal LCOW layer utilities
diskpart / Convert-VHD PowerShell (fragile, last resort)
Networking: gvisor-tap-vsock over hvsock
gvisor-tap-vsock already supports Hyper-V socket transport (AF_HYPERV). The same virtual network stack used by libkrun's in-process networking can be reused with a different transport:
libkrun: AcceptQemu() over Unix socketpair
Hyper-V: AcceptHyperV() over hvsock
The NetEndpoint type from #1 carries the transport info:
Motivation
propolis currently only runs on Linux (KVM) and macOS (Hypervisor.framework) via libkrun. There is no Windows support. This issue tracks adding a Hyper-V backend to enable running OCI container images as microVMs on Windows.
Depends on: #1 (hypervisor abstraction layer)
Background
Why Hyper-V?
hcsshim, used by Docker Desktop and containerdAlternatives considered
Proposed Implementation
Backend:
hypervisor/hyperv/Implements the
hypervisor.Backendinterface from #1:Key components
Rootfs → VHDX conversion
The OCI image extraction pipeline produces a flat directory. Hyper-V needs a VHDX disk image. Options to investigate:
virtdisk.dllWindows API (CreateVirtualDisk, AttachVirtualDisk)diskpart/Convert-VHDPowerShell (fragile, last resort)Networking: gvisor-tap-vsock over hvsock
gvisor-tap-vsockalready supports Hyper-V socket transport (AF_HYPERV). The same virtual network stack used by libkrun's in-process networking can be reused with a different transport:AcceptQemu()over Unix socketpairAcceptHyperV()over hvsockThe
NetEndpointtype from #1 carries the transport info:Guest init
libkrun reads
/.krun_config.jsonvia its built-in init. Hyper-V needs a different mechanism:/.propolis_init.jsonwith the same schema ({cmd, env, working_dir})guest/bootpackage to read this config and exec the workloadLinux kernel
Unlike libkrun (which bundles a kernel in
libkrunfw), Hyper-V requires a separate kernel image. Options:Backend.KernelPathPlatform-specific files needed
hypervisor/hyperv/backend.gohypervisor/hyperv/handle.gouvm.UtilityVMhypervisor/hyperv/vhd.gohypervisor/default_windows.goDefaultBackendName = "hyperv"preflight/hyperv_windows.gopreflight/resources_windows.gointernal/procutil/process_windows.goQueryFullProcessImageNameextract/libname_windows.go.dllnaming conventionVM lifecycle
Unlike libkrun (where
krun_start_enter()takes over the process and never returns), Hyper-V manages VM lifecycle via API calls:No two-process model needed. No signals. No
Setsid. Pure API-driven lifecycle.Open Questions
guest/bootpackage, or build a separate init binary for Hyper-V guests?Implementation phases