Skip to content

Commit

Permalink
Merge pull request #1320 from apepkuss/feat-wasmedge-executor
Browse files Browse the repository at this point in the history
[libcontainer] Integrate WasmEdge Runtime
  • Loading branch information
utam0k authored Nov 30, 2022
2 parents 237af4c + 44f1c13 commit 997bc43
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 8 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ jobs:
- run: sudo apt-get -y update
- run: sudo apt-get install -y pkg-config libsystemd-dev libdbus-glib-1-dev libelf-dev libseccomp-dev
- name: Run tests
run: cd ./crates && cargo test --all --all-features --no-fail-fast
run: |
export LD_LIBRARY_PATH=$HOME/.wasmedge/lib
cd ./crates && cargo test --all --all-features --no-fail-fast
coverage:
runs-on: ubuntu-latest
timeout-minutes: 15
Expand Down
155 changes: 155 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/libcontainer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ systemd = ["libcgroups/systemd", "v2"]
v2 = ["libcgroups/v2"]
v1 = ["libcgroups/v1"]
cgroupsv2_devices = ["libcgroups/cgroupsv2_devices"]
wasm-wasmedge = ["wasmedge-sdk/standalone"]

[dependencies]
anyhow = "1.0"
Expand All @@ -43,6 +44,7 @@ syscalls = "0.6.7"
rust-criu = "0.2.0"
wasmer = { version = "2.2.0", optional = true }
wasmer-wasi = { version = "2.3.0", optional = true }
wasmedge-sdk = { version = "0.7.1", optional = true }

[dev-dependencies]
oci-spec = { version = "0.5.8", features = ["proptests", "runtime"] }
Expand Down
9 changes: 9 additions & 0 deletions crates/libcontainer/src/workload/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ use anyhow::{Context, Result};
use oci_spec::runtime::Spec;

use self::default::DefaultExecutor;
#[cfg(feature = "wasm-wasmedge")]
use self::wasmedge::WasmEdgeExecutor;
#[cfg(feature = "wasm-wasmer")]
use self::wasmer::WasmerExecutor;

pub mod default;
#[cfg(feature = "wasm-wasmedge")]
pub mod wasmedge;
#[cfg(feature = "wasm-wasmer")]
pub mod wasmer;

Expand All @@ -28,6 +32,11 @@ impl ExecutorManager {
return WasmerExecutor::exec(spec).context("wasmer execution failed");
}

#[cfg(feature = "wasm-wasmedge")]
if WasmEdgeExecutor::can_handle(spec)? {
return WasmEdgeExecutor::exec(spec).context("wasmedge execution failed");
}

DefaultExecutor::exec(spec).context("default execution failed")
}
}
90 changes: 90 additions & 0 deletions crates/libcontainer/src/workload/wasmedge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use anyhow::Result;
use oci_spec::runtime::Spec;
use wasmedge_sdk::{
config::{CommonConfigOptions, ConfigBuilder, HostRegistrationConfigOptions},
params, Vm,
};

use super::Executor;

const EXECUTOR_NAME: &str = "wasmedge";

pub struct WasmEdgeExecutor {}
impl Executor for WasmEdgeExecutor {
fn exec(spec: &Spec) -> Result<()> {
// parse wasi parameters
let args = get_args(spec);
let mut cmd = args[0].clone();
if let Some(stripped) = args[0].strip_prefix(std::path::MAIN_SEPARATOR) {
cmd = stripped.to_string();
}
let envs = env_to_wasi(spec);

// create configuration with `wasi` option enabled
let config = ConfigBuilder::new(CommonConfigOptions::default())
.with_host_registration_config(HostRegistrationConfigOptions::default().wasi(true))
.build()?;

// create a vm with the config settings
let mut vm = Vm::new(Some(config))?;

// initialize the wasi module with the parsed parameters
let mut wasi_instance = vm.wasi_module()?;
wasi_instance.initialize(
Some(args.iter().map(|s| s as &str).collect()),
Some(envs.iter().map(|s| s as &str).collect()),
None,
);

let mut vm = vm.register_module_from_file("main", &cmd)?;

let ins = vm.named_module("main")?;
ins.func("_start")
.expect("Not found '_start' func in the 'main' module instance")
.call(&mut vm, params!())?;

Ok(())
}

fn can_handle(spec: &Spec) -> Result<bool> {
if let Some(annotations) = spec.annotations() {
if let Some(handler) = annotations.get("run.oci.handler") {
return Ok(handler == "wasm");
}

if let Some(variant) = annotations.get("module.wasm.image/variant") {
return Ok(variant == "compat");
}
}

Ok(false)
}

fn name() -> &'static str {
EXECUTOR_NAME
}
}

fn get_args(spec: &Spec) -> &[String] {
let p = match spec.process() {
None => return &[],
Some(p) => p,
};

match p.args() {
None => &[],
Some(args) => args.as_slice(),
}
}

fn env_to_wasi(spec: &Spec) -> Vec<String> {
let default = vec![];
let env = spec
.process()
.as_ref()
.unwrap()
.env()
.as_ref()
.unwrap_or(&default);
env.to_vec()
}
Loading

0 comments on commit 997bc43

Please sign in to comment.