log sandbox commands to $CODEX_HOME instead of cwd (#6171)
Logging commands in the Windows Sandbox is temporary, but while we are doing it, let's always write to CODEX_HOME instead of dirtying the cwd.
This commit is contained in:
@@ -124,6 +124,7 @@ async fn run_command_under_sandbox(
|
|||||||
let cwd_clone = cwd.clone();
|
let cwd_clone = cwd.clone();
|
||||||
let env_map = env.clone();
|
let env_map = env.clone();
|
||||||
let command_vec = command.clone();
|
let command_vec = command.clone();
|
||||||
|
let base_dir = config.codex_home.clone();
|
||||||
let res = tokio::task::spawn_blocking(move || {
|
let res = tokio::task::spawn_blocking(move || {
|
||||||
run_windows_sandbox_capture(
|
run_windows_sandbox_capture(
|
||||||
policy_str,
|
policy_str,
|
||||||
@@ -132,6 +133,7 @@ async fn run_command_under_sandbox(
|
|||||||
&cwd_clone,
|
&cwd_clone,
|
||||||
env_map,
|
env_map,
|
||||||
None,
|
None,
|
||||||
|
Some(base_dir.as_path()),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ async fn exec_windows_sandbox(
|
|||||||
params: ExecParams,
|
params: ExecParams,
|
||||||
sandbox_policy: &SandboxPolicy,
|
sandbox_policy: &SandboxPolicy,
|
||||||
) -> Result<RawExecToolCallOutput> {
|
) -> Result<RawExecToolCallOutput> {
|
||||||
|
use crate::config::find_codex_home;
|
||||||
use codex_windows_sandbox::run_windows_sandbox_capture;
|
use codex_windows_sandbox::run_windows_sandbox_capture;
|
||||||
|
|
||||||
let ExecParams {
|
let ExecParams {
|
||||||
@@ -188,8 +189,17 @@ async fn exec_windows_sandbox(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let sandbox_cwd = cwd.clone();
|
let sandbox_cwd = cwd.clone();
|
||||||
|
let logs_base_dir = find_codex_home().ok();
|
||||||
let spawn_res = tokio::task::spawn_blocking(move || {
|
let spawn_res = tokio::task::spawn_blocking(move || {
|
||||||
run_windows_sandbox_capture(policy_str, &sandbox_cwd, command, &cwd, env, timeout_ms)
|
run_windows_sandbox_capture(
|
||||||
|
policy_str,
|
||||||
|
&sandbox_cwd,
|
||||||
|
command,
|
||||||
|
&cwd,
|
||||||
|
env,
|
||||||
|
timeout_ms,
|
||||||
|
logs_base_dir.as_deref(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ mod windows_impl {
|
|||||||
cwd: &Path,
|
cwd: &Path,
|
||||||
mut env_map: HashMap<String, String>,
|
mut env_map: HashMap<String, String>,
|
||||||
timeout_ms: Option<u64>,
|
timeout_ms: Option<u64>,
|
||||||
|
logs_base_dir: Option<&Path>,
|
||||||
) -> Result<CaptureResult> {
|
) -> Result<CaptureResult> {
|
||||||
let policy = SandboxPolicy::parse(policy_json_or_preset)?;
|
let policy = SandboxPolicy::parse(policy_json_or_preset)?;
|
||||||
normalize_null_device_env(&mut env_map);
|
normalize_null_device_env(&mut env_map);
|
||||||
@@ -191,7 +192,7 @@ mod windows_impl {
|
|||||||
let current_dir = cwd.to_path_buf();
|
let current_dir = cwd.to_path_buf();
|
||||||
// for now, don't fail if we detect world-writable directories
|
// for now, don't fail if we detect world-writable directories
|
||||||
// audit::audit_everyone_writable(¤t_dir, &env_map)?;
|
// audit::audit_everyone_writable(¤t_dir, &env_map)?;
|
||||||
log_start(&command);
|
log_start(&command, logs_base_dir);
|
||||||
let (h_token, psid_to_use): (HANDLE, *mut c_void) = unsafe {
|
let (h_token, psid_to_use): (HANDLE, *mut c_void) = unsafe {
|
||||||
match &policy.0 {
|
match &policy.0 {
|
||||||
SandboxMode::ReadOnly => {
|
SandboxMode::ReadOnly => {
|
||||||
@@ -295,7 +296,7 @@ mod windows_impl {
|
|||||||
env_block.len(),
|
env_block.len(),
|
||||||
si.dwFlags,
|
si.dwFlags,
|
||||||
);
|
);
|
||||||
debug_log(&dbg);
|
debug_log(&dbg, logs_base_dir);
|
||||||
unsafe {
|
unsafe {
|
||||||
CloseHandle(in_r);
|
CloseHandle(in_r);
|
||||||
CloseHandle(in_w);
|
CloseHandle(in_w);
|
||||||
@@ -395,9 +396,9 @@ mod windows_impl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if exit_code == 0 {
|
if exit_code == 0 {
|
||||||
log_success(&command);
|
log_success(&command, logs_base_dir);
|
||||||
} else {
|
} else {
|
||||||
log_failure(&command, &format!("exit code {}", exit_code));
|
log_failure(&command, &format!("exit code {}", exit_code), logs_base_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !persist_aces {
|
if !persist_aces {
|
||||||
@@ -446,6 +447,7 @@ mod stub {
|
|||||||
_cwd: &Path,
|
_cwd: &Path,
|
||||||
_env_map: HashMap<String, String>,
|
_env_map: HashMap<String, String>,
|
||||||
_timeout_ms: Option<u64>,
|
_timeout_ms: Option<u64>,
|
||||||
|
_logs_base_dir: Option<&Path>,
|
||||||
) -> Result<CaptureResult> {
|
) -> Result<CaptureResult> {
|
||||||
bail!("Windows sandbox is only available on Windows")
|
bail!("Windows sandbox is only available on Windows")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
const LOG_COMMAND_PREVIEW_LIMIT: usize = 200;
|
const LOG_COMMAND_PREVIEW_LIMIT: usize = 200;
|
||||||
pub const LOG_FILE_NAME: &str = "sandbox_commands.rust.log";
|
pub const LOG_FILE_NAME: &str = "sandbox_commands.rust.log";
|
||||||
@@ -13,35 +15,43 @@ fn preview(command: &[String]) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_line(line: &str) {
|
fn log_file_path(base_dir: &Path) -> Option<PathBuf> {
|
||||||
if let Ok(mut f) = OpenOptions::new()
|
if base_dir.is_dir() {
|
||||||
.create(true)
|
Some(base_dir.join(LOG_FILE_NAME))
|
||||||
.append(true)
|
} else {
|
||||||
.open(LOG_FILE_NAME)
|
None
|
||||||
{
|
|
||||||
let _ = writeln!(f, "{}", line);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_start(command: &[String]) {
|
fn append_line(line: &str, base_dir: Option<&Path>) {
|
||||||
let p = preview(command);
|
if let Some(dir) = base_dir {
|
||||||
append_line(&format!("START: {}", p));
|
if let Some(path) = log_file_path(dir) {
|
||||||
|
if let Ok(mut f) = OpenOptions::new().create(true).append(true).open(path) {
|
||||||
|
let _ = writeln!(f, "{}", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_success(command: &[String]) {
|
pub fn log_start(command: &[String], base_dir: Option<&Path>) {
|
||||||
let p = preview(command);
|
let p = preview(command);
|
||||||
append_line(&format!("SUCCESS: {}", p));
|
append_line(&format!("START: {p}"), base_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_failure(command: &[String], detail: &str) {
|
pub fn log_success(command: &[String], base_dir: Option<&Path>) {
|
||||||
let p = preview(command);
|
let p = preview(command);
|
||||||
append_line(&format!("FAILURE: {} ({})", p, detail));
|
append_line(&format!("SUCCESS: {p}"), base_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_failure(command: &[String], detail: &str, base_dir: Option<&Path>) {
|
||||||
|
let p = preview(command);
|
||||||
|
append_line(&format!("FAILURE: {p} ({detail})"), base_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug logging helper. Emits only when SBX_DEBUG=1 to avoid noisy logs.
|
// Debug logging helper. Emits only when SBX_DEBUG=1 to avoid noisy logs.
|
||||||
pub fn debug_log(msg: &str) {
|
pub fn debug_log(msg: &str, base_dir: Option<&Path>) {
|
||||||
if std::env::var("SBX_DEBUG").ok().as_deref() == Some("1") {
|
if std::env::var("SBX_DEBUG").ok().as_deref() == Some("1") {
|
||||||
append_line(&format!("DEBUG: {}", msg));
|
append_line(&format!("DEBUG: {msg}"), base_dir);
|
||||||
eprintln!("{}", msg);
|
eprintln!("{msg}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ pub unsafe fn create_process_as_user(
|
|||||||
argv: &[String],
|
argv: &[String],
|
||||||
cwd: &Path,
|
cwd: &Path,
|
||||||
env_map: &HashMap<String, String>,
|
env_map: &HashMap<String, String>,
|
||||||
|
logs_base_dir: Option<&Path>,
|
||||||
) -> Result<(PROCESS_INFORMATION, STARTUPINFOW)> {
|
) -> Result<(PROCESS_INFORMATION, STARTUPINFOW)> {
|
||||||
let cmdline_str = argv
|
let cmdline_str = argv
|
||||||
.iter()
|
.iter()
|
||||||
@@ -142,7 +143,7 @@ pub unsafe fn create_process_as_user(
|
|||||||
env_block.len(),
|
env_block.len(),
|
||||||
si.dwFlags,
|
si.dwFlags,
|
||||||
);
|
);
|
||||||
logging::debug_log(&msg);
|
logging::debug_log(&msg, logs_base_dir);
|
||||||
return Err(anyhow!("CreateProcessAsUserW failed: {}", err));
|
return Err(anyhow!("CreateProcessAsUserW failed: {}", err));
|
||||||
}
|
}
|
||||||
Ok((pi, si))
|
Ok((pi, si))
|
||||||
|
|||||||
Reference in New Issue
Block a user