hook run command up to both wasi snapshots

sharing the same context! at long last
This commit is contained in:
Pat Hickey
2021-01-29 12:29:30 -08:00
parent 70f8288ec9
commit e498888732
4 changed files with 41 additions and 22 deletions

2
Cargo.lock generated
View File

@@ -2718,6 +2718,7 @@ name = "wasmtime-cli"
version = "0.22.0" version = "0.22.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cap-std",
"env_logger 0.8.2", "env_logger 0.8.2",
"file-per-thread-logger", "file-per-thread-logger",
"filecheck", "filecheck",
@@ -2733,6 +2734,7 @@ dependencies = [
"tempfile", "tempfile",
"test-programs", "test-programs",
"tracing-subscriber", "tracing-subscriber",
"wasi-cap-std-sync",
"wasi-common", "wasi-common",
"wasmparser", "wasmparser",
"wasmtime", "wasmtime",

View File

@@ -32,6 +32,7 @@ wasmtime-wast = { path = "crates/wast", version = "0.22.0" }
wasmtime-wasi = { path = "crates/wasi", version = "0.22.0" } wasmtime-wasi = { path = "crates/wasi", version = "0.22.0" }
wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "0.22.0", optional = true } wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "0.22.0", optional = true }
wasi-common = { path = "crates/wasi-common", version = "0.22.0" } wasi-common = { path = "crates/wasi-common", version = "0.22.0" }
wasi-cap-std-sync = { path = "crates/wasi-common/cap-std-sync", version = "0.22.0" }
structopt = { version = "0.3.5", features = ["color", "suggestions"] } structopt = { version = "0.3.5", features = ["color", "suggestions"] }
object = { version = "0.22.0", default-features = false, features = ["write"] } object = { version = "0.22.0", default-features = false, features = ["write"] }
anyhow = "1.0.19" anyhow = "1.0.19"
@@ -44,6 +45,7 @@ log = "0.4.8"
rayon = "1.2.1" rayon = "1.2.1"
humantime = "2.0.0" humantime = "2.0.0"
wasmparser = "0.71.0" wasmparser = "0.71.0"
cap-std = "0.11.0"
[dev-dependencies] [dev-dependencies]
env_logger = "0.8.1" env_logger = "0.8.1"

View File

@@ -25,6 +25,13 @@ impl WasiCtxBuilder {
let s = self.0.env(var, value)?; let s = self.0.env(var, value)?;
Ok(WasiCtxBuilder(s)) Ok(WasiCtxBuilder(s))
} }
pub fn envs(self, env: &[(String, String)]) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self;
for (k, v) in env {
s = s.env(k, v)?;
}
Ok(s)
}
pub fn inherit_env(self) -> Result<Self, wasi_common::StringArrayError> { pub fn inherit_env(self) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self.0; let mut s = self.0;
for (key, value) in std::env::vars() { for (key, value) in std::env::vars() {
@@ -36,6 +43,13 @@ impl WasiCtxBuilder {
let s = self.0.arg(arg)?; let s = self.0.arg(arg)?;
Ok(WasiCtxBuilder(s)) Ok(WasiCtxBuilder(s))
} }
pub fn args(self, arg: &[String]) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self;
for a in arg {
s = s.arg(&a)?;
}
Ok(s)
}
pub fn stdin(self, f: Box<dyn WasiFile>) -> Self { pub fn stdin(self, f: Box<dyn WasiFile>) -> Self {
WasiCtxBuilder(self.0.stdin(f)) WasiCtxBuilder(self.0.stdin(f))
} }

View File

@@ -2,18 +2,19 @@
use crate::{init_file_per_thread_logger, CommonOptions}; use crate::{init_file_per_thread_logger, CommonOptions};
use anyhow::{bail, Context as _, Result}; use anyhow::{bail, Context as _, Result};
use cap_std::fs::Dir;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use std::{ use std::{
ffi::{OsStr, OsString}, ffi::{OsStr, OsString},
fs::File,
path::{Component, PathBuf}, path::{Component, PathBuf},
process, process,
}; };
use structopt::{clap::AppSettings, StructOpt}; use structopt::{clap::AppSettings, StructOpt};
use wasi_common::{preopen_dir, WasiCtxBuilder}; use wasi_cap_std_sync::WasiCtxBuilder;
use wasmtime::{Engine, Func, Linker, Module, Store, Trap, Val, ValType}; use wasmtime::{Engine, Func, Linker, Module, Store, Trap, Val, ValType};
use wasmtime_wasi::Wasi; use wasmtime_wasi::snapshots::preview_0::Wasi as WasiSnapshot0;
use wasmtime_wasi::snapshots::preview_1::Wasi as WasiSnapshot1;
#[cfg(feature = "wasi-nn")] #[cfg(feature = "wasi-nn")]
use wasmtime_wasi_nn::{WasiNn, WasiNnCtx}; use wasmtime_wasi_nn::{WasiNn, WasiNnCtx};
@@ -139,7 +140,7 @@ impl RunCommand {
let argv = self.compute_argv(); let argv = self.compute_argv();
let mut linker = Linker::new(&store); let mut linker = Linker::new(&store);
populate_with_wasi(&mut linker, &preopen_dirs, &argv, &self.vars)?; populate_with_wasi(&mut linker, preopen_dirs, &argv, &self.vars)?;
// Load the preload wasm modules. // Load the preload wasm modules.
for (name, path) in self.preloads.iter() { for (name, path) in self.preloads.iter() {
@@ -195,20 +196,21 @@ impl RunCommand {
Ok(()) Ok(())
} }
fn compute_preopen_dirs(&self) -> Result<Vec<(String, File)>> { fn compute_preopen_dirs(&self) -> Result<Vec<(String, Dir)>> {
let mut preopen_dirs = Vec::new(); let mut preopen_dirs = Vec::new();
for dir in self.dirs.iter() { for dir in self.dirs.iter() {
preopen_dirs.push(( preopen_dirs.push((
dir.clone(), dir.clone(),
preopen_dir(dir).with_context(|| format!("failed to open directory '{}'", dir))?, unsafe { Dir::open_ambient_dir(dir) }
.with_context(|| format!("failed to open directory '{}'", dir))?,
)); ));
} }
for (guest, host) in self.map_dirs.iter() { for (guest, host) in self.map_dirs.iter() {
preopen_dirs.push(( preopen_dirs.push((
guest.clone(), guest.clone(),
preopen_dir(host) unsafe { Dir::open_ambient_dir(host) }
.with_context(|| format!("failed to open directory '{}'", host))?, .with_context(|| format!("failed to open directory '{}'", host))?,
)); ));
} }
@@ -340,23 +342,25 @@ impl RunCommand {
/// Populates the given `Linker` with WASI APIs. /// Populates the given `Linker` with WASI APIs.
fn populate_with_wasi( fn populate_with_wasi(
linker: &mut Linker, linker: &mut Linker,
preopen_dirs: &[(String, File)], preopen_dirs: Vec<(String, Dir)>,
argv: &[String], argv: &[String],
vars: &[(String, String)], vars: &[(String, String)],
) -> Result<()> { ) -> Result<()> {
let mk_cx = || { use std::cell::RefCell;
// Add the current snapshot to the linker. use std::rc::Rc;
let mut cx = WasiCtxBuilder::new();
cx.inherit_stdio().args(argv).envs(vars);
for (name, file) in preopen_dirs { // Add the current snapshot to the linker.
cx.preopened_dir(file.try_clone()?, name); let mut builder = WasiCtxBuilder::new();
} builder = builder.inherit_stdio().args(argv)?.envs(vars)?;
cx.build() for (name, dir) in preopen_dirs.into_iter() {
}; builder = builder.preopened_dir(dir, name)?;
let wasi = Wasi::new(linker.store(), mk_cx()?); }
wasi.add_to_linker(linker)?;
let cx = Rc::new(RefCell::new(builder.build()?));
WasiSnapshot1::new(linker.store(), cx.clone()).add_to_linker(linker)?;
WasiSnapshot0::new(linker.store(), cx).add_to_linker(linker)?;
#[cfg(feature = "wasi-nn")] #[cfg(feature = "wasi-nn")]
{ {
@@ -364,8 +368,5 @@ fn populate_with_wasi(
wasi_nn.add_to_linker(linker)?; wasi_nn.add_to_linker(linker)?;
} }
let wasi = wasmtime_wasi::old::snapshot_0::Wasi::new(linker.store(), mk_cx()?);
wasi.add_to_linker(linker)?;
Ok(()) Ok(())
} }