diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d6d45424..fbd01db69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: strategy: matrix: os: ["ubuntu-22.04"] - runtime: ["common", "wasmtime", "wasmedge", "wasmer"] + runtime: ["common", "wasmtime", "wasmedge", "wasmer", "wamr"] libc: ["musl", "gnu"] uses: ./.github/workflows/action-build.yml with: @@ -56,7 +56,7 @@ jobs: strategy: matrix: os: ["windows-latest"] - runtime: ["common", "wasmtime", "wasmedge", "wasmer"] + runtime: ["common", "wasmtime", "wasmedge", "wasmer", "wamr"] uses: ./.github/workflows/action-build.yml with: os: ${{ matrix.os }} @@ -70,7 +70,7 @@ jobs: matrix: # 20.04 uses cgroupv1, 22.04 uses cgroupv2 os: ["ubuntu-20.04", "ubuntu-22.04"] - runtime: ["wasmtime", "wasmedge", "wasmer"] + runtime: ["wasmtime", "wasmedge", "wasmer", "wamr"] uses: ./.github/workflows/action-test-smoke.yml with: os: ${{ matrix.os }} @@ -84,7 +84,7 @@ jobs: matrix: # 20.04 uses cgroupv1, 22.04 uses cgroupv2 os: ["ubuntu-20.04", "ubuntu-22.04"] - runtime: ["wasmtime", "wasmedge", "wasmer"] + runtime: ["wasmtime", "wasmedge", "wasmer", "wamr"] uses: ./.github/workflows/action-test-kind.yml with: os: ${{ matrix.os }} @@ -97,7 +97,7 @@ jobs: strategy: matrix: os: ["ubuntu-22.04"] - runtime: ["wasmtime", "wasmedge", "wasmer"] + runtime: ["wasmtime", "wasmedge", "wasmer", "wamr"] uses: ./.github/workflows/action-test-kind.yml with: os: ${{ matrix.os }} @@ -112,7 +112,7 @@ jobs: fail-fast: false matrix: os: ["ubuntu-20.04", "ubuntu-22.04"] - runtime: ["wasmtime", "wasmedge", "wasmer"] + runtime: ["wasmtime", "wasmedge", "wasmer", "wamr"] uses: ./.github/workflows/action-test-k3s.yml with: os: ${{ matrix.os }} diff --git a/Cargo.lock b/Cargo.lock index ac01e90bb..5b9753b37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,13 +253,16 @@ dependencies = [ "clang-sys", "lazy_static", "lazycell", + "log", "peeking_take_while", + "prettyplease 0.2.16", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", "syn 2.0.48", + "which", ] [[package]] @@ -608,6 +611,21 @@ dependencies = [ "ttrpc-codegen", ] +[[package]] +name = "containerd-shim-wamr" +version = "0.4.0" +dependencies = [ + "anyhow", + "containerd-shim", + "containerd-shim-wasm", + "log", + "oci-spec", + "serial_test", + "sha256", + "ttrpc", + "wamr-rust-sdk", +] + [[package]] name = "containerd-shim-wasm" version = "0.5.0" @@ -2742,6 +2760,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn 2.0.48", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -2862,7 +2890,7 @@ dependencies = [ "log", "multimap", "petgraph 0.6.4", - "prettyplease", + "prettyplease 0.1.25", "prost 0.11.9", "prost-types 0.11.9", "regex", @@ -4132,7 +4160,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" dependencies = [ - "prettyplease", + "prettyplease 0.1.25", "proc-macro2", "prost-build 0.11.9", "quote", @@ -4554,6 +4582,24 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wamr-rust-sdk" +version = "0.1.0" +source = "git+https://github.com/bytecodealliance/wamr-rust-sdk?branch=main#e2dd12e4dbd3671888ee7ccfb0d3662a8145d036" +dependencies = [ + "wamr-sys", +] + +[[package]] +name = "wamr-sys" +version = "0.1.0" +source = "git+https://github.com/bytecodealliance/wamr-rust-sdk?branch=main#e2dd12e4dbd3671888ee7ccfb0d3662a8145d036" +dependencies = [ + "bindgen", + "cc", + "cmake", +] + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index da8bedcec..a1da243c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,6 @@ [workspace] members = [ - "crates/containerd-shim-wasm", - "crates/containerd-shim-wasm-test-modules", - "crates/wasi-demo-app", - "crates/oci-tar-builder", - "crates/containerd-shim-wasmedge", - "crates/containerd-shim-wasmtime", - "crates/containerd-shim-wasmer" + "crates/*", ] resolver = "2" diff --git a/Makefile b/Makefile index d05911404..19cc2ac43 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ INSTALL ?= install CARGO ?= cargo LN ?= ln -sf TEST_IMG_NAME ?= wasmtest:latest -RUNTIMES ?= wasmedge wasmtime wasmer +RUNTIMES ?= wasmedge wasmtime wasmer wamr CONTAINERD_NAMESPACE ?= default # We have a bit of fancy logic here to determine the target diff --git a/crates/containerd-shim-wamr/Cargo.toml b/crates/containerd-shim-wamr/Cargo.toml new file mode 100644 index 000000000..7ea5e0a3f --- /dev/null +++ b/crates/containerd-shim-wamr/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "containerd-shim-wamr" +version.workspace = true +edition.workspace = true +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +containerd-shim = { workspace = true } +containerd-shim-wasm = { workspace = true } +log = { workspace = true } +oci-spec = { workspace = true, features = ["runtime"] } +ttrpc = { workspace = true } +sha256 = { workspace = true } + +wamr-rust-sdk = { git = "https://github.com/bytecodealliance/wamr-rust-sdk", branch = "main" } + +[dev-dependencies] +containerd-shim-wasm = { workspace = true, features = ["testing"] } +serial_test = { workspace = true } + +[[bin]] +name = "containerd-shim-wamr-v1" +path = "src/main.rs" diff --git a/crates/containerd-shim-wamr/src/instance.rs b/crates/containerd-shim-wamr/src/instance.rs new file mode 100644 index 000000000..3d89bdd94 --- /dev/null +++ b/crates/containerd-shim-wamr/src/instance.rs @@ -0,0 +1,90 @@ +use anyhow::{Context, Result}; +use containerd_shim_wasm::container::{ + Engine, Entrypoint, Instance, RuntimeContext, Stdio +}; +use wamr_rust_sdk::function::Function; +use wamr_rust_sdk::instance::Instance as WamrInstnace; +use wamr_rust_sdk::module::Module; +use wamr_rust_sdk::runtime::Runtime; + +pub type WamrInstance = Instance; + +pub struct WamrEngine { + runtime: Runtime, +} + +unsafe impl Send for WamrEngine {} +unsafe impl Sync for WamrEngine {} + +// TODO: wasmr_rust_sdk::runtime::Runtime should implement Clone + +impl Default for WamrEngine { + fn default() -> Self { + let runtime = Runtime::new().unwrap(); + Self { runtime } + } +} + +impl Clone for WamrEngine { + fn clone(&self) -> Self { + let runtime = Runtime::new().unwrap(); + Self { runtime } + } +} + +impl Engine for WamrEngine { + fn name() -> &'static str { + "wamr" + } + + fn run_wasi(&self, ctx: &impl RuntimeContext, stdio: Stdio) -> Result { + let args = ctx.args(); + let envs: Vec<_> = std::env::vars().map(|(k, v)| format!("{k}={v}")).collect(); + let Entrypoint { + source, + func, + arg0: _, + name, + } = ctx.entrypoint(); + + let wasm_bytes = source + .as_bytes() + .context("Failed to get bytes from source")?; + + log::info!("Create a WamrInstance"); + + // TODO: error handling isn't ideal + + let mut module = Module::from_buf(&wasm_bytes).map_err(|e| { + anyhow::Error::msg(format!("Failed to create module from bytes: {:?}", e)) + })?; + + module.set_wasi_arg_pre_open_path(vec![String::from("/")], vec![String::from("/")]); + module.set_wasi_arg_env_vars(envs); + + // TODO: no way to set args in wamr? + // TODO: no way to register a named module with bytes? + + let instance = WamrInstnace::new(&module, 1024 * 64) + .map_err(|e| anyhow::Error::msg(format!("Failed to create instance: {:?}", e)))?; + + // TODO: bug: failed at line above saying: `thread signal env initialized failed` + + log::info!("redirect stdio"); + stdio.redirect()?; + + log::info!("Running {func:?}"); + let function = Function::find_export_func(&instance, &func) + .map_err(|e| anyhow::Error::msg(format!("Failed to find function: {:?}", e)))?; + let status = function + .call(&instance, &Vec::new()) + .map(|_| 0) + .or_else(|err| { + log::error!("Error: {:?}", err); + Err(err) + }) + .map_err(|e| anyhow::Error::msg(format!("Failed to call function: {:?}", e)))?; + + Ok(status) + } +} diff --git a/crates/containerd-shim-wamr/src/lib.rs b/crates/containerd-shim-wamr/src/lib.rs new file mode 100644 index 000000000..0e7ee6caa --- /dev/null +++ b/crates/containerd-shim-wamr/src/lib.rs @@ -0,0 +1,3 @@ +pub mod instance; + +pub use instance::WamrInstance; diff --git a/crates/containerd-shim-wamr/src/main.rs b/crates/containerd-shim-wamr/src/main.rs new file mode 100644 index 000000000..3edd815b7 --- /dev/null +++ b/crates/containerd-shim-wamr/src/main.rs @@ -0,0 +1,6 @@ +use containerd_shim_wamr::WamrInstance; +use containerd_shim_wasm::sandbox::cli::{revision, shim_main, version}; + +fn main() { + shim_main::("wamr", version!(), revision!(), "v1", None); +} diff --git a/crates/containerd-shim-wamr/src/test.rs b/crates/containerd-shim-wamr/src/test.rs new file mode 100644 index 000000000..0a20db0a9 --- /dev/null +++ b/crates/containerd-shim-wamr/src/test.rs @@ -0,0 +1 @@ +// TODO: add tests \ No newline at end of file