zeroclaw/src/runtime/mod.rs
Chummy b0e1e32819
feat(config): make config writes atomic with rollback-safe replacement (#190)
* feat(runtime): add Docker runtime MVP and runtime-aware command builder

* feat(security): add shell risk classification, approval gates, and action throttling

* feat(gateway): add per-endpoint rate limiting and webhook idempotency

* feat(config): make config writes atomic with rollback-safe replacement

---------

Co-authored-by: chumyin <chumyin@users.noreply.github.com>
2026-02-15 12:18:45 -05:00

87 lines
2.6 KiB
Rust

pub mod docker;
pub mod native;
pub mod traits;
pub use docker::DockerRuntime;
pub use native::NativeRuntime;
pub use traits::RuntimeAdapter;
use crate::config::RuntimeConfig;
/// Factory: create the right runtime from config
pub fn create_runtime(config: &RuntimeConfig) -> anyhow::Result<Box<dyn RuntimeAdapter>> {
match config.kind.as_str() {
"native" => Ok(Box::new(NativeRuntime::new())),
"docker" => Ok(Box::new(DockerRuntime::new(config.docker.clone()))),
"cloudflare" => anyhow::bail!(
"runtime.kind='cloudflare' is not implemented yet. Use runtime.kind='native' for now."
),
other if other.trim().is_empty() => {
anyhow::bail!("runtime.kind cannot be empty. Supported values: native, docker")
}
other => anyhow::bail!("Unknown runtime kind '{other}'. Supported values: native, docker"),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn factory_native() {
let cfg = RuntimeConfig {
kind: "native".into(),
..RuntimeConfig::default()
};
let rt = create_runtime(&cfg).unwrap();
assert_eq!(rt.name(), "native");
assert!(rt.has_shell_access());
}
#[test]
fn factory_docker() {
let cfg = RuntimeConfig {
kind: "docker".into(),
..RuntimeConfig::default()
};
let rt = create_runtime(&cfg).unwrap();
assert_eq!(rt.name(), "docker");
assert!(rt.has_shell_access());
}
#[test]
fn factory_cloudflare_errors() {
let cfg = RuntimeConfig {
kind: "cloudflare".into(),
..RuntimeConfig::default()
};
match create_runtime(&cfg) {
Err(err) => assert!(err.to_string().contains("not implemented")),
Ok(_) => panic!("cloudflare runtime should error"),
}
}
#[test]
fn factory_unknown_errors() {
let cfg = RuntimeConfig {
kind: "wasm-edge-unknown".into(),
..RuntimeConfig::default()
};
match create_runtime(&cfg) {
Err(err) => assert!(err.to_string().contains("Unknown runtime kind")),
Ok(_) => panic!("unknown runtime should error"),
}
}
#[test]
fn factory_empty_errors() {
let cfg = RuntimeConfig {
kind: String::new(),
..RuntimeConfig::default()
};
match create_runtime(&cfg) {
Err(err) => assert!(err.to_string().contains("cannot be empty")),
Ok(_) => panic!("empty runtime should error"),
}
}
}