mirror of
https://github.com/openai/codex.git
synced 2026-10-29 19:08:43 +00:00
codex: move unified exec sandbox launch to exec-server
This commit is contained in:
@@ -38,6 +38,8 @@ use codex_protocol::error::CodexErr;
|
||||
use codex_protocol::error::SandboxErr;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::ReviewDecision;
|
||||
use codex_sandboxing::SandboxLaunchConfig;
|
||||
use codex_sandboxing::SandboxLaunchMode;
|
||||
use codex_sandboxing::SandboxablePreference;
|
||||
use codex_shell_command::powershell::prefix_powershell_script_with_utf8;
|
||||
use codex_tools::UnifiedExecShellMode;
|
||||
@@ -82,6 +84,24 @@ pub struct UnifiedExecRuntime<'a> {
|
||||
shell_mode: UnifiedExecShellMode,
|
||||
}
|
||||
|
||||
fn build_remote_exec_sandbox_config(attempt: &SandboxAttempt<'_>) -> SandboxLaunchConfig {
|
||||
SandboxLaunchConfig {
|
||||
mode: if matches!(attempt.sandbox, codex_sandboxing::SandboxType::None) {
|
||||
SandboxLaunchMode::Disabled
|
||||
} else {
|
||||
SandboxLaunchMode::Auto
|
||||
},
|
||||
policy: attempt.policy.clone(),
|
||||
file_system_policy: attempt.file_system_policy.clone(),
|
||||
network_policy: attempt.network_policy,
|
||||
sandbox_policy_cwd: attempt.sandbox_cwd.to_path_buf(),
|
||||
enforce_managed_network: attempt.enforce_managed_network,
|
||||
windows_sandbox_level: attempt.windows_sandbox_level,
|
||||
windows_sandbox_private_desktop: attempt.windows_sandbox_private_desktop,
|
||||
use_legacy_landlock: attempt.use_legacy_landlock,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> UnifiedExecRuntime<'a> {
|
||||
/// Creates a runtime bound to the shared unified-exec process manager.
|
||||
pub fn new(manager: &'a UnifiedExecProcessManager, shell_mode: UnifiedExecShellMode) -> Self {
|
||||
@@ -218,6 +238,31 @@ impl<'a> ToolRuntime<UnifiedExecRequest, UnifiedExecProcess> for UnifiedExecRunt
|
||||
if let Some(network) = req.network.as_ref() {
|
||||
network.apply_to_env(&mut env);
|
||||
}
|
||||
// Remote exec-server now owns sandbox argv construction, so this branch
|
||||
// keeps sending raw command data until we collapse the launch APIs.
|
||||
if ctx.turn.environment.exec_server_url().is_some() {
|
||||
return self
|
||||
.manager
|
||||
.open_session_with_remote_exec(
|
||||
req.process_id,
|
||||
command,
|
||||
req.cwd.clone(),
|
||||
env,
|
||||
req.tty,
|
||||
Some(build_remote_exec_sandbox_config(attempt)),
|
||||
ctx.turn.environment.as_ref(),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| match err {
|
||||
UnifiedExecError::SandboxDenied { output, .. } => {
|
||||
ToolError::Codex(CodexErr::Sandbox(SandboxErr::Denied {
|
||||
output: Box::new(output),
|
||||
network_policy_decision: None,
|
||||
}))
|
||||
}
|
||||
other => ToolError::Rejected(other.to_string()),
|
||||
});
|
||||
}
|
||||
if let UnifiedExecShellMode::ZshFork(zsh_fork_config) = &self.shell_mode {
|
||||
let command =
|
||||
build_sandbox_command(&command, &req.cwd, &env, req.additional_permissions.clone())
|
||||
@@ -239,6 +284,9 @@ impl<'a> ToolRuntime<UnifiedExecRequest, UnifiedExecProcess> for UnifiedExecRunt
|
||||
.await?
|
||||
{
|
||||
Some(prepared) => {
|
||||
// TODO: Move unified-exec zsh-fork into exec-server once
|
||||
// remote launch can participate in the existing approval
|
||||
// and escalation flow.
|
||||
if ctx.turn.environment.exec_server_url().is_some() {
|
||||
return Err(ToolError::Rejected(
|
||||
"unified_exec zsh-fork is not supported when exec_server_url is configured".to_string(),
|
||||
|
||||
@@ -609,10 +609,12 @@ impl UnifiedExecProcessManager {
|
||||
env: env.env.clone(),
|
||||
tty,
|
||||
arg0: env.arg0.clone(),
|
||||
sandbox: None,
|
||||
})
|
||||
.await
|
||||
.map_err(|err| UnifiedExecError::create_process(err.to_string()))?;
|
||||
return UnifiedExecProcess::from_remote_started(started, env.sandbox).await;
|
||||
let sandbox_type = started.sandbox_type;
|
||||
return UnifiedExecProcess::from_remote_started(started, sandbox_type).await;
|
||||
}
|
||||
|
||||
let spawn_result = if tty {
|
||||
@@ -643,6 +645,33 @@ impl UnifiedExecProcessManager {
|
||||
UnifiedExecProcess::from_spawned(spawned, env.sandbox, spawn_lifecycle).await
|
||||
}
|
||||
|
||||
pub(crate) async fn open_session_with_remote_exec(
|
||||
&self,
|
||||
process_id: i32,
|
||||
command: Vec<String>,
|
||||
cwd: PathBuf,
|
||||
env: HashMap<String, String>,
|
||||
tty: bool,
|
||||
sandbox: Option<codex_sandboxing::SandboxLaunchConfig>,
|
||||
environment: &codex_exec_server::Environment,
|
||||
) -> Result<UnifiedExecProcess, UnifiedExecError> {
|
||||
let started = environment
|
||||
.get_exec_backend()
|
||||
.start(codex_exec_server::ExecParams {
|
||||
process_id: exec_server_process_id(process_id).into(),
|
||||
argv: command,
|
||||
cwd,
|
||||
env,
|
||||
tty,
|
||||
arg0: None,
|
||||
sandbox,
|
||||
})
|
||||
.await
|
||||
.map_err(|err| UnifiedExecError::create_process(err.to_string()))?;
|
||||
let sandbox_type = started.sandbox_type;
|
||||
UnifiedExecProcess::from_remote_started(started, sandbox_type).await
|
||||
}
|
||||
|
||||
pub(super) async fn open_session_with_sandbox(
|
||||
&self,
|
||||
request: &ExecCommandRequest,
|
||||
|
||||
@@ -74,6 +74,7 @@ async fn remote_process(write_status: WriteStatus) -> UnifiedExecProcess {
|
||||
read_responses: Mutex::new(VecDeque::new()),
|
||||
wake_tx,
|
||||
}),
|
||||
sandbox_type: SandboxType::None,
|
||||
};
|
||||
|
||||
UnifiedExecProcess::from_remote_started(started, SandboxType::None)
|
||||
@@ -126,6 +127,7 @@ async fn remote_process_waits_for_early_exit_event() {
|
||||
}])),
|
||||
wake_tx: wake_tx.clone(),
|
||||
}),
|
||||
sandbox_type: SandboxType::None,
|
||||
};
|
||||
|
||||
tokio::spawn(async move {
|
||||
|
||||
Reference in New Issue
Block a user