use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum IsolationTier {
Wasmtime,
Oci,
Firecracker,
None,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RuntimeRequirement {
WasmCompiled,
Python,
Shell,
Arbitrary,
ContainerImage,
NativeTrusted,
}
pub fn select_tier(requirement: &RuntimeRequirement) -> IsolationTier {
match requirement {
RuntimeRequirement::WasmCompiled => IsolationTier::Wasmtime,
RuntimeRequirement::Python | RuntimeRequirement::Shell | RuntimeRequirement::Arbitrary => {
IsolationTier::Firecracker
}
RuntimeRequirement::ContainerImage => IsolationTier::Oci,
RuntimeRequirement::NativeTrusted => IsolationTier::None,
}
}
pub fn select_tier_with_availability(requirement: &RuntimeRequirement) -> IsolationTier {
let ideal = select_tier(requirement);
match ideal {
IsolationTier::Firecracker => {
if cfg!(feature = "firecracker-isolation") {
IsolationTier::Firecracker
} else if cfg!(feature = "oci-isolation") {
IsolationTier::Oci
} else {
IsolationTier::Wasmtime
}
}
IsolationTier::Oci => {
if cfg!(feature = "oci-isolation") {
IsolationTier::Oci
} else if cfg!(feature = "firecracker-isolation") {
IsolationTier::Firecracker
} else {
IsolationTier::Wasmtime
}
}
other => other,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wasm_goes_to_wasmtime() {
assert_eq!(
select_tier(&RuntimeRequirement::WasmCompiled),
IsolationTier::Wasmtime
);
}
#[test]
fn python_goes_to_firecracker() {
assert_eq!(
select_tier(&RuntimeRequirement::Python),
IsolationTier::Firecracker
);
}
#[test]
fn shell_goes_to_firecracker() {
assert_eq!(
select_tier(&RuntimeRequirement::Shell),
IsolationTier::Firecracker
);
}
#[test]
fn arbitrary_goes_to_firecracker() {
assert_eq!(
select_tier(&RuntimeRequirement::Arbitrary),
IsolationTier::Firecracker
);
}
#[test]
fn container_image_goes_to_oci() {
assert_eq!(
select_tier(&RuntimeRequirement::ContainerImage),
IsolationTier::Oci
);
}
#[test]
fn trusted_gets_no_isolation() {
assert_eq!(
select_tier(&RuntimeRequirement::NativeTrusted),
IsolationTier::None
);
}
#[test]
fn tier_serde_roundtrip() {
let tier = IsolationTier::Wasmtime;
let json = serde_json::to_string(&tier).unwrap();
let back: IsolationTier = serde_json::from_str(&json).unwrap();
assert_eq!(back, tier);
}
#[test]
fn oci_tier_serde_roundtrip() {
let tier = IsolationTier::Oci;
let json = serde_json::to_string(&tier).unwrap();
let back: IsolationTier = serde_json::from_str(&json).unwrap();
assert_eq!(back, tier);
}
#[test]
fn availability_wasm_always_available() {
assert_eq!(
select_tier_with_availability(&RuntimeRequirement::WasmCompiled),
IsolationTier::Wasmtime
);
}
#[test]
fn availability_trusted_always_available() {
assert_eq!(
select_tier_with_availability(&RuntimeRequirement::NativeTrusted),
IsolationTier::None
);
}
}