DarwinVmBackend — spike
Goal: run Elpe’s build/isolation on macOS in a VM (Virtualization.framework),
the modern replacement for nix-darwin’s weak sandbox-exec. Two guest kinds
are wanted:
- Linux guest — cross-build Linux images/binaries from a Mac (a primary use case), and hermetic isolation without Apple’s security theatre.
- macOS guest — build/sign macOS packages (2-VMs-max per host, IPSW restore); deferred.
What the spike proved (2026-08-03, on germaine, arm64 macOS 26)
vzspike.swift boots an Alpine Linux guest and streams its console to
stdout — reaching the initramfs userspace shell. This burns down the real
risks:
- Virtualization.framework is present and usable.
- The
com.apple.security.virtualizationentitlement works under an ad-hoc signature (codesign -s -), no paid Team ID / provisioning profile needed on a dev machine. - Our own binary can create + start a
VZVirtualMachine. - A Linux guest boots to userspace; the virtio console is captured.
The guest drops to the initramfs emergency shell only because we gave it
no root disk (kernel + initramfs only) — expected. Next increment: attach a
root disk (VZDiskImageStorageDeviceAttachment) or a virtiofs share of the
store (VZVirtioFileSystemDeviceConfiguration).
Recipe / gotchas
- Kernel format.
VZLinuxBootLoaderneeds an uncompressed arm64Image(magic41 52 4d 64= “ARM\x64” at offset 56). A distro’svmlinuzis a compressed / EFI-stub PE and fails to start with a genericVZErrorDomain Code=1 "Internal Virtualization error". Extract the raw Image (à la kernelscripts/extract-vmlinux): find the gzip magic1f 8b 08and pipe the tail throughgunzip(the CLI tolerates the trailing bytes the kernel appends; Python’s strictgzip.decompressdoes not). Alternatively useVZEFIBootLoader+ a bootable disk image, which offloads kernel handling to the guest’s own EFI — the likely path for a full build guest. - Entitlement. Sign with
--entitlements vz.entitlements; verify withcodesign -d --entitlements - vzspike. - Run loop.
VZVirtualMachineruns on the main queue; keepRunLoop.mainalive or nothing happens.
Fetching a test kernel
BASE=https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/aarch64/netboot
curl -fsSLO $BASE/vmlinuz-virt -o vmlinuz
curl -fsSLO $BASE/initramfs-virt -o initramfs
# then extract the uncompressed Image from vmlinuz (see gotchas)
Bindings decision
A thin Swift shim exposing a small C ABI, called from Rust via FFI —
rather than driving the verbose Virtualization ObjC API through objc2.
(ObjC is not deprecated, but VF is Swift-friendlier and we will want Swift
here regardless.) This spike is pure Swift; the C-ABI + Rust wrapper is the
next, low-risk step.