mirror of
https://github.com/openai/codex.git
synced 2026-11-02 19:43:24 +00:00
fix: add test that verifies that codex-exec-mcp-server starts up
This commit is contained in:
@@ -6,3 +6,6 @@ pub use posix::main_execve_wrapper;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use posix::main_mcp_server;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use posix::ExecResult;
|
||||
|
||||
@@ -82,6 +82,8 @@ mod mcp_escalation_policy;
|
||||
mod socket;
|
||||
mod stopwatch;
|
||||
|
||||
pub use mcp::ExecResult;
|
||||
|
||||
/// Default value of --execve option relative to the current executable.
|
||||
/// Note this must match the name of the binary as specified in Cargo.toml.
|
||||
const CODEX_EXECVE_WRAPPER_EXE_NAME: &str = "codex-execve-wrapper";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::os::fd::FromRawFd as _;
|
||||
@@ -34,21 +35,30 @@ pub(crate) async fn run(file: String, argv: Vec<String>) -> anyhow::Result<i32>
|
||||
.send_with_fds(&HANDSHAKE_MESSAGE, &[server.into_inner().into()])
|
||||
.await
|
||||
.context("failed to send handshake datagram")?;
|
||||
let env = std::env::vars()
|
||||
.filter(|(k, _)| {
|
||||
!matches!(
|
||||
k.as_str(),
|
||||
ESCALATE_SOCKET_ENV_VAR | BASH_EXEC_WRAPPER_ENV_VAR
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let mut env = HashMap::new();
|
||||
const MAX_ENV_ENTRY_LEN: i64 = 8_192;
|
||||
for (key, value) in std::env::vars() {
|
||||
if matches!(
|
||||
key.as_str(),
|
||||
ESCALATE_SOCKET_ENV_VAR | BASH_EXEC_WRAPPER_ENV_VAR
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
let entry_len = (key.len() + value.len()) as i64;
|
||||
if entry_len > MAX_ENV_ENTRY_LEN {
|
||||
tracing::debug!(key, entry_len, "skipping oversized environment variable");
|
||||
continue;
|
||||
}
|
||||
env.insert(key, value);
|
||||
}
|
||||
let request = EscalateRequest {
|
||||
file: file.clone().into(),
|
||||
argv: argv.clone(),
|
||||
workdir: std::env::current_dir()?,
|
||||
env,
|
||||
};
|
||||
client
|
||||
.send(EscalateRequest {
|
||||
file: file.clone().into(),
|
||||
argv: argv.clone(),
|
||||
workdir: std::env::current_dir()?,
|
||||
env,
|
||||
})
|
||||
.send(request)
|
||||
.await
|
||||
.context("failed to send EscalateRequest")?;
|
||||
let message = client.receive::<EscalateResponse>().await?;
|
||||
|
||||
@@ -138,19 +138,23 @@ async fn handle_escalate_session_with_policy(
|
||||
socket: AsyncSocket,
|
||||
policy: Arc<dyn EscalationPolicy>,
|
||||
) -> anyhow::Result<()> {
|
||||
tracing::error!("in handle_escalate_session_with_policy");
|
||||
let EscalateRequest {
|
||||
file,
|
||||
argv,
|
||||
workdir,
|
||||
env,
|
||||
} = socket.receive::<EscalateRequest>().await?;
|
||||
} = socket
|
||||
.receive::<EscalateRequest>()
|
||||
.await
|
||||
.context("failed to receive EscalateRequest")?;
|
||||
let file = PathBuf::from(&file).absolutize()?.into_owned();
|
||||
let workdir = PathBuf::from(&workdir).absolutize()?.into_owned();
|
||||
let action = policy
|
||||
.determine_action(file.as_path(), &argv, &workdir)
|
||||
.await?;
|
||||
|
||||
tracing::debug!("decided {action:?} for {file:?} {argv:?} {workdir:?}");
|
||||
tracing::error!("decided {action:?} for {file:?} {argv:?} {workdir:?}");
|
||||
|
||||
match action {
|
||||
EscalateAction::Run => {
|
||||
@@ -165,7 +169,8 @@ async fn handle_escalate_session_with_policy(
|
||||
.send(EscalateResponse {
|
||||
action: EscalateAction::Escalate,
|
||||
})
|
||||
.await?;
|
||||
.await
|
||||
.context("failed to send EscalateResponse")?;
|
||||
let (msg, fds) = socket
|
||||
.receive_with_fds::<SuperExecMessage>()
|
||||
.await
|
||||
|
||||
@@ -54,7 +54,7 @@ pub struct ExecParams {
|
||||
pub login: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, schemars::JsonSchema)]
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
|
||||
pub struct ExecResult {
|
||||
pub exit_code: i32,
|
||||
pub output: String,
|
||||
|
||||
@@ -182,21 +182,26 @@ fn send_message_bytes(socket: &Socket, data: &[u8], fds: &[OwnedFd]) -> std::io:
|
||||
frame.extend_from_slice(&encode_length(data.len())?);
|
||||
frame.extend_from_slice(data);
|
||||
|
||||
let mut control = vec![0u8; control_space_for_fds(fds.len())];
|
||||
unsafe {
|
||||
let cmsg = control.as_mut_ptr().cast::<libc::cmsghdr>();
|
||||
(*cmsg).cmsg_len = libc::CMSG_LEN(size_of::<RawFd>() as c_uint * fds.len() as c_uint) as _;
|
||||
(*cmsg).cmsg_level = libc::SOL_SOCKET;
|
||||
(*cmsg).cmsg_type = libc::SCM_RIGHTS;
|
||||
let data_ptr = libc::CMSG_DATA(cmsg).cast::<RawFd>();
|
||||
for (i, fd) in fds.iter().enumerate() {
|
||||
data_ptr.add(i).write(fd.as_raw_fd());
|
||||
}
|
||||
}
|
||||
|
||||
let mut control;
|
||||
let payload = [IoSlice::new(&frame)];
|
||||
let msg = MsgHdr::new().with_buffers(&payload).with_control(&control);
|
||||
let mut sent = socket.sendmsg(&msg, 0)?;
|
||||
let mut sent = if fds.is_empty() {
|
||||
socket.send(&frame)?
|
||||
} else {
|
||||
control = vec![0u8; control_space_for_fds(fds.len())];
|
||||
unsafe {
|
||||
let cmsg = control.as_mut_ptr().cast::<libc::cmsghdr>();
|
||||
(*cmsg).cmsg_len =
|
||||
libc::CMSG_LEN(size_of::<RawFd>() as c_uint * fds.len() as c_uint) as _;
|
||||
(*cmsg).cmsg_level = libc::SOL_SOCKET;
|
||||
(*cmsg).cmsg_type = libc::SCM_RIGHTS;
|
||||
let data_ptr = libc::CMSG_DATA(cmsg).cast::<RawFd>();
|
||||
for (i, fd) in fds.iter().enumerate() {
|
||||
data_ptr.add(i).write(fd.as_raw_fd());
|
||||
}
|
||||
}
|
||||
let msg = MsgHdr::new().with_buffers(&payload).with_control(&control);
|
||||
socket.sendmsg(&msg, 0)?
|
||||
};
|
||||
while sent < frame.len() {
|
||||
let bytes = socket.send(&frame[sent..])?;
|
||||
if bytes == 0 {
|
||||
@@ -236,8 +241,9 @@ fn send_datagram_bytes(socket: &Socket, data: &[u8], fds: &[OwnedFd]) -> std::io
|
||||
format!("too many fds: {}", fds.len()),
|
||||
));
|
||||
}
|
||||
let mut control = vec![0u8; control_space_for_fds(fds.len())];
|
||||
let mut control = Vec::new();
|
||||
if !fds.is_empty() {
|
||||
control = vec![0u8; control_space_for_fds(fds.len())];
|
||||
unsafe {
|
||||
let cmsg = control.as_mut_ptr().cast::<libc::cmsghdr>();
|
||||
(*cmsg).cmsg_len =
|
||||
|
||||
Reference in New Issue
Block a user