Skip to main content

Crate virtx

Crate virtx 

Source
Expand description

§Virtx

Run tasks in disposable Linux VMs from your own code: what a task reads, and what it runs.

Both are ordinary on purpose: a script, a build or a model handed a filesystem and a shell already knows both interfaces, and every added capability arrives as a file to read or a command to run.

  • What it reads is a filesystem, with cat, grep or anything else once a binding mounts it on the host.
  • What it runs is commands, each an argv sent over one channel, with everything the command wrote coming back.

§Quickstart

Needs the mount feature. On Linux the binding is FuseMount; macOS uses FuseTMount and Windows DokanMount, with nothing else changed.

ⓘ
use std::path::Path;

use virtx::console::ConsoleClient;
use virtx::fs::{Directory, FuseMount};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // What the task reads: an in-memory file beside a host directory.
    let context = Directory::new()
        .with_file("notes/today.md", "ship the release".as_bytes())?
        .with_mount("project", "/home/me/project")?;

    // Constructing the guard mounts, dropping it unmounts; the console holds it for the session.
    let mount = FuseMount::try_new(context, Path::new("/tmp/session"))?;

    // What the task runs. A session's shape, including where each tree appears to
    // commands, is fixed when the console is built.
    let mut console = ConsoleClient::builder()
        .mount(mount, "/work")
        .build()
        .await?;

    let result = console.exec(["sh", "-c", "wc -w /work/notes/today.md"], None).await?;
    println!("{}", String::from_utf8_lossy(&result.stdout));
    Ok(())
}

§Structure

  • fs: what a session reads and writes. Stores, the in-memory Directory, and the bindings that mount them on the host.
  • console: what a session runs. ConsoleClient runs commands in a session, which Relay shares with another native module in the same process (ailoy’s, say).
  • protocol: the wire between a console client and a console server. The server is a prebuilt binary, virtx-uvm, that ensure_virtx fetches into the cache’s bin.
  • image: the images a session runs on, declared or built ahead of time.

fs and console meet only at Mount: a console takes trees already mounted and never builds one or touches a binding, and fs does not know a console exists. There is no shared error type: fs answers in std::io::Error, classified by kind, and console in Failure, or anyhow::Error while building.

§The file layout

A module with submodules is a directory whose mod.rs holds its documentation and re-exports, and whose siblings hold the code, including one named after the module for its main type (message/message.rs has Message); hence module_inception is allowed.

Modules§

console
The public end: a console server to run commands in, over one channel.
fs
Trees a store describes in-process, and trees the operating system has mounted.
image
Images a session runs on: declared as a Recipe, named by ImageSource, or built ahead of a session with ImageClient.
protocol
The two ends of a console, and the wire between them.

Functions§

cache_root
Everything virtx keeps on this host, under one root: $VIRTX_HOME, or virtx under the user’s cache directory.
ensure_virtx
Fetch the console server into cache_root/bin if absent, and return that directory.

Type Aliases§

BoxFuture
What every waiting method of a Client or Server returns.