8 breaking releases
Uses new Rust 2024
0.10.0 | Mar 5, 2025 |
---|---|
0.8.0 | Dec 4, 2024 |
0.7.0 | Oct 7, 2024 |
0.6.0 | May 23, 2024 |
0.1.2 | Mar 7, 2023 |
#102 in WebAssembly
181 downloads per month
355KB
5K
SLoC
containerd-shim-wasm
A library to help build containerd shims for Wasm workloads.
Usage
There are two ways to implement a shim:
- Using the
Instance
trait - Using the
Engine
trait
What trait to use depends on how much control you need over the container lifecycle and the level of sandboxing you want to provide. The main difference is that the Engine
trait uses Youki's libcontainer
crate to manage the container lifecycle, such as creating the container, starting it, and deleting it, and youki handles container sandbox for you. The Instance
trait gives you more control over the container lifecycle.
Using the Engine trait
Implement the Engine
trait for a simpler integration:
use containerd_shim_wasm::{
container::{Instance, Engine, RuntimeContext},
sandbox::cli::{revision, shim_main, version},
Config,
};
use anyhow::Result;
#[derive(Clone, Default)]
struct MyEngine;
impl Engine for MyEngine {
fn name() -> &'static str {
"my-engine"
}
fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result<i32> {
// Implement your Wasm runtime logic here
Ok(0)
}
}
shim_main::<Instance<MyEngine>>(
"my-engine",
version!(),
revision!(),
"v1",
None,
);
The Engine
trait provides optional methods you can override:
can_handle()
- Validates that the runtime can run the container (checks Wasm file headers by default)supported_layers_types()
- Returns supported OCI layer typesprecompile()
- Allows precompilation of Wasm modulescan_precompile()
- Indicates if the runtime supports precompilation
Using the Instance trait directly
For more control, implement the Instance
trait:
use containerd_shim_wasm::sandbox::{Instance, InstanceConfig, Error};
use containerd_shim_wasm::container::{Engine, RuntimeContext};
use chrono::{DateTime, Utc};
use std::time::Duration;
use anyhow::Result;
#[derive(Clone, Default)]
struct MyEngine;
impl Engine for MyEngine {
fn name() -> &'static str {
"my-engine"
}
fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result<i32> {
Ok(0)
}
}
struct MyInstance {
engine: MyEngine,
}
impl Instance for MyInstance {
async fn new(id: String, cfg: &InstanceConfig) -> Result<Self, Error> {
Ok(MyInstance { engine: MyEngine })
}
async fn start(&self) -> Result<u32, Error> {
Ok(1)
}
async fn kill(&self, signal: u32) -> Result<(), Error> {
Ok(())
}
async fn delete(&self) -> Result<(), Error> {
Ok(())
}
async fn wait(&self) -> (u32, DateTime<Utc>) {
(0, Utc::now())
}
}
Running the shim
containerd expects the shim binary to be installed into $PATH
(as seen by the containerd process) with a binary name like containerd-shim-myshim-v1
which maps to the io.containerd.myshim.v1
runtime. It can be configured in containerd.
This crate is not tied to any specific wasm engine.
Check out these projects that build on top of runwasi:
Dependencies
~37–57MB
~1M SLoC