File size: 4,916 Bytes
2ee40b0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | #!/usr/bin/env bash
# Remote-env setup script for codex-rs integration tests.
#
# Usage (source-only):
# source scripts/test-remote-env.sh
# cd codex-rs
# just test -p codex-core --test all remote_test_env_can_connect_and_use_filesystem
# codex_remote_env_cleanup
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
is_sourced() {
[[ "${BASH_SOURCE[0]}" != "$0" ]]
}
setup_remote_env() {
local container_name
local codex_binary_path
local container_ip
local remote_codex_path
local remote_exec_server_pid
local remote_exec_server_port
local remote_exec_server_stdout_path
container_name="${CODEX_TEST_REMOTE_ENV_CONTAINER_NAME:-codex-remote-test-env-local-$(date +%s)-${RANDOM}}"
codex_binary_path="${CARGO_TARGET_DIR:-${REPO_ROOT}/codex-rs/target}/debug/codex"
if ! command -v docker >/dev/null 2>&1; then
echo "docker is required (Colima or Docker Desktop)" >&2
return 1
fi
if ! docker info >/dev/null 2>&1; then
echo "docker daemon is not reachable; for Colima run: colima start" >&2
return 1
fi
if ! command -v cargo >/dev/null 2>&1; then
echo "cargo is required to build codex" >&2
return 1
fi
(
cd "${REPO_ROOT}/codex-rs"
cargo build -p codex-cli --bin codex
)
if [[ ! -f "${codex_binary_path}" ]]; then
echo "codex binary not found at ${codex_binary_path}" >&2
return 1
fi
docker rm -f "${container_name}" >/dev/null 2>&1 || true
# bubblewrap needs mount propagation inside the remote test container.
docker run -d \
--name "${container_name}" \
--privileged \
--security-opt seccomp=unconfined \
ubuntu:24.04 sleep infinity >/dev/null
if ! docker exec "${container_name}" sh -lc "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y python3 zsh bubblewrap"; then
docker rm -f "${container_name}" >/dev/null 2>&1 || true
return 1
fi
if [[ -z "${CODEX_TEST_REMOTE_EXEC_SERVER_URL:-}" ]]; then
remote_codex_path="/tmp/codex-remote-env/codex"
remote_exec_server_port="31987"
remote_exec_server_stdout_path="/tmp/codex-remote-env/exec-server.stdout"
docker exec "${container_name}" sh -lc "mkdir -p /tmp/codex-remote-env"
docker cp "${codex_binary_path}" "${container_name}:${remote_codex_path}"
docker exec "${container_name}" chmod +x "${remote_codex_path}"
remote_exec_server_pid="$(
docker exec "${container_name}" sh -lc \
"rm -f ${remote_exec_server_stdout_path}; nohup ${remote_codex_path} exec-server --listen ws://0.0.0.0:${remote_exec_server_port} > ${remote_exec_server_stdout_path} 2>&1 & echo \$!"
)"
wait_for_remote_exec_server_port "${container_name}" "${remote_exec_server_port}" "${remote_exec_server_stdout_path}"
container_ip="$(
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${container_name}"
)"
if [[ -z "${container_ip}" ]]; then
echo "container ${container_name} has no IP address" >&2
docker rm -f "${container_name}" >/dev/null 2>&1 || true
return 1
fi
export CODEX_TEST_REMOTE_EXEC_SERVER_PID="${remote_exec_server_pid}"
export CODEX_TEST_REMOTE_EXEC_SERVER_URL="ws://${container_ip}:${remote_exec_server_port}"
fi
export CODEX_TEST_REMOTE_ENV="${container_name}"
export CODEX_TEST_REMOTE_ENV_CONTAINER_NAME="${container_name}"
export CODEX_TEST_ENVIRONMENT="docker"
}
wait_for_remote_exec_server_port() {
local container_name="$1"
local port="$2"
local stdout_path="$3"
local deadline=$((SECONDS + 5))
while (( SECONDS < deadline )); do
if docker exec "${container_name}" python3 -c "import socket; socket.create_connection(('127.0.0.1', ${port}), timeout=0.2).close()" >/dev/null 2>&1; then
return 0
fi
sleep 0.025
done
echo "timed out waiting for remote exec-server on ${container_name}:${port}" >&2
docker exec "${container_name}" sh -lc "cat ${stdout_path} 2>/dev/null || true" >&2 || true
return 1
}
codex_remote_env_cleanup() {
if [[ -n "${CODEX_TEST_REMOTE_ENV:-}" ]]; then
docker rm -f "${CODEX_TEST_REMOTE_ENV}" >/dev/null 2>&1 || true
unset CODEX_TEST_REMOTE_ENV
fi
unset CODEX_TEST_REMOTE_ENV_CONTAINER_NAME
unset CODEX_TEST_REMOTE_EXEC_SERVER_PID
unset CODEX_TEST_REMOTE_EXEC_SERVER_URL
unset CODEX_TEST_ENVIRONMENT
}
if ! is_sourced; then
echo "source this script instead of executing it: source scripts/test-remote-env.sh" >&2
exit 1
fi
old_shell_options="$(set +o)"
set -euo pipefail
if setup_remote_env; then
status=0
echo "CODEX_TEST_REMOTE_ENV=${CODEX_TEST_REMOTE_ENV}"
echo "CODEX_TEST_ENVIRONMENT=${CODEX_TEST_ENVIRONMENT}"
echo "CODEX_TEST_REMOTE_EXEC_SERVER_URL=${CODEX_TEST_REMOTE_EXEC_SERVER_URL}"
echo "Remote env ready. Run your command, then call: codex_remote_env_cleanup"
else
status=$?
fi
eval "${old_shell_options}"
return "${status}"
|