Skip to content

Commit

Permalink
Merge pull request #691 from andreiltd/wasi-http
Browse files Browse the repository at this point in the history
feat(wasmtime): support wasi:http/proxy world in wasmtime shim
  • Loading branch information
Mossaka authored Oct 25, 2024
2 parents 4234ea6 + 528b738 commit 6180600
Show file tree
Hide file tree
Showing 17 changed files with 717 additions and 255 deletions.
345 changes: 218 additions & 127 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ wat = "1.214"
windows-sys = "0.52"
serial_test = "2"
tracing = "0.1"
hyper = "1.5.0"
tokio = { version = "1.40.0", default-features = false }

# wasmtime
wasmtime = { version = "25.0.1", features = ["async"] }
wasmtime-wasi = { version = "25.0.1" }
wasmtime = { version = "25.0.2", features = ["async"] }
wasmtime-wasi = { version = "25.0.2" }
wasmtime-wasi-http = { version = "25.0.2" }

[profile.release]
panic = "abort"
Binary file not shown.
5 changes: 4 additions & 1 deletion crates/containerd-shim-wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Unreleased]

### Added
- Support for wasi:http/proxy world in Wasmtime shim ([](https://github.com/containerd/runwasi/pull/691))

## [v0.7.0] — 2024-10-7

### Added
Expand Down Expand Up @@ -37,4 +40,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
- Removed dependency on `native-tls` ([#683](https://github.com/containerd/runwasi/pull/683)), note that the `opentelemetry` feature still depends on `native-tls`.

[Unreleased]: <https://github.com/containerd/runwasi/compare/containerd-shim-wasm/v0.7.0..HEAD>
[v0.7.0]: <https://github.com/containerd/runwasi/compare/containerd-shim-wasm/v0.6.0...containerd-shim-wasm/v0.7.0>
[v0.7.0]: <https://github.com/containerd/runwasi/compare/containerd-shim-wasm/v0.6.0...containerd-shim-wasm/v0.7.0>
2 changes: 1 addition & 1 deletion crates/containerd-shim-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ tempfile = { workspace = true, optional = true }
thiserror = { workspace = true }
ttrpc = { workspace = true }
wat = { workspace = true }
tokio = { version = "1.38.1", features = [ "full" ] }
tokio = { workspace = true, features = ["rt-multi-thread"] }
futures = { version = "0.3.30" }
wasmparser = "0.214.0"
tokio-stream = { version = "0.1" }
Expand Down
2 changes: 1 addition & 1 deletion crates/containerd-shim-wasm/src/container/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn test_validation_error() -> anyhow::Result<()> {
// as opposed to failing when starting it.

let result = WasiTest::<InstanceFailingValidation>::builder()?
.with_start_fn("foo")?
.with_start_fn("foo")
.with_wasm("/invalid_entrypoint.wasm")?
.build();

Expand Down
2 changes: 1 addition & 1 deletion crates/containerd-shim-wasm/src/sandbox/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub trait Instance: 'static {
/// This is called after the instance has exited.
fn delete(&self) -> Result<(), Error>;

/// Waits for the instance to finish and retunrs its exit code
/// Waits for the instance to finish and returns its exit code
/// This is a blocking call.
#[cfg_attr(feature = "tracing", tracing::instrument(skip(self), parent = tracing::Span::current(), level = "Info"))]
fn wait(&self) -> (u32, DateTime<Utc>) {
Expand Down
81 changes: 54 additions & 27 deletions crates/containerd-shim-wasm/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ use std::time::Duration;

use anyhow::{bail, Result};
pub use containerd_shim_wasm_test_modules as modules;
use oci_spec::runtime::{ProcessBuilder, RootBuilder, SpecBuilder};
use libc::SIGINT;
use oci_spec::runtime::{
get_default_namespaces, LinuxBuilder, LinuxNamespace, LinuxNamespaceType, ProcessBuilder,
RootBuilder, SpecBuilder,
};

use crate::sandbox::{Instance, InstanceConfig};
use crate::sys::signals::SIGKILL;
Expand All @@ -20,6 +24,8 @@ where
WasiInstance::Engine: Default + Send + Sync + Clone,
{
container_name: String,
start_fn: String,
namespaces: Vec<LinuxNamespace>,
tempdir: tempfile::TempDir,
_phantom: PhantomData<WasiInstance>,
}
Expand Down Expand Up @@ -58,40 +64,29 @@ where
write(dir.join("stderr"), "")?;

let builder = Self {
container_name: "test".to_string(),
tempdir,
container_name: "test".to_string(),
start_fn: "".to_string(),
namespaces: get_default_namespaces(),
_phantom: Default::default(),
}
.with_wasm([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])?
.with_start_fn("")?
.with_stdin("")?;

Ok(builder)
}

pub fn with_start_fn(self, start_fn: impl AsRef<str>) -> Result<Self> {
let dir = self.tempdir.path();
let start_fn = start_fn.as_ref();

log::info!("setting wasi test start_fn to {start_fn:?}");

let entrypoint = match start_fn {
"" => "/hello.wasm".to_string(),
s => "/hello.wasm#".to_string().add(s),
};
let spec = SpecBuilder::default()
.root(RootBuilder::default().path("rootfs").build()?)
.process(
ProcessBuilder::default()
.cwd("/")
.args([entrypoint])
.build()?,
)
.build()?;

spec.save(dir.join("config.json"))?;
pub fn with_host_network(mut self) -> Self {
// Removing the `network` namespace results in the binding to the host's socket.
// This allows for direct communication with the host's networking interface.
self.namespaces
.retain(|ns| ns.typ() != LinuxNamespaceType::Network);
self
}

Ok(self)
pub fn with_start_fn(mut self, start_fn: impl AsRef<str>) -> Self {
start_fn.as_ref().clone_into(&mut self.start_fn);
self
}

pub fn with_wasm(self, wasmbytes: impl AsRef<[u8]>) -> Result<Self> {
Expand Down Expand Up @@ -155,7 +150,31 @@ where
let tempdir = self.tempdir;
let dir = tempdir.path();

log::info!("building wasi test");
log::info!("setting wasi test start_fn to {}", self.start_fn);

let entrypoint = match self.start_fn.as_str() {
"" => "/hello.wasm".to_string(),
s => "/hello.wasm#".to_string().add(s),
};

let spec = SpecBuilder::default()
.root(RootBuilder::default().path("rootfs").build()?)
.linux(
LinuxBuilder::default()
.namespaces(self.namespaces)
.build()?,
)
.process(
ProcessBuilder::default()
.cwd("/")
.args([entrypoint])
.build()?,
)
.build()?;

spec.save(dir.join("config.json"))?;

log::info!("building wasi test: {}", dir.display());

let mut cfg = InstanceConfig::new(
WasiInstance::Engine::default(),
Expand Down Expand Up @@ -186,7 +205,9 @@ where

pub fn start(&self) -> Result<&Self> {
log::info!("starting wasi test");
self.instance.start()?;
let pid = self.instance.start()?;
log::info!("wasi test pid {pid}");

Ok(self)
}

Expand All @@ -196,6 +217,12 @@ where
Ok(self)
}

pub fn ctrl_c(&self) -> Result<&Self> {
log::info!("sending SIGINT");
self.instance.kill(SIGINT as u32)?;
Ok(self)
}

pub fn wait(&self, timeout: Duration) -> Result<(u32, String, String)> {
let dir = self.tempdir.path();

Expand Down
2 changes: 1 addition & 1 deletion crates/containerd-shim-wasmedge/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn test_hello_world_oci() -> anyhow::Result<()> {
#[serial]
fn test_custom_entrypoint() -> anyhow::Result<()> {
let (exit_code, stdout, _) = WasiTest::<WasiInstance>::builder()?
.with_start_fn("foo")?
.with_start_fn("foo")
.with_wasm(CUSTOM_ENTRYPOINT)?
.build()?
.start()?
Expand Down
4 changes: 2 additions & 2 deletions crates/containerd-shim-wasmer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ edition.workspace = true
anyhow = { workspace = true }
containerd-shim-wasm = { workspace = true }
log = { workspace = true }
tokio = { workspace = true }

tokio = "1.38.1"
wasmer = { version = "4.1.2" }
wasmer-wasix = { version = "0.12.0" }
mio = { version = "0.8.11", features = ["net"] }
Expand All @@ -22,4 +22,4 @@ name = "containerd-shim-wasmer-v1"
path = "src/main.rs"

[package.metadata.cargo-machete]
ignored = ["mio"] # wasmer depends on mio but the latest version of mio moved features behind a feature flag
ignored = ["mio"] # wasmer depends on mio but the latest version of mio moved features behind a feature flag
2 changes: 1 addition & 1 deletion crates/containerd-shim-wasmer/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn test_hello_world_oci() -> anyhow::Result<()> {
#[serial]
fn test_custom_entrypoint() -> anyhow::Result<()> {
let (exit_code, stdout, _) = WasiTest::<WasiInstance>::builder()?
.with_start_fn("foo")?
.with_start_fn("foo")
.with_wasm(CUSTOM_ENTRYPOINT)?
.build()?
.start()?
Expand Down
5 changes: 5 additions & 0 deletions crates/containerd-shim-wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ edition.workspace = true
anyhow = { workspace = true }
containerd-shim-wasm = { workspace = true, features = ["opentelemetry"] }
log = { workspace = true }
hyper = { workspace = true }
tokio = { workspace = true, features = ["signal", "macros"] }
libc = { workspace = true }

wasmtime = { workspace = true }
wasmtime-wasi = { workspace = true }
wasmtime-wasi-http = { workspace = true }

[dev-dependencies]
containerd-shim-wasm = { workspace = true, features = ["testing"] }
serial_test = { workspace = true }
reqwest = { version = "0.12", default-features=false, features = ["blocking"] }

[[bin]]
name = "containerd-shim-wasmtime-v1"
Expand Down
Loading

0 comments on commit 6180600

Please sign in to comment.