diff --git a/Cargo.lock b/Cargo.lock index 9dc931cc7..feccb1427 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -865,7 +865,6 @@ dependencies = [ "containerd-client", "containerd-shim", "containerd-shim-wasm-test-modules", - "crossbeam", "dbus", "env_logger", "futures", diff --git a/Cargo.toml b/Cargo.toml index 62a69ca55..4aeda8278 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,6 @@ containerd-shim = "0.7.4" containerd-shim-wasm = { path = "crates/containerd-shim-wasm", version = "0.8.0" } containerd-shim-wasm-test-modules = { path = "crates/containerd-shim-wasm-test-modules", version = "0.4.0"} oci-tar-builder = { path = "crates/oci-tar-builder", version = "0.4.0" } -crossbeam = { version = "0.8.4", default-features = false } env_logger = "0.11" libc = "0.2.169" libcontainer = { git = "https://github.com/youki-dev/youki.git", default-features = false } diff --git a/crates/containerd-shim-wamr/src/instance.rs b/crates/containerd-shim-wamr/src/instance.rs index 5e8231419..ff021343e 100644 --- a/crates/containerd-shim-wamr/src/instance.rs +++ b/crates/containerd-shim-wamr/src/instance.rs @@ -1,5 +1,5 @@ use anyhow::{Context, Result}; -use containerd_shim_wasm::container::{Engine, Entrypoint, Instance, RuntimeContext, Stdio}; +use containerd_shim_wasm::container::{Engine, Entrypoint, Instance, RuntimeContext}; use wamr_rust_sdk::function::Function; use wamr_rust_sdk::instance::Instance as WamrInst; use wamr_rust_sdk::module::Module; @@ -36,7 +36,7 @@ impl Engine for WamrEngine { "wamr" } - fn run_wasi(&self, ctx: &impl RuntimeContext, stdio: Stdio) -> Result { + fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result { let args = ctx.args(); let envs = ctx.envs(); let Entrypoint { @@ -73,9 +73,6 @@ impl Engine for WamrEngine { let instance = WamrInst::new(&self.runtime, &module, 1024 * 64) .context("Failed to create instance")?; - log::info!("redirect stdio"); - stdio.redirect()?; - log::info!("Running {func:?}"); let function = Function::find_export_func(&instance, &func).context("Failed to find function")?; diff --git a/crates/containerd-shim-wasm/CHANGELOG.md b/crates/containerd-shim-wasm/CHANGELOG.md index 8552e7275..394af6b26 100644 --- a/crates/containerd-shim-wasm/CHANGELOG.md +++ b/crates/containerd-shim-wasm/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### Changed - Reuse and synchronise access to `Container` object instead of reloading form disk ([#763](https://github.com/containerd/runwasi/pull/763)) +- Remove custom stdio redicrection: The `run_wasi` method doesn't receive the `Stdio` object anymore, and redirection is done before the method is called ([#788](https://github.com/containerd/runwasi/pull/788)) ### Removed - Removed `containerd_shim_wasm::sandbox::instance_utils::get_instance_root` and `containerd_shim_wasm::sandbox::instance_utils::instance_exists` functions ([#763](https://github.com/containerd/runwasi/pull/763)) diff --git a/crates/containerd-shim-wasm/Cargo.toml b/crates/containerd-shim-wasm/Cargo.toml index 6f453cf27..7be2866eb 100644 --- a/crates/containerd-shim-wasm/Cargo.toml +++ b/crates/containerd-shim-wasm/Cargo.toml @@ -17,7 +17,6 @@ chrono = { workspace = true } containerd-shim = { workspace = true } containerd-shim-wasm-test-modules = { workspace = true, optional = true } oci-tar-builder = { workspace = true, optional = true } -crossbeam = { workspace = true } env_logger = { workspace = true, optional = true } git-version = { version = "0.3.9" } libc = { workspace = true } diff --git a/crates/containerd-shim-wasm/src/container/engine.rs b/crates/containerd-shim-wasm/src/container/engine.rs index e45351739..0cbcec7ad 100644 --- a/crates/containerd-shim-wasm/src/container/engine.rs +++ b/crates/containerd-shim-wasm/src/container/engine.rs @@ -6,14 +6,13 @@ use anyhow::{bail, Context, Result}; use super::Source; use crate::container::{PathResolve, RuntimeContext}; use crate::sandbox::oci::WasmLayer; -use crate::sandbox::Stdio; pub trait Engine: Clone + Send + Sync + 'static { /// The name to use for this engine fn name() -> &'static str; /// Run a WebAssembly container - fn run_wasi(&self, ctx: &impl RuntimeContext, stdio: Stdio) -> Result; + fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result; /// Check that the runtime can run the container. /// This checks runs after the container creation and before the container starts. diff --git a/crates/containerd-shim-wasm/src/container/mod.rs b/crates/containerd-shim-wasm/src/container/mod.rs index 64e58870b..c78787d99 100644 --- a/crates/containerd-shim-wasm/src/container/mod.rs +++ b/crates/containerd-shim-wasm/src/container/mod.rs @@ -22,7 +22,6 @@ pub use instance::Instance; pub use path::PathResolve; pub use wasm::WasmBinaryType; -pub use crate::sandbox::stdio::Stdio; use crate::sys::container::instance; #[cfg(test)] diff --git a/crates/containerd-shim-wasm/src/container/tests.rs b/crates/containerd-shim-wasm/src/container/tests.rs index 5f0f19f7b..669bc88df 100644 --- a/crates/containerd-shim-wasm/src/container/tests.rs +++ b/crates/containerd-shim-wasm/src/container/tests.rs @@ -1,6 +1,6 @@ use anyhow::bail; -use crate::container::{Engine, RuntimeContext, Stdio}; +use crate::container::{Engine, RuntimeContext}; use crate::sys::container::instance::Instance; use crate::testing::WasiTest; @@ -14,7 +14,7 @@ impl Engine for EngineFailingValidation { fn can_handle(&self, _ctx: &impl RuntimeContext) -> anyhow::Result<()> { bail!("can't handle"); } - fn run_wasi(&self, _ctx: &impl RuntimeContext, _stdio: Stdio) -> anyhow::Result { + fn run_wasi(&self, _ctx: &impl RuntimeContext) -> anyhow::Result { Ok(0) } } diff --git a/crates/containerd-shim-wasm/src/sandbox/containerd/client.rs b/crates/containerd-shim-wasm/src/sandbox/containerd/client.rs index 74445fe64..97c61cdf0 100644 --- a/crates/containerd-shim-wasm/src/sandbox/containerd/client.rs +++ b/crates/containerd-shim-wasm/src/sandbox/containerd/client.rs @@ -602,7 +602,6 @@ mod tests { use super::*; use crate::container::RuntimeContext; - use crate::sandbox::Stdio; use crate::testing::oci_helpers::ImageContent; use crate::testing::{oci_helpers, TEST_NAMESPACE}; @@ -992,11 +991,7 @@ mod tests { "fake" } - fn run_wasi( - &self, - _ctx: &impl RuntimeContext, - _stdio: Stdio, - ) -> std::result::Result { + fn run_wasi(&self, _ctx: &impl RuntimeContext) -> std::result::Result { panic!("not implemented") } diff --git a/crates/containerd-shim-wasm/src/sandbox/mod.rs b/crates/containerd-shim-wasm/src/sandbox/mod.rs index 7ae7b1b74..062a14a52 100644 --- a/crates/containerd-shim-wasm/src/sandbox/mod.rs +++ b/crates/containerd-shim-wasm/src/sandbox/mod.rs @@ -5,13 +5,11 @@ pub mod error; pub mod instance; pub mod instance_utils; pub mod shim; -pub mod stdio; pub mod sync; pub use error::{Error, Result}; pub use instance::{Instance, InstanceConfig}; pub use shim::Cli as ShimCli; -pub use stdio::Stdio; pub(crate) mod containerd; pub(crate) mod oci; diff --git a/crates/containerd-shim-wasm/src/sandbox/stdio.rs b/crates/containerd-shim-wasm/src/sandbox/stdio.rs deleted file mode 100644 index afa31220f..000000000 --- a/crates/containerd-shim-wasm/src/sandbox/stdio.rs +++ /dev/null @@ -1,146 +0,0 @@ -use std::io::ErrorKind::NotFound; -use std::io::{Error, Result}; -use std::path::Path; -use std::sync::{Arc, OnceLock}; - -use super::InstanceConfig; -use crate::sys::stdio::*; - -#[derive(Default, Clone)] -pub struct Stdio { - pub stdin: Stdin, - pub stdout: Stdout, - pub stderr: Stderr, -} - -static INITIAL_STDIO: OnceLock = OnceLock::new(); - -impl Stdio { - pub fn redirect(self) -> Result<()> { - self.stdin.redirect()?; - self.stdout.redirect()?; - self.stderr.redirect()?; - Ok(()) - } - - pub fn take(&self) -> Self { - Self { - stdin: self.stdin.take(), - stdout: self.stdout.take(), - stderr: self.stderr.take(), - } - } - - pub fn init_from_cfg(cfg: &InstanceConfig) -> Result { - Ok(Self { - stdin: StdioStream::try_from_path(cfg.get_stdin())?, - stdout: StdioStream::try_from_path(cfg.get_stdout())?, - stderr: StdioStream::try_from_path(cfg.get_stderr())?, - }) - } - - pub fn init_from_std() -> Self { - Self { - stdin: Stdin::try_from_std().unwrap_or_default(), - stdout: Stdout::try_from_std().unwrap_or_default(), - stderr: Stderr::try_from_std().unwrap_or_default(), - } - } - - pub fn guard(self) -> impl Drop { - StdioGuard(self) - } -} - -struct StdioGuard(Stdio); - -impl Drop for StdioGuard { - fn drop(&mut self) { - let _ = self.0.take().redirect(); - } -} - -#[derive(Clone, Default)] -pub struct StdioStream(Arc); - -impl StdioStream { - pub fn redirect(self) -> Result<()> { - if let Some(fd) = self.0.as_raw_fd() { - // Before any redirection we try to keep a copy of the original stdio - // to make sure the streams stay open - INITIAL_STDIO.get_or_init(Stdio::init_from_std); - - if unsafe { libc::dup2(fd, FD) } == -1 { - return Err(Error::last_os_error()); - } - } - Ok(()) - } - - pub fn take(&self) -> Self { - Self(Arc::new(self.0.take())) - } - - pub fn try_from_std() -> Result { - let fd: i32 = unsafe { libc::dup(FD) }; - if fd == -1 { - return Err(Error::last_os_error()); - } - Ok(Self(Arc::new(unsafe { StdioOwnedFd::from_raw_fd(fd) }))) - } -} - -impl StdioStream { - fn try_from_path(path: impl AsRef) -> Result { - let path = path.as_ref(); - if path.as_os_str().is_empty() { - return Ok(Self(Arc::default())); - } - - let fd = match StdioOwnedFd::try_from_path(path) { - Err(err) if err.kind() == NotFound => Default::default(), - Err(err) => return Err(err), - Ok(fd) => fd, - }; - - Ok(Self(Arc::new(fd))) - } -} - -pub type Stdin = StdioStream; -pub type Stdout = StdioStream; -pub type Stderr = StdioStream; - -#[cfg(test)] -mod test { - use std::fs::File; - - use tempfile::tempdir; - - use super::*; - - /// containerd can send an empty path or a non-existent path - /// In both these cases we should just assume that the stdio stream was not setup (intentionally) - /// Any other error is a real error. - #[test] - fn test_maybe_open_stdio() -> anyhow::Result<()> { - // empty path - let s = Stdout::try_from_path("")?; - assert!(s.0.take().as_raw_fd().is_none()); - - // nonexistent path - let s = Stdout::try_from_path("/some/nonexistent/path")?; - assert!(s.0.take().as_raw_fd().is_none()); - - // valid path - let dir = tempdir()?; - let path = dir.path().join("testfile"); - let temp = File::create(&path)?; - drop(temp); - - // a valid path should not fail - let s = Stdout::try_from_path(path)?; - assert!(s.0.take().as_raw_fd().is_some()); - Ok(()) - } -} diff --git a/crates/containerd-shim-wasm/src/sys/unix/container/executor.rs b/crates/containerd-shim-wasm/src/sys/unix/container/executor.rs index 30da2f5dc..23326f78f 100644 --- a/crates/containerd-shim-wasm/src/sys/unix/container/executor.rs +++ b/crates/containerd-shim-wasm/src/sys/unix/container/executor.rs @@ -14,7 +14,7 @@ use libcontainer::workload::{ use oci_spec::image::Platform; use oci_spec::runtime::Spec; -use crate::container::{Engine, PathResolve, RuntimeContext, Source, Stdio, WasiContext}; +use crate::container::{Engine, PathResolve, RuntimeContext, Source, WasiContext}; use crate::sandbox::oci::WasmLayer; #[derive(Clone)] @@ -27,7 +27,6 @@ enum InnerExecutor { #[derive(Clone)] pub(crate) struct Executor { engine: E, - stdio: Stdio, inner: OnceCell, wasm_layers: Vec, platform: Platform, @@ -51,12 +50,11 @@ impl LibcontainerExecutor for Executor { InnerExecutor::CantHandle => Err(LibcontainerExecutorError::CantHandle(E::name())), InnerExecutor::Linux => { log::info!("executing linux container"); - self.stdio.take().redirect().unwrap(); DefaultExecutor {}.exec(spec) } InnerExecutor::Wasm => { log::info!("calling start function"); - match self.engine.run_wasi(&self.ctx(spec), self.stdio.take()) { + match self.engine.run_wasi(&self.ctx(spec)) { Ok(code) => std::process::exit(code), Err(err) => { log::info!("error running start function: {err}"); @@ -84,10 +82,9 @@ impl LibcontainerExecutor for Executor { } impl Executor { - pub fn new(engine: E, stdio: Stdio, wasm_layers: Vec, platform: Platform) -> Self { + pub fn new(engine: E, wasm_layers: Vec, platform: Platform) -> Self { Self { engine, - stdio, inner: Default::default(), wasm_layers, platform, diff --git a/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs b/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs index edff4811d..b14d45f85 100644 --- a/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs +++ b/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs @@ -20,9 +20,10 @@ use crate::sandbox::async_utils::AmbientRuntime as _; use crate::sandbox::instance_utils::determine_rootdir; use crate::sandbox::sync::WaitableCell; use crate::sandbox::{ - containerd, Error as SandboxError, Instance as SandboxInstance, InstanceConfig, Stdio, + containerd, Error as SandboxError, Instance as SandboxInstance, InstanceConfig, }; use crate::sys::container::executor::Executor; +use crate::sys::stdio::open; static DEFAULT_CONTAINER_ROOT_DIR: &str = "/run/containerd"; @@ -44,7 +45,6 @@ impl SandboxInstance for Instance { let namespace = cfg.get_namespace(); let rootdir = Path::new(DEFAULT_CONTAINER_ROOT_DIR).join(E::name()); let rootdir = determine_rootdir(&bundle, &namespace, rootdir)?; - let stdio = Stdio::init_from_cfg(cfg)?; // check if container is OCI image with wasm layers and attempt to read the module let (modules, platform) = containerd::Client::connect(cfg.get_containerd_address().as_str(), &namespace).block_on()? @@ -55,12 +55,21 @@ impl SandboxInstance for Instance { (vec![], Platform::default()) }); - let container = ContainerBuilder::new(id.clone(), SyscallType::Linux) - .with_executor(Executor::new(engine, stdio, modules, platform)) - .with_root_path(rootdir.clone())? - .as_init(&bundle) - .with_systemd(false) - .build()?; + let mut builder = ContainerBuilder::new(id.clone(), SyscallType::Linux) + .with_executor(Executor::new(engine, modules, platform)) + .with_root_path(rootdir.clone())?; + + if let Ok(f) = open(cfg.get_stdin()) { + builder = builder.with_stdin(f); + } + if let Ok(f) = open(cfg.get_stdout()) { + builder = builder.with_stdout(f); + } + if let Ok(f) = open(cfg.get_stderr()) { + builder = builder.with_stderr(f); + } + + let container = builder.as_init(&bundle).with_systemd(false).build()?; Ok(Self { id, diff --git a/crates/containerd-shim-wasm/src/sys/unix/stdio.rs b/crates/containerd-shim-wasm/src/sys/unix/stdio.rs index 51f4e9d8d..5784035a0 100644 --- a/crates/containerd-shim-wasm/src/sys/unix/stdio.rs +++ b/crates/containerd-shim-wasm/src/sys/unix/stdio.rs @@ -1,51 +1,7 @@ -use std::fs::OpenOptions; +use std::fs::{File, OpenOptions}; use std::io::Result; -use std::os::fd::{IntoRawFd, OwnedFd, RawFd}; use std::path::Path; -use crossbeam::atomic::AtomicCell; -pub use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; - -pub type StdioRawFd = RawFd; - -pub struct StdioOwnedFd(AtomicCell); - -impl Drop for StdioOwnedFd { - fn drop(&mut self) { - let fd = self.0.swap(-1); - if fd >= 0 { - unsafe { libc::close(fd) }; - } - } -} - -impl Default for StdioOwnedFd { - fn default() -> Self { - Self(AtomicCell::new(-1)) - } -} - -impl StdioOwnedFd { - pub fn try_from(f: impl Into) -> Result { - let fd = f.into().into_raw_fd(); - Ok(unsafe { Self::from_raw_fd(fd) }) - } - - pub unsafe fn from_raw_fd(fd: StdioRawFd) -> Self { - Self(AtomicCell::new(fd)) - } - - pub fn as_raw_fd(&self) -> Option { - let fd = self.0.load(); - (fd >= 0).then_some(fd) - } - - pub fn take(&self) -> Self { - let fd = self.0.swap(-1); - unsafe { Self::from_raw_fd(fd) } - } - - pub fn try_from_path(path: impl AsRef) -> Result { - Self::try_from(OpenOptions::new().read(true).write(true).open(path)?) - } +pub fn open(path: impl AsRef) -> Result { + OpenOptions::new().read(true).write(true).open(path) } diff --git a/crates/containerd-shim-wasm/src/sys/windows/stdio.rs b/crates/containerd-shim-wasm/src/sys/windows/stdio.rs index fb763b1b2..69e1e4ba4 100644 --- a/crates/containerd-shim-wasm/src/sys/windows/stdio.rs +++ b/crates/containerd-shim-wasm/src/sys/windows/stdio.rs @@ -1,69 +1,16 @@ -use std::fs::OpenOptions; -use std::io::ErrorKind::Other; -use std::io::{Error, Result}; -use std::os::windows::fs::OpenOptionsExt; -use std::os::windows::prelude::{AsRawHandle, IntoRawHandle, OwnedHandle}; +use std::fs::{File, OpenOptions}; +use std::io::Result; +use std::os::windows::fs::OpenOptionsExt as _; use std::path::Path; -use crossbeam::atomic::AtomicCell; -use libc::{intptr_t, open_osfhandle, O_APPEND}; use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_OVERLAPPED; -pub type StdioRawFd = libc::c_int; - -pub const STDIN_FILENO: StdioRawFd = 0; -pub const STDOUT_FILENO: StdioRawFd = 1; -pub const STDERR_FILENO: StdioRawFd = 2; - -pub struct StdioOwnedFd(AtomicCell); - -impl Drop for StdioOwnedFd { - fn drop(&mut self) { - let fd = self.0.swap(-1); - if fd >= 0 { - unsafe { libc::close(fd) }; - } - } -} - -impl Default for StdioOwnedFd { - fn default() -> Self { - Self(AtomicCell::new(-1)) - } -} - -impl StdioOwnedFd { - pub fn try_from(f: impl Into) -> Result { - let handle = f.into(); - let fd = unsafe { open_osfhandle(handle.as_raw_handle() as intptr_t, O_APPEND) }; - if fd == -1 { - return Err(Error::new(Other, "Failed to open file descriptor")); - } - let _ = handle.into_raw_handle(); // drop ownership of the handle, it's managed by fd now - Ok(unsafe { Self::from_raw_fd(fd) }) - } - - pub unsafe fn from_raw_fd(fd: StdioRawFd) -> Self { - Self(AtomicCell::new(fd)) - } - - pub fn as_raw_fd(&self) -> Option { - let fd = self.0.load(); - (fd >= 0).then_some(fd) - } - - pub fn take(&self) -> Self { - let fd = self.0.swap(-1); - unsafe { Self::from_raw_fd(fd) } - } - - pub fn try_from_path(path: impl AsRef) -> Result { - // Containerd always passes a named pipe for stdin, stdout, and stderr so we can check if it is a pipe and open with overlapped IO - let mut options = OpenOptions::new(); - options.read(true).write(true); - if path.as_ref().starts_with(r"\\.\pipe\") { - options.custom_flags(FILE_FLAG_OVERLAPPED); - } - Self::try_from(options.open(path)?) +pub fn open(path: impl AsRef) -> Result { + // Containerd always passes a named pipe for stdin, stdout, and stderr so we can check if it is a pipe and open with overlapped IO + let mut options = OpenOptions::new(); + options.read(true).write(true); + if path.as_ref().starts_with(r"\\.\pipe\") { + options.custom_flags(FILE_FLAG_OVERLAPPED); } + options.open(path) } diff --git a/crates/containerd-shim-wasm/src/test/signals.rs b/crates/containerd-shim-wasm/src/test/signals.rs index 6a223a5fa..54798592a 100644 --- a/crates/containerd-shim-wasm/src/test/signals.rs +++ b/crates/containerd-shim-wasm/src/test/signals.rs @@ -29,7 +29,6 @@ use containerd_shim_wasm_test_modules::HELLO_WORLD; use tokio::sync::Notify; use crate::container::{Engine, Instance, RuntimeContext}; -use crate::sandbox::Stdio; use crate::testing::WasiTest; #[derive(Clone, Default)] @@ -55,8 +54,7 @@ impl Engine for SomeEngine { "some-engine" } - fn run_wasi(&self, ctx: &impl RuntimeContext, stdio: Stdio) -> Result { - stdio.redirect()?; + fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result { let name = ctx.entrypoint().func; tokio::runtime::Builder::new_current_thread() .enable_all() diff --git a/crates/containerd-shim-wasmedge/src/instance.rs b/crates/containerd-shim-wasmedge/src/instance.rs index 1e20e2a65..95babe64d 100644 --- a/crates/containerd-shim-wasmedge/src/instance.rs +++ b/crates/containerd-shim-wasmedge/src/instance.rs @@ -1,5 +1,5 @@ use anyhow::{Context, Result}; -use containerd_shim_wasm::container::{Engine, Entrypoint, Instance, RuntimeContext, Stdio}; +use containerd_shim_wasm::container::{Engine, Entrypoint, Instance, RuntimeContext}; use wasmedge_sdk::config::{ConfigBuilder, HostRegistrationConfigOptions}; use wasmedge_sdk::plugin::PluginManager; use wasmedge_sdk::VmBuilder; @@ -29,7 +29,7 @@ impl Engine for WasmEdgeEngine { "wasmedge" } - fn run_wasi(&self, ctx: &impl RuntimeContext, stdio: Stdio) -> Result { + fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result { let args = ctx.args(); let envs = ctx.envs(); let Entrypoint { @@ -58,8 +58,6 @@ impl Engine for WasmEdgeEngine { .register_module_from_bytes(&mod_name, wasm_bytes) .context("registering module")?; - stdio.redirect()?; - log::debug!("running with method {func:?}"); vm.run_func(Some(&mod_name), func, vec![])?; diff --git a/crates/containerd-shim-wasmer/src/instance.rs b/crates/containerd-shim-wasmer/src/instance.rs index bb0c0968d..abfa83e5f 100644 --- a/crates/containerd-shim-wasmer/src/instance.rs +++ b/crates/containerd-shim-wasmer/src/instance.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use containerd_shim_wasm::container::{Engine, Entrypoint, Instance, RuntimeContext, Stdio}; +use containerd_shim_wasm::container::{Engine, Entrypoint, Instance, RuntimeContext}; use tokio::runtime::Handle; use wasmer::{Module, Store}; use wasmer_wasix::virtual_fs::host_fs::FileSystem; @@ -17,7 +17,7 @@ impl Engine for WasmerEngine { "wasmer" } - fn run_wasi(&self, ctx: &impl RuntimeContext, stdio: Stdio) -> Result { + fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result { let args = ctx.args(); let envs = ctx .envs() @@ -56,9 +56,6 @@ impl Engine for WasmerEngine { .preopen_dir("/")? .instantiate(module, &mut store)?; - log::info!("redirect stdio"); - stdio.redirect()?; - log::info!("Running {func:?}"); let start = instance.exports.get_function(&func)?; wasi_env.data(&store).thread.set_status_running(); diff --git a/crates/containerd-shim-wasmtime/src/instance.rs b/crates/containerd-shim-wasmtime/src/instance.rs index fc09c96b4..c782eb810 100644 --- a/crates/containerd-shim-wasmtime/src/instance.rs +++ b/crates/containerd-shim-wasmtime/src/instance.rs @@ -4,7 +4,7 @@ use std::marker::PhantomData; use anyhow::{bail, Context, Result}; use containerd_shim_wasm::container::{ - Engine, Entrypoint, Instance, RuntimeContext, Stdio, WasmBinaryType, + Engine, Entrypoint, Instance, RuntimeContext, WasmBinaryType, }; use containerd_shim_wasm::sandbox::WasmLayer; use tokio_util::sync::CancellationToken; @@ -137,7 +137,7 @@ impl Engine for WasmtimeEngine { "wasmtime" } - fn run_wasi(&self, ctx: &impl RuntimeContext, stdio: Stdio) -> Result { + fn run_wasi(&self, ctx: &impl RuntimeContext) -> Result { log::info!("setting up wasi"); let Entrypoint { source, @@ -147,7 +147,7 @@ impl Engine for WasmtimeEngine { } = ctx.entrypoint(); let wasm_bytes = &source.as_bytes()?; - self.execute(ctx, wasm_bytes, func, stdio).into_error_code() + self.execute(ctx, wasm_bytes, func).into_error_code() } fn precompile(&self, layers: &[WasmLayer]) -> Result>>> { @@ -199,7 +199,6 @@ where ctx: &impl RuntimeContext, module: Module, func: &String, - stdio: Stdio, ) -> Result { log::debug!("execute module"); @@ -224,8 +223,6 @@ where log::debug!("running start function {func:?}"); - stdio.redirect()?; - start_func .call_async(&mut store, &[], &mut []) .await @@ -238,7 +235,6 @@ where ctx: &impl RuntimeContext, component: Component, func: String, - stdio: Stdio, ) -> Result { log::info!("instantiating component"); @@ -247,8 +243,6 @@ where func.as_str(), ); - stdio.redirect()?; - // This is a adapter logic that converts wasip1 `_start` function to wasip2 `run` function. let status = match target { ComponentTarget::HttpProxy => { @@ -312,13 +306,12 @@ where ctx: &impl RuntimeContext, component: Component, func: String, - stdio: Stdio, ) -> Result { log::debug!("loading wasm component"); wasmtime_wasi::runtime::in_tokio(async move { tokio::select! { - status = self.execute_component_async(ctx, component, func, stdio) => { + status = self.execute_component_async(ctx, component, func) => { status } status = self.handle_signals() => { @@ -344,33 +337,27 @@ where wait_for_signal().await } - fn execute( - &self, - ctx: &impl RuntimeContext, - wasm_binary: &[u8], - func: String, - stdio: Stdio, - ) -> Result { + fn execute(&self, ctx: &impl RuntimeContext, wasm_binary: &[u8], func: String) -> Result { match WasmBinaryType::from_bytes(wasm_binary) { Some(WasmBinaryType::Module) => { log::debug!("loading wasm module"); let module = Module::from_binary(&self.engine, wasm_binary)?; - self.execute_module(ctx, module, &func, stdio) + self.execute_module(ctx, module, &func) } Some(WasmBinaryType::Component) => { let component = Component::from_binary(&self.engine, wasm_binary)?; - self.execute_component(ctx, component, func, stdio) + self.execute_component(ctx, component, func) } None => match &self.engine.detect_precompiled(wasm_binary) { Some(Precompiled::Module) => { log::info!("using precompiled module"); let module = unsafe { Module::deserialize(&self.engine, wasm_binary) }?; - self.execute_module(ctx, module, &func, stdio) + self.execute_module(ctx, module, &func) } Some(Precompiled::Component) => { log::info!("using precompiled component"); let component = unsafe { Component::deserialize(&self.engine, wasm_binary) }?; - self.execute_component(ctx, component, func, stdio) + self.execute_component(ctx, component, func) } None => { bail!("invalid precompiled module")