supermachine 0.4.18

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.
//! Integration smoke for the v0.2 stable surface:
//!
//! - `Image::start` — one-shot VM
//! - `Vm::write_file` / `Vm::read_file`
//! - `ExecBuilder::output() -> ExecOutcome` with `.timeout()`
//!
//! ## Important: in-process VM cardinality
//!
//! macOS `hv_vm_create` is a process-wide singleton — one
//! embedding process can host **one** Vm at a time. To run
//! many VMs concurrently from a single Rust app, use the CLI's
//! pool (`supermachine-router --workers-per-snapshot N`) which
//! spawns separate worker subprocesses. A future v0.2.x will
//! make `Image::acquire` transparently spawn workers in the
//! same shape, so you'll write the same code and get N VMs.
//!
//! Usage:
//!
//! ```sh
//! supermachine run nginx:1.27-alpine --detach && supermachine run --stop
//! cargo run --release --example v02_surface
//! ```

use std::time::Duration;

use supermachine::{Image, VmConfig};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let snap_path = std::env::args().nth(1).unwrap_or_else(|| {
        format!(
            "{}/.local/supermachine-snapshots/nginx_1_27-alpine",
            std::env::var("HOME").unwrap()
        )
    });
    let image = Image::from_snapshot(&snap_path)?;

    println!("=== image.start() + write_file/read_file + timeout ===");
    let vm = image.start(&VmConfig::new())?;

    // 1. exec with output()
    let out = vm
        .exec_builder()
        .argv(["echo", "hello from start()"])
        .timeout(Duration::from_secs(5))
        .output()?;
    println!(
        "  echo: status={:?} duration={:?} peak_rss_kib={:?} stdout={:?}",
        out.status.code(),
        out.duration,
        out.peak_rss_kib,
        String::from_utf8_lossy(&out.stdout).trim_end()
    );

    // 2. write_file + read_file round-trip
    vm.write_file("/tmp/v02-test.txt", b"v0.2 surface works\n")?;
    let bytes = vm.read_file("/tmp/v02-test.txt")?;
    println!(
        "  write/read round-trip: {:?}",
        String::from_utf8_lossy(&bytes).trim_end()
    );

    // 3. timeout fires on a slow command
    let out = vm
        .exec_builder()
        .argv(["sh", "-c", "sleep 10; echo never"])
        .timeout(Duration::from_millis(500))
        .output()?;
    println!(
        "  timeout: timed_out={} duration={:?} status={:?}",
        out.timed_out,
        out.duration,
        out.status.code()
    );

    vm.stop()?;
    println!("OK");
    Ok(())
}