Skip to content

Commit

Permalink
implements can_handle in wasmtime executor.
Browse files Browse the repository at this point in the history
This commit implements can_handle in wasmtime executor. It checks
if the entrypoint binary has wasm as the path extension. If not,
the wasmtime executor will not be used.

It adds a default executor to the wasmtime shim as a backup
so it enables running wasm and containers side-by-side.

Add wat extension support in can_handle

Signed-off-by: jiaxiao zhou <[email protected]>
  • Loading branch information
Mossaka committed Jul 10, 2023
1 parent aaaea73 commit 558732d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 10 deletions.
33 changes: 30 additions & 3 deletions crates/containerd-shim-wasmtime/src/executor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use nix::unistd::{dup, dup2};
use std::{fs::OpenOptions, os::fd::RawFd};
use std::{fs::OpenOptions, os::fd::RawFd, path::PathBuf};

use anyhow::{anyhow, Result, Context};
use containerd_shim_wasm::sandbox::oci;
Expand Down Expand Up @@ -39,8 +39,35 @@ impl Executor for WasmtimeExecutor {
};
}

fn can_handle(&self, _spec: &Spec) -> bool {
true
fn can_handle(&self, spec: &Spec) -> bool {
// check if the entrypoint of the spec is a wasm binary.
let args = oci::get_args(spec);
if args.is_empty() {
return false;
}

let start = args[0].clone();
let mut iterator = start.split('#');
let mut cmd = iterator.next().unwrap().to_string();
let stripped = cmd.strip_prefix(std::path::MAIN_SEPARATOR);
if let Some(strpd) = stripped {
cmd = strpd.to_string();
}

let mut path = PathBuf::from(cmd);
if path.is_relative() {
path = std::env::current_dir().unwrap().join(path);
}

// TODO: do we need to validate the wasm binary?
// ```rust
// let bytes = std::fs::read(path).unwrap();
// wasmparser::validate(&bytes).is_ok()
// ```

path.extension()
.map(|ext| ext == "wasm" || ext == "wat")
.unwrap_or(false)
}

fn name(&self) -> &'static str {
Expand Down
37 changes: 30 additions & 7 deletions crates/containerd-shim-wasmtime/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use containerd_shim_wasm::sandbox::instance_utils::{
};
use libcontainer::container::builder::ContainerBuilder;
use libcontainer::container::{Container, ContainerStatus};
use libcontainer::workload::default::DefaultExecutor;
use nix::errno::Errno;
use nix::sys::wait::waitid;
use serde::{Deserialize, Serialize};
Expand All @@ -19,7 +20,7 @@ use chrono::{DateTime, Utc};
use containerd_shim_wasm::sandbox::error::Error;
use containerd_shim_wasm::sandbox::instance::Wait;
use containerd_shim_wasm::sandbox::{EngineGetter, Instance, InstanceConfig};
use libc::{dup2, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
use libc::{dup, dup2, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
use libc::{SIGINT, SIGKILL};
use libcontainer::syscall::syscall::create_syscall;
use log::error;
Expand Down Expand Up @@ -243,13 +244,35 @@ impl Wasi {
let stdout = maybe_open_stdio(stdout).context("could not open stdout")?;
let stderr = maybe_open_stdio(stderr).context("could not open stderr")?;

let wasmtime_executor = Box::new(WasmtimeExecutor {
engine,
stdin,
stdout,
stderr,
});
let default_executor = Box::<DefaultExecutor>::default();

if let Some(stdin) = stdin {
unsafe {
STDIN_FD = Some(dup(STDIN_FILENO));
dup2(stdin, STDIN_FILENO);
}
}
if let Some(stdout) = stdout {
unsafe {
STDOUT_FD = Some(dup(STDOUT_FILENO));
dup2(stdout, STDOUT_FILENO);
}
}
if let Some(stderr) = stderr {
unsafe {
STDERR_FD = Some(dup(STDERR_FILENO));
dup2(stderr, STDERR_FILENO);
}
}

let container = ContainerBuilder::new(self.id.clone(), syscall.as_ref())
.with_executor(vec![Box::new(WasmtimeExecutor {
stdin,
stdout,
stderr,
engine,
})])?
.with_executor(vec![wasmtime_executor, default_executor])?
.with_root_path(self.rootdir.clone())?
.as_init(&self.bundle)
.with_systemd(false)
Expand Down

0 comments on commit 558732d

Please sign in to comment.