mirror of
https://github.com/extism/extism.git
synced 2026-01-11 14:58:01 -05:00
Compare commits
4 Commits
externref-
...
wasi-reado
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ff515d3a0 | ||
|
|
10ee81952b | ||
|
|
fb3c131a1e | ||
|
|
9e586a36d9 |
@@ -249,7 +249,13 @@ pub struct Manifest {
|
||||
#[serde(default)]
|
||||
pub allowed_paths: Option<BTreeMap<PathBuf, PathBuf>>,
|
||||
|
||||
/// The plugin timeout, by default this is set to 30s
|
||||
/// Specifies which paths should be made for reading only when using WASI. This is a mapping from
|
||||
/// the path on disk to the path it should be available inside the plugin.
|
||||
/// For example, `".": "/tmp"` would mount the current directory as `/tmp` inside the module
|
||||
#[serde(default)]
|
||||
pub allowed_paths_readonly: Option<BTreeMap<PathBuf, PathBuf>>,
|
||||
|
||||
/// The plugin timeout
|
||||
#[serde(default)]
|
||||
pub timeout_ms: Option<u64>,
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
wasmtime = ">= 14.0.0, < 18.0.0"
|
||||
wasmtime-wasi = ">= 14.0.0, < 18.0.0"
|
||||
wasmtime = ">= 18.0.0, < 19.0.0"
|
||||
wasmtime-wasi = ">= 18.0.0, < 19.0.0"
|
||||
anyhow = "1"
|
||||
serde = {version = "1", features = ["derive"]}
|
||||
serde_json = "1"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use wasmtime::component::ResourceTable;
|
||||
use wasmtime_wasi::preview2::{preview1::WasiPreview1Adapter, DirPerms, FilePerms};
|
||||
|
||||
use crate::*;
|
||||
|
||||
/// CurrentPlugin stores data that is available to the caller in PDK functions, this should
|
||||
@@ -18,6 +21,7 @@ pub struct CurrentPlugin {
|
||||
}
|
||||
|
||||
unsafe impl Send for CurrentPlugin {}
|
||||
unsafe impl Sync for CurrentPlugin {}
|
||||
|
||||
pub(crate) struct MemoryLimiter {
|
||||
bytes_left: usize,
|
||||
@@ -289,24 +293,62 @@ impl CurrentPlugin {
|
||||
) -> Result<Self, Error> {
|
||||
let wasi = if wasi {
|
||||
let auth = wasmtime_wasi::ambient_authority();
|
||||
let mut ctx = wasmtime_wasi::WasiCtxBuilder::new();
|
||||
for (k, v) in manifest.config.iter() {
|
||||
ctx.env(k, v)?;
|
||||
}
|
||||
let mut ctx = wasmtime_wasi::preview2::WasiCtxBuilder::new();
|
||||
ctx.allow_ip_name_lookup(true);
|
||||
ctx.allow_tcp(true);
|
||||
ctx.allow_udp(true);
|
||||
|
||||
if let Some(a) = &manifest.allowed_paths {
|
||||
for (k, v) in a.iter() {
|
||||
let d = wasmtime_wasi::Dir::open_ambient_dir(k, auth)?;
|
||||
ctx.preopened_dir(d, v)?;
|
||||
if k.as_path().is_dir() {
|
||||
let d = wasmtime_wasi::Dir::open_ambient_dir(k, auth)?;
|
||||
ctx.preopened_dir(
|
||||
d,
|
||||
DirPerms::READ | DirPerms::MUTATE,
|
||||
FilePerms::READ | FilePerms::WRITE,
|
||||
v.to_string_lossy(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(a) = &manifest.allowed_paths_readonly {
|
||||
for (k, v) in a.iter() {
|
||||
if k.as_path().is_dir() {
|
||||
let d = wasmtime_wasi::Dir::open_ambient_dir(k, auth)?;
|
||||
ctx.preopened_dir(d, DirPerms::READ, FilePerms::READ, v.to_string_lossy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(h) = &manifest.allowed_hosts {
|
||||
let h = h.clone();
|
||||
ctx.socket_addr_check(move |addr, _kind| {
|
||||
for host in h.iter() {
|
||||
let addrs = std::net::ToSocketAddrs::to_socket_addrs(&host);
|
||||
if let Ok(addrs) = addrs {
|
||||
for a in addrs.into_iter() {
|
||||
if addr == &a {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
});
|
||||
}
|
||||
|
||||
// Enable WASI output, typically used for debugging purposes
|
||||
if std::env::var("EXTISM_ENABLE_WASI_OUTPUT").is_ok() {
|
||||
ctx.inherit_stdout().inherit_stderr();
|
||||
}
|
||||
|
||||
Some(Wasi { ctx: ctx.build() })
|
||||
Some(Wasi {
|
||||
ctx: ctx.build(),
|
||||
preview2_table: ResourceTable::new(),
|
||||
preview1_adapter: WasiPreview1Adapter::new(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
@@ -3,7 +3,29 @@ use crate::*;
|
||||
/// WASI context
|
||||
pub struct Wasi {
|
||||
/// wasi
|
||||
pub ctx: wasmtime_wasi::WasiCtx,
|
||||
pub ctx: wasmtime_wasi::preview2::WasiCtx,
|
||||
pub preview2_table: wasmtime::component::ResourceTable,
|
||||
pub preview1_adapter: wasmtime_wasi::preview2::preview1::WasiPreview1Adapter,
|
||||
}
|
||||
|
||||
impl wasmtime_wasi::preview2::WasiView for CurrentPlugin {
|
||||
fn table(&mut self) -> &mut wasmtime::component::ResourceTable {
|
||||
&mut self.wasi.as_mut().unwrap().preview2_table
|
||||
}
|
||||
|
||||
fn ctx(&mut self) -> &mut wasmtime_wasi::preview2::WasiCtx {
|
||||
&mut self.wasi.as_mut().unwrap().ctx
|
||||
}
|
||||
}
|
||||
|
||||
impl wasmtime_wasi::preview2::preview1::WasiPreview1View for CurrentPlugin {
|
||||
fn adapter(&self) -> &wasmtime_wasi::preview2::preview1::WasiPreview1Adapter {
|
||||
&self.wasi.as_ref().unwrap().preview1_adapter
|
||||
}
|
||||
|
||||
fn adapter_mut(&mut self) -> &mut wasmtime_wasi::preview2::preview1::WasiPreview1Adapter {
|
||||
&mut self.wasi.as_mut().unwrap().preview1_adapter
|
||||
}
|
||||
}
|
||||
|
||||
/// InternalExt provides a unified way of acessing `memory`, `store` and `internal` values
|
||||
|
||||
@@ -307,9 +307,7 @@ impl Plugin {
|
||||
|
||||
// If wasi is enabled then add it to the linker
|
||||
if with_wasi {
|
||||
wasmtime_wasi::add_to_linker(&mut linker, |x: &mut CurrentPlugin| {
|
||||
&mut x.wasi.as_mut().unwrap().ctx
|
||||
})?;
|
||||
wasmtime_wasi::preview2::preview1::add_to_linker_sync(&mut linker)?;
|
||||
}
|
||||
|
||||
for f in &mut imports {
|
||||
@@ -805,12 +803,8 @@ impl Plugin {
|
||||
}
|
||||
|
||||
let wasi_exit_code = e
|
||||
.downcast_ref::<wasmtime_wasi::I32Exit>()
|
||||
.map(|e| e.0)
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<wasmtime_wasi::preview2::I32Exit>()
|
||||
.map(|e| e.0)
|
||||
});
|
||||
.downcast_ref::<wasmtime_wasi::preview2::I32Exit>()
|
||||
.map(|e| e.0);
|
||||
if let Some(exit_code) = wasi_exit_code {
|
||||
debug!(
|
||||
plugin = self.id.to_string(),
|
||||
|
||||
@@ -389,20 +389,6 @@ pub unsafe extern "C" fn extism_plugin_config(
|
||||
}
|
||||
};
|
||||
|
||||
let wasi = &mut plugin.current_plugin_mut().wasi;
|
||||
if let Some(Wasi { ctx, .. }) = wasi {
|
||||
for (k, v) in json.iter() {
|
||||
match v {
|
||||
Some(v) => {
|
||||
let _ = ctx.push_env(k, v);
|
||||
}
|
||||
None => {
|
||||
let _ = ctx.push_env(k, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let id = plugin.id;
|
||||
let config = &mut plugin.current_plugin_mut().manifest.config;
|
||||
for (k, v) in json.into_iter() {
|
||||
|
||||
Reference in New Issue
Block a user