supermachine 0.7.107

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
//! Verification harness for supermachine-vm PR #40 / issue #39.
//! Boots one nginx:alpine KVM VM, stamps a distinct index.html via exec,
//! exposes a host-port forward to guest port 80, prints READY, then holds.
//! Two of these run concurrently (in separate pid namespaces sharing one
//! TMPDIR) to reproduce the mux-socket collision that severs/hijacks the
//! first VM's forward.

fn main() {
    let mut args = std::env::args().skip(1);
    let snap = args
        .next()
        .expect("usage: two_vm_probe <snapshot-dir> <host-port> <guest-port> <hold-secs> <tag>");
    let host_port: u16 = args
        .next()
        .expect("host port")
        .parse()
        .expect("host port u16");
    let guest_port: u16 = args
        .next()
        .expect("guest port")
        .parse()
        .expect("guest port u16");
    let hold_secs: u64 = args
        .next()
        .expect("hold secs")
        .parse()
        .expect("hold secs u64");
    let tag = args.next().unwrap_or_else(|| "vm".to_string());

    eprintln!(
        "[{tag}] pid={} tmpdir={}",
        std::process::id(),
        std::env::temp_dir().display()
    );

    let image = supermachine::Image::from_snapshot(&snap).expect("Image::from_snapshot");
    let vm = supermachine::Vm::start(&image, &supermachine::VmConfig::new()).expect("Vm::start");
    std::thread::sleep(std::time::Duration::from_secs(2));

    let script = format!("echo hello-{tag} > /usr/share/nginx/html/index.html && echo ok");
    let outcome = vm
        .exec_builder()
        .argv(vec!["sh".to_string(), "-c".to_string(), script])
        .timeout(std::time::Duration::from_secs(20))
        .output()
        .expect("exec stamp");
    eprintln!(
        "[{tag}] stamp exec: status={:?} stdout={}",
        outcome.status,
        String::from_utf8_lossy(&outcome.stdout).trim()
    );

    let fwd = vm.expose_tcp(host_port, guest_port).expect("expose_tcp");
    println!(
        "READY {tag} pid={} host_port={} local_addr={}",
        std::process::id(),
        host_port,
        fwd.local_addr()
    );
    std::thread::sleep(std::time::Duration::from_secs(hold_secs));
    println!("DONE {tag}");
    drop(fwd);
    drop(vm);
}