supermachine 0.7.78

Run any OCI/Docker image as a hardware-isolated microVM on macOS HVF (Linux KVM and Windows WHP in progress). Single library API, zero flags for the common case, sub-100 ms cold-restore from snapshot.
Documentation
//! Validate the KVM bake host-side: turn OCI layer tarball(s) into a bootable
//! rootfs squashfs via `Image::bake_kvm`, boot it, and read a file from the
//! mounted OCI rootfs (`/dev/vda` → `/mnt` in the agent initramfs) — proving the
//! baked filesystem is correct + attached + mountable.
//!
//! Usage:
//!   kvm_bake <layer.tar>[,<layer2.tar>,...] <kernel> <agent_initrd> <dest_dir>
//!
//! The agent_initrd's init must mount /dev/vda at /mnt (squashfs).

#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
fn main() {
    use std::path::PathBuf;
    use std::time::Duration;
    let args: Vec<String> = std::env::args().collect();
    let src = args
        .get(1)
        .expect("usage: kvm_bake <layer.tar[,..] | ref:IMAGE> <kernel> <agent_initrd> <dest>");
    let kernel = PathBuf::from(args.get(2).expect("kernel arg"));
    let agent_initrd = PathBuf::from(args.get(3).expect("agent_initrd arg"));
    let dest = args.get(4).expect("dest arg");

    // `ref:alpine:3.20` pulls from a registry; otherwise comma-separated layer
    // tarballs.
    let image = if let Some(image_ref) = src.strip_prefix("ref:") {
        eprintln!("=== baking KVM image from registry ref {image_ref} ===");
        supermachine::Image::bake_kvm_from_ref(image_ref, &kernel, &agent_initrd, dest)
            .expect("bake_kvm_from_ref")
    } else {
        let layers: Vec<PathBuf> = src.split(',').map(PathBuf::from).collect();
        eprintln!(
            "=== baking KVM image from {} layer tar(s) ===",
            layers.len()
        );
        supermachine::Image::bake_kvm(&layers, &kernel, &agent_initrd, dest).expect("bake_kvm")
    };
    eprintln!("=== baked; starting VM ===");
    let vm = image
        .start(&supermachine::VmConfig::new())
        .expect("Image::start");
    std::thread::sleep(Duration::from_millis(6000));

    // Exec runs INSIDE the container (/ = the OCI rootfs), so read the image's
    // own /etc/os-release — no /mnt prefix.
    let out = vm
        .exec_builder()
        .argv(["/bin/cat", "/etc/os-release"])
        .output()
        .expect("exec cat");
    eprintln!(
        "=== IN-CONTAINER /etc/os-release: success={} contents={:?} ===",
        out.success(),
        String::from_utf8_lossy(&out.stdout).trim_end()
    );

    // Writability: the overlay's tmpfs upper makes the container rootfs writable.
    let w = vm
        .exec_builder()
        .argv([
            "/bin/sh",
            "-c",
            "echo sm-write-ok > /root/probe && cat /root/probe",
        ])
        .output()
        .expect("exec write");
    eprintln!(
        "=== IN-CONTAINER write test: success={} out={:?} ===",
        w.success(),
        String::from_utf8_lossy(&w.stdout).trim_end()
    );

    vm.stop().expect("stop");
    eprintln!("=== done ===");
}

#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
fn main() {
    eprintln!("kvm_bake is Linux/x86_64 only");
}