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 {
    //! Embed-vs-CLI perf comparison. Boots a 1-vcpu nginx via the
    //! library API, exposes guest:80 on host:8081, sits there until
    //! Ctrl-C. Compare wrk against this port vs port 8080 (CLI run).

    use std::sync::atomic::{AtomicBool, Ordering};
    use std::sync::Arc;
    use supermachine::{Image, VmConfig};

    pub(super) fn main() -> Result<(), Box<dyn std::error::Error>> {
        let snap = format!(
            "{}/.local/supermachine-snapshots/nginx_1v",
            std::env::var("HOME")?
        );
        let port: u16 = std::env::var("PORT")
            .ok()
            .and_then(|s| s.parse().ok())
            .unwrap_or(8081);

        let image = Image::from_snapshot(&snap)?;
        let vm = image.start(&VmConfig::new())?;
        let _fwd = vm.expose_tcp(port, 80)?;
        println!("listening on http://127.0.0.1:{port}/  (Ctrl-C to stop)");

        let stop = Arc::new(AtomicBool::new(false));
        let s = stop.clone();
        ctrlc_handler(move || s.store(true, Ordering::SeqCst));
        while !stop.load(Ordering::SeqCst) {
            std::thread::sleep(std::time::Duration::from_millis(200));
        }
        vm.stop()?;
        Ok(())
    }

    fn ctrlc_handler<F: FnMut() + Send + 'static>(mut cb: F) {
        unsafe {
            let mut sa: libc::sigaction = std::mem::zeroed();
            sa.sa_sigaction = sigint_handler as usize;
            libc::sigemptyset(&mut sa.sa_mask);
            sa.sa_flags = libc::SA_RESTART;
            libc::sigaction(libc::SIGINT, &sa, std::ptr::null_mut());
        }
        std::thread::spawn(move || loop {
            let n = SIGINT_COUNT.load(Ordering::SeqCst);
            if n > 0 {
                cb();
                return;
            }
            std::thread::sleep(std::time::Duration::from_millis(100));
        });
    }

    static SIGINT_COUNT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);

    extern "C" fn sigint_handler(_sig: libc::c_int) {
        SIGINT_COUNT.fetch_add(1, Ordering::SeqCst);
    }
}

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