vmexec 0.7.1

Run a single command in a speedy virtual machine with zero-setup
Documentation
use std::time::Duration;

use color_eyre::Result;

use vmexec::{
    runner,
    types::{Interactive, Memory},
    utils::{VmexecDirs, find_required_tools},
    vms::reserve_vm,
};

#[tokio::main]
async fn main() -> Result<()> {
    let dirs = VmexecDirs::new()?;
    let tool_paths = find_required_tools()?;

    let reservation = reserve_vm(&dirs, None)?;
    let vmid = reservation.vmid.clone();

    // Run a VM in the background.
    let run_opts = runner::RunOptions {
        memory: Some(Memory { gb: 4 }),
        interactive: Interactive::Never,
        args: vec!["sleep".to_string(), "60".to_string()],
        rm: true,
        ..Default::default()
    };
    let _handle = tokio::spawn({
        let dirs = dirs.clone();
        async move { runner::prepare_and_run(&dirs, reservation, tool_paths, run_opts).await }
    });

    // Chill until the VM is actually ready.
    runner::check_ready(&dirs, &vmid, Some(Duration::from_secs(10))).await?;

    // Run a command in the already running VM and capture its output.
    let exec_opts = runner::ExecOpts {
        interactive: Interactive::Never,
        args: vec!["echo".to_string(), "hello from inside the VM".to_string()],
        ..Default::default()
    };
    let output = runner::exec_in_running_vm(&dirs, &vmid, exec_opts).await?;

    if let Some(output) = output {
        println!("exit code: {}", output.exit_code);
        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    }

    Ok(())
}