Skip to content

Commit

Permalink
Harmonize executors
Browse files Browse the repository at this point in the history
  • Loading branch information
Furisto committed Jan 1, 2022
1 parent 5cdedd5 commit d4ca2cf
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 32 deletions.
4 changes: 2 additions & 2 deletions crates/libcontainer/src/process/container_init_process.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::args::ContainerArgs;
use crate::apparmor;
use crate::syscall::Syscall;
use crate::workload::Executor;
use crate::workload::{CompositeExecutor, Executor};
use crate::{
capabilities, hooks, namespaces::Namespaces, process::channel, rootfs::RootFS,
rootless::Rootless, seccomp, tty, utils,
Expand Down Expand Up @@ -415,7 +415,7 @@ pub fn container_init_process(
}

if proc.args().is_some() {
Executor::default().exec(spec)
CompositeExecutor::default().exec(spec)
} else {
bail!("on non-Windows, at least one process arg entry is required")
}
Expand Down
6 changes: 3 additions & 3 deletions crates/libcontainer/src/workload/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use anyhow::{bail, Context, Result};
use nix::unistd;
use oci_spec::runtime::Spec;

use super::{ExecHandler, EMPTY};
use super::{Executor, EMPTY};

pub struct DefaultExecHandler {}
pub struct DefaultExecutor {}

impl ExecHandler for DefaultExecHandler {
impl Executor for DefaultExecutor {
fn exec(&self, spec: &Spec) -> Result<()> {
log::debug!("Executing workload with default handler");
let args = spec
Expand Down
63 changes: 43 additions & 20 deletions crates/libcontainer/src/workload/mod.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,76 @@
use anyhow::{Context, Result};
use oci_spec::runtime::Spec;

use self::default::DefaultExecHandler;
use self::default::DefaultExecutor;
#[cfg(feature = "wasm-wasmer")]
use self::wasmer::WasmerExecHandler;
use self::wasmer::WasmerExecutor;

pub mod default;
#[cfg(feature = "wasm-wasmer")]
pub mod wasmer;

static EMPTY: Vec<String> = Vec::new();

pub trait ExecHandler {
/// The name of the handler
fn name(&self) -> &str;
pub trait Executor {
/// Executes the workload
fn exec(&self, spec: &Spec) -> Result<()>;
/// Checks if the handler is able to handle the workload
fn can_handle(&self, spec: &Spec) -> Result<bool>;
/// The name of the handler
fn name(&self) -> &str;
}
pub struct Executor {
handlers: Vec<Box<dyn ExecHandler>>,
pub struct CompositeExecutor {
executors: Vec<Box<dyn Executor>>,
}

impl Executor {
pub fn exec(&self, spec: &Spec) -> Result<()> {
for handler in &self.handlers {
if handler
impl Executor for CompositeExecutor {
fn exec(&self, spec: &Spec) -> Result<()> {
for executor in &self.executors {
if executor
.can_handle(spec)
.with_context(|| format!("handler {} failed on selection", handler.name()))?
.with_context(|| format!("executor {} failed on selection", executor.name()))?
{
handler
.exec(spec)
.with_context(|| format!("handler {} failed on exec", handler.name()))?;
let result = executor.exec(spec);
if result.is_err() {
let error_msg = if executor.name() == "default" {
"executor default failed on exec. This might have been caused \
by another handler not being able to match on your request".to_string()
} else {
format!("executor {} failed on exec", executor.name())
};

return result.context(error_msg);
} else {
return Ok(());
}
}
}

unreachable!("no suitable execution handler has been registered");
}

fn can_handle(&self, spec: &Spec) -> Result<bool> {
Ok(self
.executors
.iter()
.any(|h| h.can_handle(spec).unwrap_or_default()))
}

fn name(&self) -> &str {
"composite"
}
}

impl Default for Executor {
impl Default for CompositeExecutor {
fn default() -> Self {
let handlers: Vec<Box<dyn ExecHandler>> = vec![
let handlers: Vec<Box<dyn Executor>> = vec![
#[cfg(feature = "wasm-wasmer")]
Box::new(WasmerExecHandler {}),
Box::new(DefaultExecHandler {}),
Box::new(WasmerExecutor {}),
Box::new(DefaultExecutor {}),
];

Self { handlers }
Self {
executors: handlers,
}
}
}
14 changes: 7 additions & 7 deletions crates/libcontainer/src/workload/wasmer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use oci_spec::runtime::Spec;
use wasmer::{Instance, Module, Store};
use wasmer_wasi::WasiState;

use super::{ExecHandler, EMPTY};
use super::{Executor, EMPTY};

pub struct WasmerExecHandler {}
pub struct WasmerExecutor {}

impl ExecHandler for WasmerExecHandler {
impl Executor for WasmerExecutor {
fn exec(&self, spec: &Spec) -> Result<()> {
log::debug!("Executing workload with wasmer handler");
let process = spec.process().as_ref();
Expand All @@ -27,7 +27,7 @@ impl ExecHandler for WasmerExecHandler {
bail!("at least one process arg must be specified")
}

if !args[0].ends_with(".wasm") || !args[0].ends_with(".wat") {
if !args[0].ends_with(".wasm") && !args[0].ends_with(".wat") {
bail!(
"first argument must be a wasm or wat module, but was {}",
args[0]
Expand Down Expand Up @@ -93,7 +93,7 @@ mod tests {
.build()
.context("build spec")?;

let handler = WasmerExecHandler {};
let handler = WasmerExecutor {};
assert!(handler.can_handle(&spec).context("can handle")?);

Ok(())
Expand All @@ -108,7 +108,7 @@ mod tests {
.build()
.context("build spec")?;

let handler = WasmerExecHandler {};
let handler = WasmerExecutor {};
assert!(handler.can_handle(&spec).context("can handle")?);

Ok(())
Expand All @@ -118,7 +118,7 @@ mod tests {
fn test_can_handle_no_execute() -> Result<()> {
let spec = SpecBuilder::default().build().context("build spec")?;

let handler = WasmerExecHandler {};
let handler = WasmerExecutor {};
assert!(!handler.can_handle(&spec).context("can handle")?);

Ok(())
Expand Down

0 comments on commit d4ca2cf

Please sign in to comment.