1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-06-01 20:36:12 +02:00

Merge pull request #1403 from utam0k/exec-manager

libcontainer: Make the workloads injectable
This commit is contained in:
Thomas Schubart 2023-03-13 10:23:05 +01:00 committed by GitHub
commit 4e029b0d46
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 212 additions and 93 deletions

14
Cargo.lock generated
View File

@ -349,9 +349,9 @@ dependencies = [
[[package]]
name = "clap_complete"
version = "4.1.2"
version = "4.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd125be87bf4c255ebc50de0b7f4d2a6201e8ac3dc86e39c0ad081dc5e7236fe"
checksum = "0012995dc3a54314f4710f5631d74767e73c534b8757221708303e48eef7a19b"
dependencies = [
"clap",
]
@ -1642,11 +1642,6 @@ dependencies = [
"serde_json",
"serial_test",
"syscalls",
"wasmedge-sdk",
"wasmer",
"wasmer-wasi",
"wasmtime",
"wasmtime-wasi",
]
[[package]]
@ -4273,6 +4268,11 @@ dependencies = [
"serial_test",
"tabwriter",
"vergen",
"wasmedge-sdk",
"wasmer",
"wasmer-wasi",
"wasmtime",
"wasmtime-wasi",
]
[[package]]

View File

@ -37,7 +37,7 @@ libc = { version = "0.2.140", optional = true }
oci-spec = { version = "^0.6.0", features = ["proptests", "runtime"] }
quickcheck = "1"
mockall = { version = "0.11.3", features = [] }
clap = "4.0.32"
clap = "4.1.6"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
env_logger = "0.10"

View File

@ -13,9 +13,6 @@ keywords = ["youki", "container", "cgroups"]
[features]
default = ["systemd", "v2", "v1"]
wasm-wasmer = ["wasmer", "wasmer-wasi"]
wasm-wasmedge = ["wasmedge-sdk/standalone"]
wasm-wasmtime = ["wasmtime", "wasmtime-wasi"]
systemd = ["libcgroups/systemd", "v2"]
v2 = ["libcgroups/v2"]
v1 = ["libcgroups/v1"]
@ -43,11 +40,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
syscalls = "0.6.7"
rust-criu = "0.4.0"
wasmer = { version = "2.2.0", optional = true }
wasmer-wasi = { version = "2.3.0", optional = true }
wasmedge-sdk = { version = "0.7.1", optional = true }
wasmtime = {version = "6.0.1", optional = true }
wasmtime-wasi = {version = "6.0.1", optional = true }
clone3 = "0.2.3"
[dev-dependencies]

View File

@ -1,5 +1,7 @@
use crate::workload::default::DefaultExecutor;
use crate::workload::{Executor, ExecutorManager};
use crate::{syscall::Syscall, utils::PathBufExt};
use anyhow::{anyhow, Context, Result};
use anyhow::{anyhow, bail, Context, Result};
use std::path::PathBuf;
use super::{init_builder::InitContainerBuilder, tenant_builder::TenantContainerBuilder};
@ -18,6 +20,9 @@ pub struct ContainerBuilder<'a> {
pub(super) console_socket: Option<PathBuf>,
/// File descriptors to be passed into the container process
pub(super) preserve_fds: i32,
/// Manage the functions that actually run on the container
/// Default executes the specified execution of a generic command
pub(super) executor_manager: ExecutorManager,
}
/// Builder that can be used to configure the common properties of
@ -28,8 +33,12 @@ pub struct ContainerBuilder<'a> {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .with_root_path("/run/containers/youki").expect("invalid root path")
/// .with_pid_file(Some("/var/run/docker.pid")).expect("invalid pid file")
/// .with_console_socket(Some("/var/run/docker/sock.tty"))
@ -45,8 +54,12 @@ impl<'a> ContainerBuilder<'a> {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
///
/// let builder = ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref());
/// let builder = ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// );
/// ```
pub fn new(container_id: String, syscall: &'a dyn Syscall) -> Self {
let root_path = PathBuf::from("/run/youki");
@ -57,6 +70,9 @@ impl<'a> ContainerBuilder<'a> {
pid_file: None,
console_socket: None,
preserve_fds: 0,
executor_manager: ExecutorManager {
executors: vec![Box::<DefaultExecutor>::default()],
},
}
}
@ -100,8 +116,12 @@ impl<'a> ContainerBuilder<'a> {
/// ```no_run
/// # use libcontainer::container::builder::ContainerBuilder;
/// # use libcontainer::syscall::syscall::create_syscall;
/// # use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_tenant()
/// .with_container_args(vec!["sleep".to_owned(), "9001".to_owned()])
/// .build();
@ -117,8 +137,12 @@ impl<'a> ContainerBuilder<'a> {
/// ```no_run
/// # use libcontainer::container::builder::ContainerBuilder;
/// # use libcontainer::syscall::syscall::create_syscall;
/// # use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_init("/var/run/docker/bundle")
/// .with_systemd(false)
/// .build();
@ -134,8 +158,12 @@ impl<'a> ContainerBuilder<'a> {
/// ```no_run
/// # use libcontainer::container::builder::ContainerBuilder;
/// # use libcontainer::syscall::syscall::create_syscall;
/// # use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .with_root_path("/run/containers/youki").expect("invalid root path");
/// ```
pub fn with_root_path<P: Into<PathBuf>>(mut self, path: P) -> Result<Self> {
@ -154,8 +182,12 @@ impl<'a> ContainerBuilder<'a> {
/// ```no_run
/// # use libcontainer::container::builder::ContainerBuilder;
/// # use libcontainer::syscall::syscall::create_syscall;
/// # use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .with_pid_file(Some("/var/run/docker.pid")).expect("invalid pid file");
/// ```
pub fn with_pid_file<P: Into<PathBuf>>(mut self, path: Option<P>) -> Result<Self> {
@ -180,8 +212,12 @@ impl<'a> ContainerBuilder<'a> {
/// ```no_run
/// # use libcontainer::container::builder::ContainerBuilder;
/// # use libcontainer::syscall::syscall::create_syscall;
/// # use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .with_console_socket(Some("/var/run/docker/sock.tty"));
/// ```
pub fn with_console_socket<P: Into<PathBuf>>(mut self, path: Option<P>) -> Self {
@ -196,14 +232,40 @@ impl<'a> ContainerBuilder<'a> {
/// ```no_run
/// # use libcontainer::container::builder::ContainerBuilder;
/// # use libcontainer::syscall::syscall::create_syscall;
/// # use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .with_preserved_fds(5);
/// ```
pub fn with_preserved_fds(mut self, preserved_fds: i32) -> Self {
self.preserve_fds = preserved_fds;
self
}
/// Sets the number of additional file descriptors which will be passed into
/// the container process.
/// # Example
///
/// ```no_run
/// # use libcontainer::container::builder::ContainerBuilder;
/// # use libcontainer::syscall::syscall::create_syscall;
/// # use libcontainer::workload::default::DefaultExecutor;
///
/// ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .with_executor(vec![Box::<DefaultExecutor>::default()]);
/// ```
pub fn with_executor(mut self, executors: Vec<Box<dyn Executor>>) -> Result<Self> {
if executors.is_empty() {
bail!("executors must not be empty");
};
self.executor_manager = ExecutorManager { executors };
Ok(self)
}
}
#[cfg(test)]

View File

@ -9,6 +9,7 @@ use crate::{
rootless::Rootless,
syscall::Syscall,
utils,
workload::ExecutorManager,
};
use anyhow::{bail, Context, Result};
use nix::unistd::Pid;
@ -43,6 +44,8 @@ pub(super) struct ContainerBuilderImpl<'a> {
pub preserve_fds: i32,
/// If the container is to be run in detached mode
pub detached: bool,
/// Default executes the specified execution of a generic command
pub executor_manager: ExecutorManager,
}
impl<'a> ContainerBuilderImpl<'a> {
@ -126,6 +129,7 @@ impl<'a> ContainerBuilderImpl<'a> {
rootless: &self.rootless,
cgroup_manager: cmanager,
detached: self.detached,
executor_manager: &self.executor_manager,
};
let init_pid = process::container_main_process::container_main_process(&container_args)?;

View File

@ -14,9 +14,13 @@ impl Container {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
///
/// # fn main() -> anyhow::Result<()> {
/// let mut container = ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// let mut container = ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_init("/var/run/docker/bundle")
/// .build()?;
///

View File

@ -11,9 +11,13 @@ impl Container {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
///
/// # fn main() -> anyhow::Result<()> {
/// let mut container = ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// let mut container = ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_init("/var/run/docker/bundle")
/// .build()?;
///

View File

@ -12,10 +12,14 @@ impl Container {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
/// use nix::sys::signal::Signal;
///
/// # fn main() -> anyhow::Result<()> {
/// let mut container = ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// let mut container = ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_init("/var/run/docker/bundle")
/// .build()?;
///

View File

@ -10,9 +10,13 @@ impl Container {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
///
/// # fn main() -> anyhow::Result<()> {
/// let mut container = ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// let mut container = ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_init("/var/run/docker/bundle")
/// .build()?;
///

View File

@ -11,9 +11,13 @@ impl Container {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
///
/// # fn main() -> anyhow::Result<()> {
/// let mut container = ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// let mut container = ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_init("/var/run/docker/bundle")
/// .build()?;
///

View File

@ -16,9 +16,13 @@ impl Container {
/// ```no_run
/// use libcontainer::container::builder::ContainerBuilder;
/// use libcontainer::syscall::syscall::create_syscall;
/// use libcontainer::workload::default::DefaultExecutor;
///
/// # fn main() -> anyhow::Result<()> {
/// let mut container = ContainerBuilder::new("74f1a4cb3801".to_owned(), create_syscall().as_ref())
/// let mut container = ContainerBuilder::new(
/// "74f1a4cb3801".to_owned(),
/// create_syscall().as_ref(),
/// )
/// .as_init("/var/run/docker/bundle")
/// .build()?;
///

View File

@ -94,6 +94,7 @@ impl<'a> InitContainerBuilder<'a> {
// given. For now, set the detached to true because this is what
// `youki create` defaults to.
detached: true,
executor_manager: self.base.executor_manager,
};
// TODO: Fix waiting on this pid (init process) when detached = false.

View File

@ -144,6 +144,7 @@ impl<'a> TenantContainerBuilder<'a> {
container: None,
preserve_fds: self.base.preserve_fds,
detached: self.detached,
executor_manager: self.base.executor_manager,
};
let pid = builder_impl.create()?;

View File

@ -4,6 +4,7 @@ use std::os::unix::prelude::RawFd;
use std::path::PathBuf;
use crate::rootless::Rootless;
use crate::workload::ExecutorManager;
use crate::{container::Container, notify_socket::NotifyListener, syscall::Syscall};
#[derive(Debug, Copy, Clone)]
@ -35,4 +36,6 @@ pub struct ContainerArgs<'a> {
pub cgroup_manager: Box<dyn CgroupManager>,
/// If the container is to be run in detached mode
pub detached: bool,
/// Manage the functions that actually run on the container
pub executor_manager: &'a ExecutorManager,
}

View File

@ -1,7 +1,6 @@
use super::args::{ContainerArgs, ContainerType};
use crate::apparmor;
use crate::syscall::Syscall;
use crate::workload::ExecutorManager;
use crate::{
capabilities, hooks, namespaces::Namespaces, process::channel, rootfs::RootFS,
rootless::Rootless, seccomp, tty, utils,
@ -442,7 +441,8 @@ pub fn container_init_process(
}
if proc.args().is_some() {
ExecutorManager::exec(spec)
args.executor_manager.exec(spec)?;
unreachable!("should not be back here");
} else {
bail!("on non-Windows, at least one process arg entry is required")
}

View File

@ -8,10 +8,11 @@ use super::{Executor, EMPTY};
const EXECUTOR_NAME: &str = "default";
#[derive(Default)]
pub struct DefaultExecutor {}
impl Executor for DefaultExecutor {
fn exec(spec: &Spec) -> Result<()> {
fn exec(&self, spec: &Spec) -> Result<()> {
log::debug!("Executing workload with default handler");
let args = spec
.process()
@ -37,11 +38,11 @@ impl Executor for DefaultExecutor {
unreachable!();
}
fn can_handle(_: &Spec) -> Result<bool> {
fn can_handle(&self, _: &Spec) -> Result<bool> {
Ok(true)
}
fn name() -> &'static str {
fn name(&self) -> &'static str {
EXECUTOR_NAME
}
}

View File

@ -1,51 +1,37 @@
use anyhow::{Context, Result};
use anyhow::{bail, Context, Result};
use oci_spec::runtime::Spec;
use self::default::DefaultExecutor;
#[cfg(feature = "wasm-wasmedge")]
use self::wasmedge::WasmEdgeExecutor;
#[cfg(feature = "wasm-wasmer")]
use self::wasmer::WasmerExecutor;
#[cfg(feature = "wasm-wasmtime")]
use self::wasmtime::WasmtimeExecutor;
pub mod default;
#[cfg(feature = "wasm-wasmedge")]
pub mod wasmedge;
#[cfg(feature = "wasm-wasmer")]
pub mod wasmer;
#[cfg(feature = "wasm-wasmtime")]
pub mod wasmtime;
static EMPTY: Vec<String> = Vec::new();
pub static EMPTY: Vec<String> = Vec::new();
pub trait Executor {
/// Executes the workload
fn exec(spec: &Spec) -> Result<()>;
fn exec(&self, spec: &Spec) -> Result<()>;
/// Checks if the handler is able to handle the workload
fn can_handle(spec: &Spec) -> Result<bool>;
fn can_handle(&self, spec: &Spec) -> Result<bool>;
/// The name of the handler
fn name() -> &'static str;
fn name(&self) -> &'static str;
}
/// Manage the functions that actually run on the container
pub struct ExecutorManager {
pub executors: Vec<Box<dyn Executor>>,
}
pub struct ExecutorManager {}
impl ExecutorManager {
pub fn exec(spec: &Spec) -> Result<()> {
#[cfg(feature = "wasm-wasmer")]
if WasmerExecutor::can_handle(spec)? {
return WasmerExecutor::exec(spec).context("wasmer execution failed");
}
pub fn exec(&self, spec: &Spec) -> Result<()> {
if self.executors.is_empty() {
bail!("executors must not be empty");
};
#[cfg(feature = "wasm-wasmedge")]
if WasmEdgeExecutor::can_handle(spec)? {
return WasmEdgeExecutor::exec(spec).context("wasmedge execution failed");
for executor in self.executors.iter() {
if executor.can_handle(spec)? {
return executor.exec(spec).context("execution failed");
}
}
#[cfg(feature = "wasm-wasmtime")]
if WasmtimeExecutor::can_handle(spec)? {
return WasmtimeExecutor::exec(spec).context("wasmtime execution failed");
}
DefaultExecutor::exec(spec).context("default execution failed")
bail!("cannot find an executor that satisfies all requirements")
}
}

View File

@ -11,6 +11,6 @@ edition = "2021"
keywords = ["youki", "container", "oci"]
[dependencies.clap]
version = "4.0.32"
version = "4.1.6"
default-features = false
features = ["std", "suggestions", "derive", "cargo", "help", "usage", "error-context"]

View File

@ -16,12 +16,12 @@ systemd = ["libcgroups/systemd", "libcontainer/systemd", "v2"]
v2 = ["libcgroups/v2", "libcontainer/v2"]
v1 = ["libcgroups/v1", "libcontainer/v1"]
cgroupsv2_devices = ["libcgroups/cgroupsv2_devices", "libcontainer/cgroupsv2_devices"]
wasm-wasmer = ["libcontainer/wasm-wasmer"]
wasm-wasmedge = ["libcontainer/wasm-wasmedge"]
wasm-wasmtime = ["libcontainer/wasm-wasmtime"]
wasm-wasmer = ["wasmer", "wasmer-wasi"]
wasm-wasmedge = ["wasmedge-sdk/standalone"]
wasm-wasmtime = ["wasmtime", "wasmtime-wasi"]
[dependencies.clap]
version = "4.0.32"
version = "4.1.6"
default-features = false
features = ["std", "suggestions", "derive", "cargo", "help", "usage", "error-context"]
@ -40,8 +40,13 @@ procfs = "0.15.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tabwriter = "1"
clap_complete = "4.0.7"
clap_complete = "4.1.3"
caps = "0.5.5"
wasmer = { version = "2.2.0", optional = true }
wasmer-wasi = { version = "2.3.0", optional = true }
wasmedge-sdk = { version = "0.7.1", optional = true }
wasmtime = {version = "6.0.1", optional = true }
wasmtime-wasi = {version = "6.0.1", optional = true }
[dev-dependencies]
serial_test = "1.0.0"

View File

@ -5,6 +5,8 @@ use std::path::PathBuf;
use libcontainer::{container::builder::ContainerBuilder, syscall::syscall::create_syscall};
use liboci_cli::Create;
use crate::workload::executor::default_executors;
// One thing to note is that in the end, container is just another process in Linux
// it has specific/different control group, namespace, using which program executing in it
// can be given impression that is is running on a complete system, but on the system which
@ -13,6 +15,7 @@ use liboci_cli::Create;
pub fn create(args: Create, root_path: PathBuf, systemd_cgroup: bool) -> Result<()> {
let syscall = create_syscall();
ContainerBuilder::new(args.container_id.clone(), syscall.as_ref())
.with_executor(default_executors())?
.with_pid_file(args.pid_file.as_ref())?
.with_console_socket(args.console_socket.as_ref())
.with_root_path(root_path)?

View File

@ -5,9 +5,12 @@ use std::path::PathBuf;
use libcontainer::{container::builder::ContainerBuilder, syscall::syscall::create_syscall};
use liboci_cli::Exec;
use crate::workload::executor::default_executors;
pub fn exec(args: Exec, root_path: PathBuf) -> Result<i32> {
let syscall = create_syscall();
let pid = ContainerBuilder::new(args.container_id.clone(), syscall.as_ref())
.with_executor(default_executors())?
.with_root_path(root_path)?
.with_console_socket(args.console_socket.as_ref())
.with_pid_file(args.pid_file.as_ref())?

View File

@ -4,11 +4,14 @@ use anyhow::{Context, Result};
use libcontainer::{container::builder::ContainerBuilder, syscall::syscall::create_syscall};
use liboci_cli::Run;
use crate::workload::executor::default_executors;
pub fn run(args: Run, root_path: PathBuf, systemd_cgroup: bool) -> Result<()> {
let syscall = create_syscall();
// TODO: `youki run` should support passing in `detached` flags. Defaults to
// detached = true right now.
let mut container = ContainerBuilder::new(args.container_id.clone(), syscall.as_ref())
.with_executor(default_executors())?
.with_pid_file(args.pid_file.as_ref())?
.with_console_socket(args.console_socket.as_ref())
.with_root_path(root_path)?

View File

@ -3,6 +3,7 @@
//! This crate provides a container runtime which can be used by a high-level container runtime to run containers.
mod commands;
mod logger;
mod workload;
use anyhow::bail;
use anyhow::Context;

View File

@ -0,0 +1,13 @@
use libcontainer::workload::{default::DefaultExecutor, Executor};
pub fn default_executors() -> Vec<Box<dyn Executor>> {
vec![
#[cfg(feature = "wasm-wasmer")]
Box::<super::wasmer::WasmerExecutor>::default(),
#[cfg(feature = "wasm-wasmedge")]
Box::<super::wasmedge::WasmEdgeExecutor>::default(),
#[cfg(feature = "wasm-wasmtime")]
Box::<super::wasmtime::WasmtimeExecutor>::default(),
Box::<DefaultExecutor>::default(),
]
}

View File

@ -0,0 +1,7 @@
pub mod executor;
#[cfg(feature = "wasm-wasmedge")]
mod wasmedge;
#[cfg(feature = "wasm-wasmer")]
mod wasmer;
#[cfg(feature = "wasm-wasmtime")]
mod wasmtime;

View File

@ -5,13 +5,15 @@ use wasmedge_sdk::{
params, Vm,
};
use super::Executor;
use libcontainer::workload::Executor;
const EXECUTOR_NAME: &str = "wasmedge";
#[derive(Default)]
pub struct WasmEdgeExecutor {}
impl Executor for WasmEdgeExecutor {
fn exec(spec: &Spec) -> Result<()> {
fn exec(&self, spec: &Spec) -> Result<()> {
// parse wasi parameters
let args = get_args(spec);
let mut cmd = args[0].clone();
@ -46,7 +48,7 @@ impl Executor for WasmEdgeExecutor {
Ok(())
}
fn can_handle(spec: &Spec) -> Result<bool> {
fn can_handle(&self, spec: &Spec) -> Result<bool> {
if let Some(annotations) = spec.annotations() {
if let Some(handler) = annotations.get("run.oci.handler") {
return Ok(handler == "wasm");
@ -60,7 +62,7 @@ impl Executor for WasmEdgeExecutor {
Ok(false)
}
fn name() -> &'static str {
fn name(&self) -> &'static str {
EXECUTOR_NAME
}
}

View File

@ -3,14 +3,15 @@ use oci_spec::runtime::Spec;
use wasmer::{Instance, Module, Store};
use wasmer_wasi::WasiState;
use super::{Executor, EMPTY};
use libcontainer::workload::{Executor, EMPTY};
const EXECUTOR_NAME: &str = "wasmer";
#[derive(Default)]
pub struct WasmerExecutor {}
impl Executor for WasmerExecutor {
fn exec(spec: &Spec) -> Result<()> {
fn exec(&self, spec: &Spec) -> Result<()> {
log::debug!("Executing workload with wasmer handler");
let process = spec.process().as_ref();
@ -62,7 +63,7 @@ impl Executor for WasmerExecutor {
Ok(())
}
fn can_handle(spec: &Spec) -> Result<bool> {
fn can_handle(&self, spec: &Spec) -> Result<bool> {
if let Some(annotations) = spec.annotations() {
if let Some(handler) = annotations.get("run.oci.handler") {
return Ok(handler == "wasm");
@ -76,7 +77,7 @@ impl Executor for WasmerExecutor {
Ok(false)
}
fn name() -> &'static str {
fn name(&self) -> &'static str {
EXECUTOR_NAME
}
}
@ -96,7 +97,9 @@ mod tests {
.build()
.context("build spec")?;
assert!(WasmerExecutor::can_handle(&spec).context("can handle")?);
assert!(WasmerExecutor::default()
.can_handle(&spec)
.context("can handle")?);
Ok(())
}
@ -110,7 +113,9 @@ mod tests {
.build()
.context("build spec")?;
assert!(WasmerExecutor::can_handle(&spec).context("can handle")?);
assert!(WasmerExecutor::default()
.can_handle(&spec)
.context("can handle")?);
Ok(())
}
@ -119,7 +124,9 @@ mod tests {
fn test_can_handle_no_execute() -> Result<()> {
let spec = SpecBuilder::default().build().context("build spec")?;
assert!(!WasmerExecutor::can_handle(&spec).context("can handle")?);
assert!(!WasmerExecutor::default()
.can_handle(&spec)
.context("can handle")?);
Ok(())
}

View File

@ -3,14 +3,15 @@ use oci_spec::runtime::Spec;
use wasmtime::*;
use wasmtime_wasi::WasiCtxBuilder;
use super::{Executor, EMPTY};
use libcontainer::workload::{Executor, EMPTY};
const EXECUTOR_NAME: &str = "wasmtime";
#[derive(Default)]
pub struct WasmtimeExecutor {}
impl Executor for WasmtimeExecutor {
fn exec(spec: &Spec) -> Result<()> {
fn exec(&self, spec: &Spec) -> Result<()> {
log::info!("Executing workload with wasmtime handler");
let process = spec.process().as_ref();
@ -76,7 +77,7 @@ impl Executor for WasmtimeExecutor {
.context("wasm module was not executed successfully")
}
fn can_handle(spec: &Spec) -> Result<bool> {
fn can_handle(&self, spec: &Spec) -> Result<bool> {
if let Some(annotations) = spec.annotations() {
if let Some(handler) = annotations.get("run.oci.handler") {
return Ok(handler == "wasm");
@ -90,7 +91,7 @@ impl Executor for WasmtimeExecutor {
Ok(false)
}
fn name() -> &'static str {
fn name(&self) -> &'static str {
EXECUTOR_NAME
}
}

View File

@ -25,7 +25,7 @@ uuid = "1.3"
which = "4.4.0"
[dependencies.clap]
version = "4.0.32"
version = "4.1.6"
default-features = false
features = ["std", "suggestions", "derive", "cargo", "help", "usage", "error-context"]