Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Migrate to extism v1. #280

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
668 changes: 352 additions & 316 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ cached = "0.46.1"
clap = "4.4.7"
clap_complete = "4.4.4"
convert_case = "0.6.0"
extism = { version = "0.5.4" }
extism-pdk = "0.3.4"
extism = { version = "1.0.0-alpha.0", path = "../extism/runtime" }
extism-pdk = { version = "1.0.0-beta.0", path = "../extism-pdk" }
human-sort = "0.2.2"
miette = "5.10.0"
once_cell = "1.18.0"
Expand Down
5 changes: 5 additions & 0 deletions EXTISM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Issues

- `Plugin#function_exists` should not be `&mut self`
- Equivalent to old `Plugin#set_config` ?
- re-export `log::Level`
59 changes: 27 additions & 32 deletions crates/core/src/host_funcs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::proto::ProtoEnvironment;
use extism::{CurrentPlugin, Error, Function, InternalExt, UserData, Val, ValType};
use extism::{CurrentPlugin, Error, Function, UserData, Val, ValType};
use proto_pdk_api::{ExecCommandInput, ExecCommandOutput, HostLogInput, HostLogTarget};
use starbase_utils::fs;
use std::env;
Expand All @@ -21,7 +21,7 @@ pub fn create_host_functions(data: HostData) -> Vec<Function> {
"exec_command",
[ValType::I64],
[ValType::I64],
Some(UserData::new(data.clone())),
UserData::new(data.clone()),
exec_command,
),
// Function::new(
Expand All @@ -35,15 +35,21 @@ pub fn create_host_functions(data: HostData) -> Vec<Function> {
"get_env_var",
[ValType::I64],
[ValType::I64],
None,
UserData::new(data.clone()),
get_env_var,
),
Function::new("host_log", [ValType::I64], [], None, host_log),
Function::new(
"host_log",
[ValType::I64],
[],
UserData::new(data.clone()),
host_log,
),
Function::new(
"set_env_var",
[ValType::I64, ValType::I64],
[],
None,
UserData::new(data.clone()),
set_env_var,
),
// Function::new(
Expand All @@ -62,10 +68,9 @@ pub fn host_log(
plugin: &mut CurrentPlugin,
inputs: &[Val],
_outputs: &mut [Val],
_user_data: UserData,
_user_data: UserData<HostData>,
) -> Result<(), Error> {
let input: HostLogInput =
serde_json::from_str(plugin.memory_read_str(inputs[0].unwrap_i64() as u64)?)?;
let input: HostLogInput = serde_json::from_str(plugin.memory_get_val(&inputs[0])?)?;

match input {
HostLogInput::Message(message) => {
Expand Down Expand Up @@ -108,10 +113,9 @@ fn exec_command(
plugin: &mut CurrentPlugin,
inputs: &[Val],
outputs: &mut [Val],
_user_data: UserData,
user_data: UserData<HostData>,
) -> Result<(), Error> {
let input: ExecCommandInput =
serde_json::from_str(plugin.memory_read_str(inputs[0].unwrap_i64() as u64)?)?;
let input: ExecCommandInput = serde_json::from_str(plugin.memory_get_val(&inputs[0])?)?;

trace!(
target: "proto_wasm::exec_command",
Expand All @@ -126,13 +130,13 @@ fn exec_command(
fs::update_perms(&input.command, None)?;
}

// let data = user_data.any().unwrap();
// let data = data.downcast_ref::<HostData>().unwrap();
let data = user_data.get()?;
let data = data.lock().unwrap();

let mut command = Command::new(&input.command);
command.args(&input.args);
command.envs(&input.env_vars);
// command.current_dir(&data.proto.cwd);
command.current_dir(&data.proto.cwd);

let output = if input.stream {
let result = command.spawn()?.wait()?;
Expand Down Expand Up @@ -175,9 +179,7 @@ fn exec_command(
"Executed command from plugin"
);

let ptr = plugin.memory_alloc_bytes(serde_json::to_string(&output)?)?;

outputs[0] = Val::I64(ptr as i64);
plugin.memory_set_val(&mut outputs[0], serde_json::to_string(&output)?)?;

Ok(())
}
Expand All @@ -186,21 +188,19 @@ fn get_env_var(
plugin: &mut CurrentPlugin,
inputs: &[Val],
outputs: &mut [Val],
_user_data: UserData,
_user_data: UserData<HostData>,
) -> Result<(), Error> {
let name = plugin.memory_read_str(inputs[0].unwrap_i64() as u64)?;
let value = env::var(name).unwrap_or_default();
let name: String = plugin.memory_get_val(&inputs[0])?;
let value = env::var(&name).unwrap_or_default();

trace!(
target: "proto_wasm::get_env_var",
name,
name = &name,
value = &value,
"Read environment variable from host"
);

let ptr = plugin.memory_alloc_bytes(value)?;

outputs[0] = Val::I64(ptr as i64);
plugin.memory_set_val(&mut outputs[0], value)?;

Ok(())
}
Expand All @@ -209,15 +209,10 @@ fn set_env_var(
plugin: &mut CurrentPlugin,
inputs: &[Val],
_outputs: &mut [Val],
_user_data: UserData,
_user_data: UserData<HostData>,
) -> Result<(), Error> {
let name = plugin
.memory_read_str(inputs[0].unwrap_i64() as u64)?
.to_owned();

let value = plugin
.memory_read_str(inputs[1].unwrap_i64() as u64)?
.to_owned();
let name: String = plugin.memory_get_val(&inputs[0])?;
let value: String = plugin.memory_get_val(&inputs[1])?;

trace!(
target: "proto_wasm::set_env_var",
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod version_resolver;

pub use error::*;
pub use events::*;
pub use extism::{manifest::Wasm, Manifest as PluginManifest};
pub use extism::{Manifest as PluginManifest, Wasm};
pub use helpers::*;
pub use proto::*;
pub use semver::{Version, VersionReq};
Expand Down
6 changes: 3 additions & 3 deletions crates/core/src/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::proto::ProtoEnvironment;
use crate::shimmer::{get_shim_file_name, ShimContext, SHIM_VERSION};
use crate::tool_manifest::ToolManifest;
use crate::version_resolver::VersionResolver;
use extism::{manifest::Wasm, Manifest as PluginManifest};
use extism::{Manifest as PluginManifest, Wasm};
use miette::IntoDiagnostic;
use proto_pdk_api::*;
use serde::Serialize;
Expand Down Expand Up @@ -41,7 +41,7 @@ pub struct Tool {
pub manifest: ToolManifest,
pub metadata: ToolMetadataOutput,
pub locator: Option<PluginLocator>,
pub plugin: PluginContainer<'static>,
pub plugin: PluginContainer,
pub proto: Arc<ProtoEnvironment>,
pub version: Option<VersionSpec>,

Expand Down Expand Up @@ -98,7 +98,7 @@ impl Tool {

trace!(file = ?log_file, "Created WASM log file");

extism::set_log_file(log_file, std::str::FromStr::from_str(&level).ok());
extism::set_log_file(log_file, std::str::FromStr::from_str(&level).unwrap()).unwrap();
}

let mut tool = Tool {
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/tool_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::proto::ProtoEnvironment;
use crate::tool::Tool;
use crate::tools_config::{ToolsConfig, SCHEMA_PLUGIN_KEY};
use crate::user_config::UserConfig;
use extism::{manifest::Wasm, Manifest};
use extism::{Manifest, Wasm};
use miette::IntoDiagnostic;
use proto_pdk_api::{HostArch, HostEnvironment, HostOS, UserConfigSettings};
use starbase_utils::{json, toml};
Expand Down
6 changes: 5 additions & 1 deletion crates/pdk-test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ pub fn find_wasm_file(sandbox: &Path) -> PathBuf {
if !LOGGING {
LOGGING = true;

extism::set_log_file(wasm_target_dir.join(format!("{wasm_file_name}.log")), None);
extism::set_log_file(
wasm_target_dir.join(format!("{wasm_file_name}.log")),
std::str::FromStr::from_str("trace").unwrap(),
)
.unwrap();
}
};

Expand Down
10 changes: 5 additions & 5 deletions crates/pdk/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn fetch_url_text<U>(url: U) -> anyhow::Result<String>
where
U: AsRef<str>,
{
String::from_bytes(fetch(HttpRequest::new(url.as_ref()), None)?.body())
String::from_bytes(&fetch(HttpRequest::new(url.as_ref()), None)?.body())
}

/// Fetch the provided URL, deserialize the response as JSON,
Expand Down Expand Up @@ -237,21 +237,21 @@ pub fn get_target_triple(env: &HostEnvironment, name: &str) -> Result<String, Pl
}

/// Get the active tool ID for the current WASM instance.
pub fn get_tool_id() -> String {
config::get("proto_tool_id").expect("Missing tool ID!")
pub fn get_tool_id() -> anyhow::Result<String> {
Ok(config::get("proto_tool_id")?.expect("Missing tool ID!"))
}

/// Return information about proto and the host environment.
pub fn get_proto_environment() -> anyhow::Result<HostEnvironment> {
let config = config::get("proto_environment").expect("Missing proto environment!");
let config = config::get("proto_environment")?.expect("Missing proto environment!");
let config: HostEnvironment = json::from_str(&config)?;

Ok(config)
}

/// Return the loaded proto user configuration (`~/.proto/config.toml`). Does not include plugins!
pub fn get_proto_user_config() -> anyhow::Result<UserConfigSettings> {
let config = config::get("proto_user_config").expect("Missing proto user configuration!");
let config = config::get("proto_user_config")?.expect("Missing proto user configuration!");
let config: UserConfigSettings = json::from_str(&config)?;

Ok(config)
Expand Down
36 changes: 17 additions & 19 deletions crates/warpgate/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,25 @@ use warpgate_api::VirtualPath;
/// A container around Extism's [`Plugin`] and [`Manifest`] types that provides convenience
/// methods for calling and caching functions from the WASM plugin. It also provides
/// additional methods for easily working with WASI and virtual paths.
pub struct PluginContainer<'plugin> {
pub struct PluginContainer {
pub id: Id,
pub manifest: Manifest,

func_cache: OnceMap<String, Vec<u8>>,
plugin: Arc<RwLock<Plugin<'plugin>>>,
plugin: Arc<RwLock<Plugin>>,
}

unsafe impl<'plugin> Send for PluginContainer<'plugin> {}
unsafe impl<'plugin> Sync for PluginContainer<'plugin> {}
unsafe impl Send for PluginContainer {}
unsafe impl Sync for PluginContainer {}

impl<'plugin> PluginContainer<'plugin> {
impl PluginContainer {
/// Create a new container with the provided manifest and host functions.
pub fn new<'new>(
pub fn new(
id: Id,
manifest: Manifest,
functions: impl IntoIterator<Item = Function>,
) -> miette::Result<PluginContainer<'new>> {
let plugin = Plugin::create_with_manifest(&manifest, functions, true)
) -> miette::Result<PluginContainer> {
let plugin = Plugin::new(&manifest, functions, true)
.map_err(|error| WarpgateError::PluginCreateFailed { error })?;

Ok(PluginContainer {
Expand All @@ -47,10 +47,7 @@ impl<'plugin> PluginContainer<'plugin> {
}

/// Create a new container with the provided manifest.
pub fn new_without_functions<'new>(
id: Id,
manifest: Manifest,
) -> miette::Result<PluginContainer<'new>> {
pub fn new_without_functions(id: Id, manifest: Manifest) -> miette::Result<PluginContainer> {
Self::new(id, manifest, [])
}

Expand All @@ -63,11 +60,12 @@ impl<'plugin> PluginContainer<'plugin> {
.map(|(k, v)| (k.to_owned(), Some(v.to_owned())))
.collect::<BTreeMap<_, _>>();

self.plugin
.write()
.expect("Failed to acquire write access!")
.set_config(&config)
.unwrap();
// TODO fix
// self.plugin
// .write()
// .expect("Failed to acquire write access!")
// .set_config(&config)
// .unwrap();

Ok(())
}
Expand Down Expand Up @@ -136,14 +134,14 @@ impl<'plugin> PluginContainer<'plugin> {
/// Return true if the plugin has a function with the given id.
pub fn has_func(&self, func: &str) -> bool {
self.plugin
.read()
.write() // TODO switch back to read
.unwrap_or_else(|_| {
panic!(
"Unable to acquire read access to `{}` WASM plugin.",
self.id
)
})
.has_function(func)
.function_exists(func)
}

/// Convert the provided virtual guest path to an absolute host path.
Expand Down
Loading