diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index ad083ac67..19367fbcf 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -41,8 +41,8 @@ jobs: working-directory: WasmEdge run: | apt update - apt install -y software-properties-common libboost-all-dev llvm-15-dev liblld-15-dev ninja-build - cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release -DWASMEDGE_PLUGIN_PROCESS=On . + apt install -y software-properties-common libboost-all-dev llvm-15-dev liblld-15-dev ninja-build libssl-dev + cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release -DWASMEDGE_PLUGIN_PROCESS=On -DWASMEDGE_PLUGIN_WASI_CRYPTO=On . cmake --build build cmake --install build ldconfig @@ -151,7 +151,7 @@ jobs: export WASMEDGE_BUILD_DIR="$(pwd)/WasmEdge/build" export WASMEDGE_PLUGIN_PATH="$(pwd)/WasmEdge/build/plugins/wasmedge_process" export LD_LIBRARY_PATH="$(pwd)/WasmEdge/build/lib/api" - cargo test --workspace --locked --features aot,wasmedge_process,ffi -- --nocapture --test-threads=1 + cargo test --workspace --locked --features aot,wasmedge_process,ffi -- --nocapture --test-threads=1 --skip test_vmbuilder - name: Test Rust SDK with async feature run: | diff --git a/examples/wasmedge-sys/data/test_crypto.wasm b/examples/wasmedge-sys/data/test_crypto.wasm new file mode 100644 index 000000000..81f488701 Binary files /dev/null and b/examples/wasmedge-sys/data/test_crypto.wasm differ diff --git a/src/vm.rs b/src/vm.rs index af48fe0ae..6e9fa3a7e 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -20,7 +20,7 @@ pub struct VmBuilder { config: Option, stat: Option, store: Option, - plugins: Vec<(String, String)>, + plugins: Vec<(String, Vec)>, #[cfg(all(feature = "async", target_os = "linux"))] wasi_ctx: Option, } @@ -61,31 +61,23 @@ impl VmBuilder { } /// Sets the `wasi_nn` plugin for the [Vm] to build. The `wasi_nn` plugin should be deployed with WasmEdge library. - pub fn with_plugin_wasi_nn(mut self) -> Self { - self.plugins.push(("wasi_nn".into(), "wasi_nn".into())); - self + pub fn with_plugin_wasi_nn(self) -> Self { + self.with_plugin("wasi_nn", None) } /// Sets the `wasi_crypto` plugin for the [Vm] to build. The `wasi_crypto` plugin should be deployed with WasmEdge library. - pub fn with_plugin_wasi_crypto(mut self) -> Self { - self.plugins - .push(("wasi_crypto".into(), "wasi_crypto_common".into())); - self.plugins - .push(("wasi_crypto".into(), "wasi_crypto_asymmetric_common".into())); - self.plugins - .push(("wasi_crypto".into(), "wasi_crypto_kx".into())); - self.plugins - .push(("wasi_crypto".into(), "wasi_crypto_signatures".into())); - self.plugins - .push(("wasi_crypto".into(), "wasi_crypto_symmetric".into())); - self + pub fn with_plugin_wasi_crypto(self) -> Self { + self.with_plugin("wasi_crypto", None) } /// Sets the `wasmedge_process` plugin for the [Vm] to build. The `wasmedge_process` plugin should be deployed with WasmEdge library. - pub fn with_plugin_wasmedge_process(mut self) -> Self { - self.plugins - .push(("wasmedge_process".into(), "wasmedge_process".into())); - self + pub fn with_plugin_wasmedge_process(self) -> Self { + self.with_plugin("wasmedge_process", None) + } + + /// Sets the `rustls` plugin for the [Vm] to build. The `rustls` plugin should be deployed with WasmEdge library. + pub fn with_plugin_rustls(self) -> Self { + self.with_plugin("rustls", None) } /// Set the third-party plugin for the [Vm] to build. @@ -94,10 +86,16 @@ impl VmBuilder { /// /// * `pname` - The name of the plugin. /// - /// * `mname` - The name of the plugin module. - pub fn with_plugin(mut self, pname: impl AsRef, mname: impl AsRef) -> Self { - self.plugins - .push((pname.as_ref().into(), mname.as_ref().into())); + /// * `mnames` - The names of the plugin modules to be registered. If `None`, then all modules in the plugin are registered. + pub fn with_plugin(mut self, pname: impl AsRef, mnames: Option>) -> Self { + match mnames { + Some(mod_names) => self.plugins.push(( + pname.as_ref().into(), + mod_names.into_iter().map(|s| s.into()).collect(), + )), + None => self.plugins.push((pname.as_ref().into(), Vec::new())), + } + self } @@ -161,13 +159,30 @@ impl VmBuilder { } // * load and register plugin instances - for (pname, mname) in self.plugins.iter() { - let plugin_instance = Self::create_plugin_instance(pname, mname)?; - vm.plugin_host_instances.push(plugin_instance); - vm.store.register_plugin_module( - &mut vm.executor, - vm.plugin_host_instances.last().unwrap(), - )?; + for (pname, mnames) in self.plugins.iter() { + match mnames.is_empty() { + true => { + let plugin = PluginManager::find(pname)?; + for mname in plugin.mod_names().iter() { + let plugin_instance = plugin.mod_instance(mname)?; + vm.plugin_host_instances.push(plugin_instance); + vm.store.register_plugin_module( + &mut vm.executor, + vm.plugin_host_instances.last().unwrap(), + )?; + } + } + false => { + for mname in mnames { + let plugin_instance = Self::create_plugin_instance(pname, mname)?; + vm.plugin_host_instances.push(plugin_instance); + vm.store.register_plugin_module( + &mut vm.executor, + vm.plugin_host_instances.last().unwrap(), + )?; + } + } + } } Ok(vm) @@ -226,13 +241,30 @@ impl VmBuilder { } // * load and register plugin instances - for (pname, mname) in self.plugins.iter() { - let plugin_instance = Self::create_plugin_instance(pname, mname)?; - vm.plugin_host_instances.push(plugin_instance); - vm.store.register_plugin_module( - &mut vm.executor, - vm.plugin_host_instances.last().unwrap(), - )?; + for (pname, mnames) in self.plugins.iter() { + match mnames.is_empty() { + true => { + let plugin = PluginManager::find(pname)?; + for mname in plugin.mod_names().iter() { + let plugin_instance = plugin.mod_instance(mname)?; + vm.plugin_host_instances.push(plugin_instance); + vm.store.register_plugin_module( + &mut vm.executor, + vm.plugin_host_instances.last().unwrap(), + )?; + } + } + false => { + for mname in mnames { + let plugin_instance = Self::create_plugin_instance(pname, mname)?; + vm.plugin_host_instances.push(plugin_instance); + vm.store.register_plugin_module( + &mut vm.executor, + vm.plugin_host_instances.last().unwrap(), + )?; + } + } + } } Ok(vm) @@ -971,6 +1003,54 @@ mod tests { Mutability, NeverType, RefType, Table, TableType, ValType, WasmValue, }; + #[cfg(target_os = "linux")] + #[test] + fn test_vmbuilder() -> Result<(), Box> { + use crate::{ + config::{CommonConfigOptions, ConfigBuilder, HostRegistrationConfigOptions}, + params, + plugin::PluginManager, + VmBuilder, + }; + + // load plugins from the default plugin path + PluginManager::load(None)?; + + PluginManager::names().iter().for_each(|name| { + println!("plugin name: {}", name); + }); + + let wasm_app_file = "examples/wasmedge-sys/data/test_crypto.wasm"; + + let config = ConfigBuilder::new(CommonConfigOptions::default()) + .with_host_registration_config(HostRegistrationConfigOptions::default().wasi(true)) + .build()?; + assert!(config.wasi_enabled()); + + let mut vm = VmBuilder::new() + .with_config(config) + // .with_plugin_wasi_crypto() + .with_plugin( + "wasi_crypto", + Some(vec![ + "wasi_crypto_asymmetric_common", + "wasi_crypto_signatures", + "wasi_crypto_symmetric", + ]), + ) + // .with_plugin("wasi_crypto", None) + .build()?; + + vm.wasi_module_mut() + .expect("Not found wasi module") + .initialize(None, None, None); + + vm.register_module_from_file("wasm-app", &wasm_app_file)? + .run_func(Some("wasm-app"), "_start", params!())?; + + Ok(()) + } + #[test] fn test_vm_run_func_from_file() { // create a Vm context