supermachine 0.5.5

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.
//! 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;

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(())
}