sausage-vfs: layers (host, memory, generated, mounts), process guards, wasi:filesystem adapter

Checkpoint. More tests and the review findings follow.
This commit is contained in:
2026-10-23 00:08:02 +01:00
parent 01712e745a
commit 0a479b5800
15 changed files with 1932 additions and 1 deletions
+94
View File
@@ -0,0 +1,94 @@
//! Compiles a real WASIp2 guest and runs std, SQLite, and tempfile through the adapter.
use sausage_vfs::{
adapter::{self, Adapter, View},
*,
};
use std::sync::Arc;
use wasmtime::{
Engine, Store,
component::{Component, Linker, ResourceTable},
};
use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiCtxView, WasiView};
struct State {
wasi: WasiCtx,
table: ResourceTable,
fs: Adapter,
}
impl WasiView for State {
fn ctx(&mut self) -> WasiCtxView<'_> {
WasiCtxView {
ctx: &mut self.wasi,
table: &mut self.table,
}
}
}
#[tokio::test(flavor = "multi_thread")]
async fn rust_guest() {
let manifest =
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/guests/files/Cargo.toml");
let target = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../target/vfs/guests");
let status = std::process::Command::new("cargo")
.args([
"build",
"--release",
"--locked",
"--offline",
"--target",
"wasm32-wasip2",
"--manifest-path",
])
.arg(manifest)
.env("CARGO_TARGET_DIR", &target)
.status()
.unwrap();
assert!(status.success());
let world = tempfile::tempdir().unwrap();
std::fs::create_dir(world.path().join("tmp")).unwrap();
let mut mounts = Mounts::default();
mounts.mount(
"/",
Arc::new(Host::new(world.path(), Process::default()).unwrap()),
false,
);
mounts.mount("/run", Arc::new(Memory::default()), false);
mounts.mount("/self", Arc::new(Memory::default()), false);
let mut generated = Generated::default();
generated.insert("/value", || Ok(b"snapshot".to_vec()));
mounts.mount("/proc", Arc::new(generated), true);
let engine = Engine::default();
let mut linker = Linker::new(&engine);
wasmtime_wasi::p2::add_to_linker_async(&mut linker).unwrap();
adapter::add_to_linker(&mut linker, |s: &mut State| View {
adapter: &mut s.fs,
table: &mut s.table,
})
.unwrap();
let component = Component::from_file(
&engine,
target.join("wasm32-wasip2/release/vfs-files-guest.wasm"),
)
.unwrap();
let mut store = Store::new(
&engine,
State {
wasi: WasiCtxBuilder::new()
.inherit_stdio()
.env("TMPDIR", "/tmp")
.build(),
table: ResourceTable::new(),
fs: Adapter::new(mounts),
},
);
let command =
wasmtime_wasi::p2::bindings::Command::instantiate_async(&mut store, &component, &linker)
.await
.unwrap();
assert!(
command
.wasi_cli_run()
.call_run(&mut store)
.await
.unwrap()
.is_ok()
);
}