Skip to content

Commit

Permalink
fixed wasm error
Browse files Browse the repository at this point in the history
Signed-off-by: yihuaf <[email protected]>
  • Loading branch information
yihuaf committed May 18, 2023
1 parent ac8fd4d commit a286eb6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 77 deletions.
33 changes: 17 additions & 16 deletions crates/youki/src/workload/wasmedge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const EXECUTOR_NAME: &str = "wasmedge";
#[derive(Default)]
pub struct WasmEdgeExecutor {}

impl WasmEdgeExecutor {
fn exec_inner(spec: &Spec) -> anyhow::Result<()> {
impl Executor for WasmEdgeExecutor {
fn exec(&self, spec: &Spec) -> Result<(), ExecutorError> {
// parse wasi parameters
let args = get_args(spec);
let mut cmd = args[0].clone();
Expand All @@ -24,14 +24,23 @@ impl WasmEdgeExecutor {
// create configuration with `wasi` option enabled
let config = ConfigBuilder::new(CommonConfigOptions::default())
.with_host_registration_config(HostRegistrationConfigOptions::default().wasi(true))
.build()?;
.build()
.map_err(|err| {
ExecutorError::Other(format!("failed to create wasmedge config: {}", err))
})?;

// create a vm with the config settings
let mut vm = VmBuilder::new()
.with_config(config)
.build()?
.register_module_from_file("main", cmd)?;

.build()
.map_err(|err| ExecutorError::Other(format!("failed to create wasmedge vm: {}", err)))?
.register_module_from_file("main", cmd)
.map_err(|err| {
ExecutorError::Other(format!(
"failed to register wasmedge module from the file: {}",
err
))
})?;
// initialize the wasi module with the parsed parameters
let wasi_instance = vm
.wasi_module_mut()
Expand All @@ -42,19 +51,11 @@ impl WasmEdgeExecutor {
None,
);

vm.run_func(Some("main"), "_start", params!())?;
vm.run_func(Some("main"), "_start", params!())
.map_err(|err| ExecutorError::Execution(err))?;

Ok(())
}
}

impl Executor for WasmEdgeExecutor {
fn exec(&self, spec: &Spec) -> Result<(), ExecutorError> {
Self::exec_inner(spec).map_err(|err| {
tracing::error!(?err, "failed to execute workload with wasmedge handler");
ExecutorError::Execution(err.into())
})
}

fn can_handle(&self, spec: &Spec) -> bool {
if let Some(annotations) = spec.annotations() {
Expand Down
68 changes: 35 additions & 33 deletions crates/youki/src/workload/wasmer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use anyhow::{bail, Context, Result};
use oci_spec::runtime::Spec;
use wasmer::{Instance, Module, Store};
use wasmer_wasix::WasiEnv;
Expand All @@ -10,9 +9,9 @@ const EXECUTOR_NAME: &str = "wasmer";
#[derive(Default)]
pub struct WasmerExecutor {}

impl WasmerExecutor {
fn exec_inner(spec: &Spec) -> anyhow::Result<()> {
tracing::debug!("Executing workload with wasmer handler");
impl Executor for WasmerExecutor {
fn exec(&self, spec: &Spec) -> Result<(), ExecutorError> {
tracing::debug!("executing workload with wasmer handler");
let process = spec.process().as_ref();

let args = process.and_then(|p| p.args().as_ref()).unwrap_or(&EMPTY);
Expand All @@ -27,54 +26,56 @@ impl WasmerExecutor {
});

if args.is_empty() {
bail!("at least one process arg must be specified")
tracing::error!("at least one process arg must be specified");
return Err(ExecutorError::InvalidArg);
}

if !args[0].ends_with(".wasm") && !args[0].ends_with(".wat") {
bail!(
tracing::error!(
"first argument must be a wasm or wat module, but was {}",
args[0]
)
);
return Err(ExecutorError::InvalidArg);
}

let mut store = Store::default();
let module = Module::from_file(&store, &args[0])
.with_context(|| format!("could not load wasm module from {}", &args[0]))?;
let module = Module::from_file(&store, &args[0]).map_err(|err| {
tracing::error!(err = ?err, file = ?args[0], "could not load wasm module from file");
ExecutorError::Other("could not load wasm module from file".to_string())
})?;

let mut wasi_env = WasiEnv::builder("youki_wasm_app")
.args(args.iter().skip(1))
.envs(env)
.finalize(&mut store)?;

let imports = wasi_env
.import_object(&mut store, &module)
.context("could not retrieve wasm imports")?;
let instance = Instance::new(&mut store, &module, &imports)
.context("wasm module could not be instantiated")?;

wasi_env.initialize(&mut store, instance.clone())?;

let start = instance
.exports
.get_function("_start")
.context("could not retrieve wasm module main function")?;
.finalize(&mut store)
.map_err(|err| ExecutorError::Other(format!("could not create wasi env: {}", err)))?;

let imports = wasi_env.import_object(&mut store, &module).map_err(|err| {
ExecutorError::Other(format!("could not retrieve wasm imports: {}", err))
})?;
let instance = Instance::new(&mut store, &module, &imports).map_err(|err| {
ExecutorError::Other(format!("could not instantiate wasm module: {}", err))
})?;

wasi_env
.initialize(&mut store, instance.clone())
.map_err(|err| {
ExecutorError::Other(format!("could not initialize wasi env: {}", err))
})?;

let start = instance.exports.get_function("_start").map_err(|err| {
ExecutorError::Other(format!(
"could not retrieve wasm module main function: {err}"
))
})?;
start
.call(&mut store, &[])
.context("wasm module was not executed successfully")?;
.map_err(|err| ExecutorError::Execution(err.into()))?;

wasi_env.cleanup(&mut store, None);

Ok(())
}
}

impl Executor for WasmerExecutor {
fn exec(&self, spec: &Spec) -> Result<(), ExecutorError> {
Self::exec_inner(spec).map_err(|err| {
tracing::error!(?err, "failed to execute workload with wasmer handler");
ExecutorError::Execution(err.into())
})
}

fn can_handle(&self, spec: &Spec) -> bool {
if let Some(annotations) = spec.annotations() {
Expand All @@ -98,6 +99,7 @@ impl Executor for WasmerExecutor {
#[cfg(test)]
mod tests {
use super::*;
use anyhow::{Context, Result};
use oci_spec::runtime::SpecBuilder;
use std::collections::HashMap;

Expand Down
57 changes: 29 additions & 28 deletions crates/youki/src/workload/wasmtime.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use anyhow::{anyhow, bail, Context, Result};
use oci_spec::runtime::Spec;
use wasmtime::*;
use wasmtime_wasi::WasiCtxBuilder;
Expand All @@ -10,8 +9,8 @@ const EXECUTOR_NAME: &str = "wasmtime";
#[derive(Default)]
pub struct WasmtimeExecutor {}

impl WasmtimeExecutor {
fn exec_inner(spec: &Spec) -> anyhow::Result<()> {
impl Executor for WasmtimeExecutor {
fn exec(&self, spec: &Spec) -> Result<(), ExecutorError> {
tracing::info!("Executing workload with wasmtime handler");
let process = spec.process().as_ref();

Expand All @@ -21,14 +20,16 @@ impl WasmtimeExecutor {
.and_then(|p| p.args().as_ref())
.unwrap_or(&EMPTY);
if args.is_empty() {
bail!("at least one process arg must be specified")
tracing::error!("at least one process arg must be specified");
return Err(ExecutorError::InvalidArg);
}

if !args[0].ends_with(".wasm") && !args[0].ends_with(".wat") {
bail!(
tracing::error!(
"first argument must be a wasm or wat module, but was {}",
args[0]
)
);
return Err(ExecutorError::InvalidArg);
}

let mut cmd = args[0].clone();
Expand All @@ -48,42 +49,42 @@ impl WasmtimeExecutor {
.collect();

let engine = Engine::default();
let module = Module::from_file(&engine, &cmd)
.with_context(|| format!("could not load wasm module from {}", &cmd))?;
let module = Module::from_file(&engine, &cmd).map_err(|err| {
tracing::error!(err = ?err, file = ?cmd, "could not load wasm module from file");
ExecutorError::Other("could not load wasm module from file".to_string())
})?;

let mut linker = Linker::new(&engine);
wasmtime_wasi::add_to_linker(&mut linker, |s| s)
.context("cannot add wasi context to linker")?;
wasmtime_wasi::add_to_linker(&mut linker, |s| s).map_err(|err| {
tracing::error!(err = ?err, "cannot add wasi context to linker");
ExecutorError::Other("cannot add wasi context to linker".to_string())
})?;

let wasi = WasiCtxBuilder::new()
.inherit_stdio()
.args(args)
.context("cannot add args to wasi context")?
.map_err(|err| {
ExecutorError::Other(format!("cannot add args to wasi context: {}", err))
})?
.envs(&envs)
.context("cannot add environment variables to wasi context")?
.map_err(|err| {
ExecutorError::Other(format!("cannot add envs to wasi context: {}", err))
})?
.build();

let mut store = Store::new(&engine, wasi);

let instance = linker
.instantiate(&mut store, &module)
.context("wasm module could not be instantiated")?;
let start = instance
.get_func(&mut store, "_start")
.ok_or_else(|| anyhow!("could not retrieve wasm module main function"))?;
let instance = linker.instantiate(&mut store, &module).map_err(|err| {
tracing::error!(err = ?err, "wasm module could not be instantiated");
ExecutorError::Other("wasm module could not be instantiated".to_string())
})?;
let start = instance.get_func(&mut store, "_start").ok_or_else(|| {
ExecutorError::Other("could not retrieve wasm module main function".into())
})?;

start
.call(&mut store, &[], &mut [])
.context("wasm module was not executed successfully")
}
}

impl Executor for WasmtimeExecutor {
fn exec(&self, spec: &Spec) -> Result<(), ExecutorError> {
Self::exec_inner(spec).map_err(|err| {
tracing::error!(?err, "failed to execute workload with wasmtime handler");
ExecutorError::Execution(err.into())
})
.map_err(|err| ExecutorError::Execution(err.into()))
}

fn can_handle(&self, spec: &Spec) -> bool {
Expand Down

0 comments on commit a286eb6

Please sign in to comment.