supermachine 0.7.104

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 {
    //! Embedded VM exposed as a normal localhost TCP service.
    //!
    //! ```sh
    //! supermachine bundle --into /tmp/my-bundles --image nginx:1.27-alpine
    //! cargo supermachine build --release --example tcp_forward
    //! target/release/examples/tcp_forward /tmp/my-bundles/nginx_1_27-alpine 9090
    //! curl http://127.0.0.1:9090/
    //! ```
    //!
    //! Compared to `bundle_load`: instead of the embedder driving
    //! `vm.connect()` directly, the library binds a TCP listener and
    //! forwards every accepted connection to the guest. The embedder's
    //! own users / threads / HTTP clients see a normal localhost
    //! service.

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

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

    pub(super) fn main() -> Result<(), Box<dyn std::error::Error>> {
        let bundle_dir = std::env::args()
            .nth(1)
            .ok_or("usage: tcp_forward <BUNDLE_DIR> [HOST_PORT]")?;
        let host_port: u16 = std::env::args()
            .nth(2)
            .map(|s| s.parse())
            .transpose()?
            .unwrap_or(0);

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

        let fwd = vm.expose_tcp(host_port, 80)?;
        eprintln!("listening on {} → guest", fwd.local_addr());

        // Self-test: hit our own listener like a normal HTTP client.
        let mut tcp = TcpStream::connect(fwd.local_addr())?;
        tcp.set_read_timeout(Some(Duration::from_secs(2)))?;
        tcp.write_all(b"GET / HTTP/1.1\r\nHost: workload\r\nConnection: close\r\n\r\n")?;
        let mut response = Vec::new();
        tcp.read_to_end(&mut response)?;
        let preview = String::from_utf8_lossy(&response);
        for line in preview.lines().take(4) {
            eprintln!("  {line}");
        }

        drop(fwd); // stop accepting new conns
        vm.stop()?;
        eprintln!("done in {:?}", 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(())
}