supermachine 0.7.106

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-supermachine demo: spin up a microVM from a baked
    //! snapshot, send an HTTP request to its workload over the
    //! vsock-mux unix socket, print the response.
    //!
    //! Usage:
    //!
    //! ```sh
    //! # Bake the snapshot once via the CLI:
    //! supermachine run nginx:1.27-alpine --detach && supermachine run --stop
    //!
    //! # Then run this example pointing at the resulting snapshot:
    //! cargo run --release --example embed_simple -- \
    //!     ~/.local/supermachine-snapshots/nginx_1_27-alpine/restore.snap
    //! ```
    //!
    //! Required setup: this example's binary needs the HVF
    //! entitlement. The `cargo-supermachine` plugin handles it:
    //!
    //! ```sh
    //! cargo install supermachine
    //! cargo supermachine build --release --example embed_simple
    //! ```

    use std::io::{Read, Write};
    use std::time::Instant;

    use supermachine::{Image, Vm, VmConfig};

    pub(super) fn main() -> Result<(), Box<dyn std::error::Error>> {
        let snapshot_path = std::env::args()
            .nth(1)
            .ok_or("usage: embed_simple <snapshot-path>")?;

        let t0 = Instant::now();
        let image = Image::from_snapshot(&snapshot_path)?;
        let vm = Vm::start(&image, &VmConfig::new())?;
        eprintln!("vm started in {:?}", t0.elapsed());
        eprintln!("vsock path: {}", vm.vsock_path().display());

        // Send an HTTP request directly through the vsock-mux socket.
        // The bytes proxy through to the guest's TSI listener (typically
        // the workload's :80) — supermachine's vsock bridge is a
        // transparent byte pump.
        let mut sock = vm.connect()?;
        sock.write_all(
            b"GET / HTTP/1.1\r\n\
          Host: workload\r\n\
          Connection: close\r\n\
          \r\n",
        )?;
        let mut response = Vec::new();
        sock.read_to_end(&mut response)?;
        eprintln!("response: {} bytes", response.len());

        // Print the response status line + first few headers.
        let preview = String::from_utf8_lossy(&response);
        for line in preview.lines().take(6) {
            eprintln!("  {line}");
        }

        vm.stop()?;
        eprintln!("vm stopped after {:?}", t0.elapsed());
        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(())
}