minion_engine/sandbox/
mod.rs1pub mod config;
19pub mod docker;
20
21pub use config::{SandboxConfig, SandboxMode};
22pub use docker::DockerSandbox;
23
24use anyhow::{bail, Result};
25
26pub fn resolve_mode(
28 sandbox_flag: bool,
29 global_config: &std::collections::HashMap<String, serde_yaml::Value>,
30 agent_config: &std::collections::HashMap<String, serde_yaml::Value>,
31) -> SandboxMode {
32 if sandbox_flag {
34 return SandboxMode::FullWorkflow;
35 }
36
37 if let Some(serde_yaml::Value::Mapping(m)) = global_config.get("sandbox") {
39 if m.get(serde_yaml::Value::String("enabled".into()))
40 .and_then(|v| v.as_bool())
41 .unwrap_or(false)
42 {
43 return SandboxMode::Devbox;
44 }
45 }
46
47 if agent_config
49 .get("sandbox")
50 .and_then(|v| v.as_bool())
51 .unwrap_or(false)
52 {
53 return SandboxMode::AgentOnly;
54 }
55
56 SandboxMode::Disabled
57}
58
59pub async fn require_docker() -> Result<()> {
61 if !DockerSandbox::is_sandbox_available().await {
62 bail!(
63 "Docker Sandbox is not available.\n\
64 \n\
65 Requirements:\n\
66 • Docker Desktop 4.40 or later (https://www.docker.com/products/docker-desktop/)\n\
67 • Docker daemon must be running\n\
68 \n\
69 To disable the sandbox, remove --sandbox flag or set `config.agent.sandbox: false`."
70 );
71 }
72 Ok(())
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use std::collections::HashMap;
79
80 fn make_global_sandbox_enabled() -> HashMap<String, serde_yaml::Value> {
81 serde_yaml::from_str(
82 r#"
83sandbox:
84 enabled: true
85 image: "ubuntu:22.04"
86"#,
87 )
88 .unwrap()
89 }
90
91 fn make_agent_sandbox_true() -> HashMap<String, serde_yaml::Value> {
92 serde_yaml::from_str("sandbox: true").unwrap()
93 }
94
95 #[test]
96 fn cli_flag_wins_over_config() {
97 let mode = resolve_mode(true, &HashMap::new(), &HashMap::new());
98 assert_eq!(mode, SandboxMode::FullWorkflow);
99 }
100
101 #[test]
102 fn global_config_enabled_gives_devbox_mode() {
103 let global = make_global_sandbox_enabled();
104 let mode = resolve_mode(false, &global, &HashMap::new());
105 assert_eq!(mode, SandboxMode::Devbox);
106 }
107
108 #[test]
109 fn agent_config_sandbox_true_gives_agent_only() {
110 let agent = make_agent_sandbox_true();
111 let mode = resolve_mode(false, &HashMap::new(), &agent);
112 assert_eq!(mode, SandboxMode::AgentOnly);
113 }
114
115 #[test]
116 fn no_config_gives_disabled() {
117 let mode = resolve_mode(false, &HashMap::new(), &HashMap::new());
118 assert_eq!(mode, SandboxMode::Disabled);
119 }
120
121 #[test]
122 fn cli_flag_overrides_agent_config() {
123 let agent = make_agent_sandbox_true();
124 let mode = resolve_mode(true, &HashMap::new(), &agent);
125 assert_eq!(mode, SandboxMode::FullWorkflow);
126 }
127}