vmrunner 0.0.1

micro-vm runner for testcases that require root or invasive IO
Documentation
# vmrunner

A utility to enable running tests, or components of integration tests specifically, in a micro-vm.

## Host Requirements

* `mkosi` - create images from a rootfs
* `libkrunfw` - the linux kernel compiled as an `.so` / shared object
* `tap/tun` - support for overlay networks in your kernel

## The Magic

It takes `std::env::current_exe()` and uses a provided rootfs to execute the current process again inside the VM, mapping
the specific binary into the VM. To create an overlay network, we need to become root on the host, for which we use `unshare`.

A typical test uses `#[vmrunner::test(...)]` instead of `#[test]`. The macro builds a
`TestSetup` before calling the test body; VM harness code can then use the setup's per-test
system rootfs path when launching the guest.

```rust,no_run
use vmrunner::TestSetup;

#[vmrunner::test(system = "fedora")]
fn guest_smoke_test(setup: TestSetup) -> anyhow::Result<()> {
    assert_eq!(setup.test_name(), "guest_smoke_test");
    println!("guest rootfs: {}", setup.system_rootfs_path().display());

    // Launch the VM or prepare guest files using setup.system_rootfs_path().
    Ok(())
}
```

The generated wrapper is roughly equivalent to this expanded form:

```rust,no_run
use vmrunner::TestSetup;

fn __vmrunner_inner_guest_smoke_test(setup: TestSetup) -> anyhow::Result<()> {
    assert_eq!(setup.test_name(), "guest_smoke_test");
    println!("guest rootfs: {}", setup.system_rootfs_path().display());
    Ok(())
}

#[test]
fn guest_smoke_test() -> anyhow::Result<()> {
    if vmrunner::run_current_test_in_unshare_child("guest_smoke_test")
        .expect("vmrunner failed to run test in user+network namespace")
    {
        return Ok(());
    }

    let vmrunner_setup = TestSetup::new_with_isolated_system_rootfs(
        "guest_smoke_test",
        std::env!("KRUN_TEST_ROOTFS"),
    )
    .expect("vmrunner failed to create per-test system rootfs state directory");

    __vmrunner_inner_guest_smoke_test(vmrunner_setup)
}
```