supermachine 0.7.108

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
#[cfg(any(
    all(target_os = "linux", target_arch = "x86_64"),
    all(target_os = "macos", target_arch = "aarch64")
))]
mod supported {
    //! Prepare the snapshots `_axis_bench` and the comparison harness need.
    //! Idempotent — skips snapshots that already exist at the expected path.
    //! Run once before the bench suite.

    use std::time::Duration;
    use supermachine::Image;

    pub(super) fn main() -> Result<(), Box<dyn std::error::Error>> {
        let home = std::env::var("HOME")?;
        let snap_dir = format!("{home}/.local/supermachine-snapshots");

        let needed = [
            ("rust_1_slim", "rust:1-slim", 1u32, false),
            ("rust_1_slim_4vcpu", "rust:1-slim", 4u32, false),
            ("rust_1_slim__warm__rustc_v1", "rust:1-slim", 1u32, true),
            ("nginx_1v", "nginx:alpine", 1u32, false),
        ];

        for (name, image_ref, vcpus, warm_rustc) in needed {
            let path = format!("{snap_dir}/{name}");
            if std::path::Path::new(&path).is_dir()
            && std::path::Path::new(&format!("{path}/restore.snap")).is_file()
            // Try loading; if it fails (e.g. v8 format) we re-bake.
            && Image::from_snapshot(&path).is_ok()
            {
                eprintln!("[prep] {name}: already baked, skip");
                continue;
            }
            eprintln!(
                "[prep] {name}: baking {image_ref} (vcpus={vcpus}, warm_rustc={warm_rustc})…"
            );
            let t0 = std::time::Instant::now();
            let mut b = Image::builder(image_ref)
                .with_name(name)
                .with_memory_mib(if warm_rustc { 2048 } else { 512 })
                .with_vcpus(vcpus);
            if warm_rustc {
                // Warm path: pre-compile a hello.rs once during the bake so
                // the rustc-cycle benchmark hits with rustc's caches hot
                // (filesystem dentries / page cache / etc.).
                b = b
                    .with_warmup(|vm| {
                        vm.exec_builder()
                            .stage_file("/tmp/hello.rs", b"fn main(){println!(\"hi\");}".to_vec())
                            .argv(["rustc", "-O", "/tmp/hello.rs", "-o", "/tmp/h"])
                            .timeout(Duration::from_secs(120))
                            .output()?;
                        Ok(())
                    })
                    .with_warmup_tag("rustc_v1");
            }
            let _ = b.build()?;
            eprintln!("[prep] {name}: baked in {:.1}s", t0.elapsed().as_secs_f32());
        }
        eprintln!("[prep] done");
        Ok(())
    }
}

#[cfg(any(
    all(target_os = "linux", target_arch = "x86_64"),
    all(target_os = "macos", target_arch = "aarch64")
))]
fn main() -> Result<(), Box<dyn std::error::Error>> {
    supported::main()
}

#[cfg(not(any(
    all(target_os = "linux", target_arch = "x86_64"),
    all(target_os = "macos", target_arch = "aarch64")
)))]
fn main() -> Result<(), Box<dyn std::error::Error>> {
    eprintln!("this example requires a linux-x86_64 (KVM) or macos-aarch64 (HVF) host; unsupported on this platform");
    Ok(())
}