use serde::{Deserialize, Serialize}; use crate::{Capability, EnvironmentResource}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum GuestRuntimeKind { Wasmtime, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum CommandBackendKind { LinuxRootlessPodman, WindowsCommandDev, StubbedWindowsSandbox, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct CommandInvocation { pub program: String, pub args: Vec, pub env: Option, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct CommandPlan { pub guest_runtime: GuestRuntimeKind, pub backend: CommandBackendKind, pub required_capability: Capability, pub user_attached_development_execution: bool, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct NativeCommandPolicy { pub hosted_control_plane: bool, pub node_has_command_capability: bool, } impl NativeCommandPolicy { pub fn authorize(&self) -> Result<(), String> { if self.hosted_control_plane { return Err("hosted coordinator control plane cannot run native commands".to_owned()); } if !self.node_has_command_capability { return Err("selected node or task lacks native command capability".to_owned()); } Ok(()) } } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum TaskBoundaryValue { SmallJson(serde_json::Value), SourceSnapshot(crate::Digest), Blob(crate::Digest), Artifact(crate::ArtifactId), VfsManifest(crate::Digest), } impl TaskBoundaryValue { pub fn reject_host_only(type_name: &str) -> Result { Err(format!( "task boundary value `{type_name}` is host-only; use small serialized data or handles" )) } } #[cfg(test)] mod tests { use super::*; #[test] fn hosted_control_plane_cannot_authorize_native_command() { let policy = NativeCommandPolicy { hosted_control_plane: true, node_has_command_capability: true, }; assert!(policy .authorize() .unwrap_err() .contains("hosted coordinator")); } #[test] fn raw_pointer_style_task_argument_is_rejected() { let error = TaskBoundaryValue::reject_host_only("*const u8").unwrap_err(); assert!(error.contains("host-only")); } }