supermachine 0.5.0

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.
//! Time each phase of with_warmup bake.

use std::time::{Duration, Instant};
use supermachine::Image;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Wipe any cache for this name.
    let warm_dir = format!(
        "{}/.local/supermachine-snapshots/rust_1_slim__warm__timing",
        std::env::var("HOME")?
    );
    let _ = std::fs::remove_dir_all(&warm_dir);

    let _ = std::fs::remove_dir_all(format!(
        "{}/.local/supermachine-snapshots/rust_1_slim",
        std::env::var("HOME")?
    ));
    let _ = std::fs::remove_dir_all(format!(
        "{}/.local/supermachine-layer-cache/deltas",
        std::env::var("HOME")?
    ));

    let t_total = Instant::now();
    let t_builder = Instant::now();
    let image = Image::builder("rust:1-slim")
        .with_name("rust_1_slim")
        .with_memory_mib(2048)
        .with_warmup(|vm| {
            let t = Instant::now();
            vm.exec_builder()
                .stage_file(
                    "/tmp/seed.rs",
                    b"fn main() { println!(\"warm\"); }".to_vec(),
                )
                .argv(["rustc", "-O", "/tmp/seed.rs", "-o", "/tmp/seed"])
                .chain(["/tmp/seed"])
                .timeout(Duration::from_secs(60))
                .output()?;
            eprintln!("[warmup-closure] rustc + run: {:?}", t.elapsed());
            Ok(())
        })
        .with_warmup_tag("timing")
        .build()?;
    eprintln!("[builder.build] total: {:?}", t_builder.elapsed());

    // Use the warm-baked image
    let t_pool = Instant::now();
    let pool = image
        .pool()
        .min(1)
        .max(1)
        .restore_on_release(false)
        .build()?;
    eprintln!("[pool.build] {:?}", t_pool.elapsed());

    let t_acq = Instant::now();
    let vm = pool.acquire()?;
    eprintln!("[first acquire] {:?}", t_acq.elapsed());

    let t_cyc = Instant::now();
    let _ = vm
        .exec_builder()
        .stage_file("/tmp/main.rs", b"fn main() { println!(\"hi\"); }".to_vec())
        .argv(["rustc", "-O", "/tmp/main.rs", "-o", "/tmp/m"])
        .chain(["/tmp/m"])
        .timeout(Duration::from_secs(60))
        .output()?;
    eprintln!("[first cycle] {:?}", t_cyc.elapsed());

    eprintln!("[total wall] {:?}", t_total.elapsed());
    Ok(())
}