Source commit: 2a68aa98149e9042b7975736e002699a0118ece6 Public tree identity: sha256:8aa9c852dc87a3e5469c13fda3134ad19dbc626c8712bb7e019e062616d4a52e
90 lines
2.4 KiB
Rust
90 lines
2.4 KiB
Rust
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<String>,
|
|
pub env: Option<EnvironmentResource>,
|
|
}
|
|
|
|
#[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<Self, String> {
|
|
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"));
|
|
}
|
|
}
|