diff --git a/scripts/lib/live-docker-auth.sh b/scripts/lib/live-docker-auth.sh index d179070538ea..41d8c1dcf77c 100644 --- a/scripts/lib/live-docker-auth.sh +++ b/scripts/lib/live-docker-auth.sh @@ -206,6 +206,19 @@ openclaw_live_append_array() { eval "${target_array}+=(\"\${${source_array}[@]}\")" } +openclaw_live_init_docker_run_args() { + local target_array="${1:?target array required}" + local timeout_value="${2:-${OPENCLAW_LIVE_DOCKER_RUN_TIMEOUT:-2700s}}" + local quoted_timeout + + if command -v timeout >/dev/null 2>&1; then + quoted_timeout="$(printf '%q' "$timeout_value")" + eval "${target_array}=(timeout ${quoted_timeout} docker run)" + return + fi + eval "${target_array}=(docker run)" +} + openclaw_live_stage_auth_into_home() { local dest_home="${1:?destination home directory required}" shift diff --git a/scripts/test-live-acp-bind-docker.sh b/scripts/test-live-acp-bind-docker.sh index b541da18f188..5278a727c9b5 100644 --- a/scripts/test-live-acp-bind-docker.sh +++ b/scripts/test-live-acp-bind-docker.sh @@ -335,7 +335,9 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do echo "==> Profile file: $PROFILE_STATUS" echo "==> Auth dirs: ${AUTH_DIRS_CSV:-none}" echo "==> Auth files: ${AUTH_FILES_CSV:-none}" - DOCKER_RUN_ARGS=(docker run --rm -t \ + DOCKER_RUN_ARGS=() + openclaw_live_init_docker_run_args DOCKER_RUN_ARGS "${OPENCLAW_LIVE_ACP_BIND_DOCKER_RUN_TIMEOUT:-2700s}" + DOCKER_RUN_ARGS+=(--rm -t \ -u "$DOCKER_USER" \ --entrypoint bash \ -e ANTHROPIC_API_KEY \ diff --git a/scripts/test-live-cli-backend-docker.sh b/scripts/test-live-cli-backend-docker.sh index b1a70995e7e0..33bca1479d5e 100644 --- a/scripts/test-live-cli-backend-docker.sh +++ b/scripts/test-live-cli-backend-docker.sh @@ -414,7 +414,9 @@ else ) fi -DOCKER_RUN_ARGS=(docker run --rm -t \ +DOCKER_RUN_ARGS=() +openclaw_live_init_docker_run_args DOCKER_RUN_ARGS "${OPENCLAW_LIVE_CLI_BACKEND_DOCKER_RUN_TIMEOUT:-2700s}" +DOCKER_RUN_ARGS+=(--rm -t \ -u "$DOCKER_USER" \ --entrypoint bash \ -e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ diff --git a/scripts/test-live-codex-harness-docker.sh b/scripts/test-live-codex-harness-docker.sh index 9a58dd05f346..874c8657e098 100644 --- a/scripts/test-live-codex-harness-docker.sh +++ b/scripts/test-live-codex-harness-docker.sh @@ -298,7 +298,9 @@ echo "==> CI-safe Codex config: ${OPENCLAW_LIVE_CODEX_HARNESS_USE_CI_SAFE_CODEX_ echo "==> Test files: ${OPENCLAW_LIVE_CODEX_TEST_FILES:-src/gateway/gateway-codex-harness.live.test.ts}" echo "==> Harness fallback: none" echo "==> Auth files: ${AUTH_FILES_CSV:-none}" -DOCKER_RUN_ARGS=(docker run --rm -t \ +DOCKER_RUN_ARGS=() +openclaw_live_init_docker_run_args DOCKER_RUN_ARGS "${OPENCLAW_LIVE_CODEX_HARNESS_DOCKER_RUN_TIMEOUT:-2100s}" +DOCKER_RUN_ARGS+=(--rm -t \ -u "$DOCKER_USER" \ --entrypoint bash \ -e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ diff --git a/scripts/test-live-gateway-models-docker.sh b/scripts/test-live-gateway-models-docker.sh index f53d85e3ff5f..411ef16fa998 100755 --- a/scripts/test-live-gateway-models-docker.sh +++ b/scripts/test-live-gateway-models-docker.sh @@ -172,7 +172,9 @@ echo "==> Target: src/gateway/gateway-models.profiles.live.test.ts" echo "==> Profile file: $PROFILE_STATUS" echo "==> External auth dirs: ${AUTH_DIRS_CSV:-none}" echo "==> External auth files: ${AUTH_FILES_CSV:-none}" -DOCKER_RUN_ARGS=(docker run --rm -t \ +DOCKER_RUN_ARGS=() +openclaw_live_init_docker_run_args DOCKER_RUN_ARGS "${OPENCLAW_LIVE_GATEWAY_DOCKER_RUN_TIMEOUT:-2100s}" +DOCKER_RUN_ARGS+=(--rm -t \ -u "$DOCKER_USER" \ --entrypoint bash \ -e OPENAI_API_KEY \ diff --git a/scripts/test-live-models-docker.sh b/scripts/test-live-models-docker.sh index ad6e6ca293ef..2a9d3b94f7de 100755 --- a/scripts/test-live-models-docker.sh +++ b/scripts/test-live-models-docker.sh @@ -198,7 +198,9 @@ echo "==> Profile env only: ${OPENCLAW_DOCKER_PROFILE_ENV_ONLY:-0}" echo "==> Profile file: $PROFILE_STATUS" echo "==> External auth dirs: ${AUTH_DIRS_CSV:-none}" echo "==> External auth files: ${AUTH_FILES_CSV:-none}" -DOCKER_RUN_ARGS=(docker run --rm -t \ +DOCKER_RUN_ARGS=() +openclaw_live_init_docker_run_args DOCKER_RUN_ARGS "${OPENCLAW_LIVE_MODELS_DOCKER_RUN_TIMEOUT:-2100s}" +DOCKER_RUN_ARGS+=(--rm -t \ -u "$DOCKER_USER" \ --entrypoint bash \ -e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ diff --git a/scripts/test-live-subagent-announce-docker.sh b/scripts/test-live-subagent-announce-docker.sh index 0c2183d04cbc..fc7c948496b8 100644 --- a/scripts/test-live-subagent-announce-docker.sh +++ b/scripts/test-live-subagent-announce-docker.sh @@ -128,7 +128,9 @@ echo "==> Run subagent announce live test in Docker" echo "==> Target: src/agents/subagent-announce.live.test.ts" echo "==> Model: ${OPENCLAW_LIVE_SUBAGENT_E2E_MODEL:-openai/gpt-5.5}" echo "==> Profile file: $PROFILE_STATUS" -DOCKER_RUN_ARGS=(docker run --rm -t \ +DOCKER_RUN_ARGS=() +openclaw_live_init_docker_run_args DOCKER_RUN_ARGS "${OPENCLAW_LIVE_SUBAGENT_DOCKER_RUN_TIMEOUT:-1200s}" +DOCKER_RUN_ARGS+=(--rm -t \ -u "$DOCKER_USER" \ --entrypoint bash \ -e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ diff --git a/test/scripts/package-acceptance-workflow.test.ts b/test/scripts/package-acceptance-workflow.test.ts index 2c58258b97fa..1a0ff53a6af7 100644 --- a/test/scripts/package-acceptance-workflow.test.ts +++ b/test/scripts/package-acceptance-workflow.test.ts @@ -637,6 +637,8 @@ describe("package artifact reuse", () => { expect(scheduler).toContain("function liveDockerHarnessScriptCommand"); expect(scheduler).toContain('liveDockerHarnessScriptCommand("test-live-build-docker.sh")'); expect(liveDockerAuth).toContain("codex-cli | openai | openai-codex)"); + expect(liveDockerAuth).toContain("openclaw_live_init_docker_run_args()"); + expect(liveDockerAuth).toContain('timeout_value="${2:-${OPENCLAW_LIVE_DOCKER_RUN_TIMEOUT:-2700s}}"'); expect(harness).toContain('source "$TRUSTED_HARNESS_DIR/scripts/lib/live-docker-auth.sh"'); expect(harness).not.toContain('source "$ROOT_DIR/scripts/lib/live-docker-auth.sh"'); expect(harness).toContain( @@ -647,9 +649,14 @@ describe("package artifact reuse", () => { ); expect(harness).toContain('node --import tsx "$trusted_scripts_dir/prepare-codex-ci-auth.ts"'); expect(harness).toContain('source "$trusted_scripts_dir/lib/live-docker-stage.sh"'); - for (const script of sharedLiveScripts) { + for (const script of [harness, ...sharedLiveScripts]) { expect(script).toContain('source "$TRUSTED_HARNESS_DIR/scripts/lib/live-docker-auth.sh"'); expect(script).not.toContain('source "$ROOT_DIR/scripts/lib/live-docker-auth.sh"'); + expect(script).toContain("openclaw_live_init_docker_run_args DOCKER_RUN_ARGS"); + expect(script).toContain("DOCKER_RUN_ARGS+=(--rm -t \\"); + expect(script).not.toContain("DOCKER_RUN_ARGS=(docker run --rm -t \\"); + } + for (const script of sharedLiveScripts) { expect(script).toContain( 'OPENCLAW_LIVE_DOCKER_REPO_ROOT="$ROOT_DIR" "$TRUSTED_HARNESS_DIR/scripts/test-live-build-docker.sh"', ); @@ -661,6 +668,24 @@ describe("package artifact reuse", () => { "openclaw_live_append_array DOCKER_RUN_ARGS DOCKER_TRUSTED_HARNESS_MOUNT", ); } + expect(readFileSync("scripts/test-live-models-docker.sh", "utf8")).toContain( + 'OPENCLAW_LIVE_MODELS_DOCKER_RUN_TIMEOUT:-2100s', + ); + expect(readFileSync("scripts/test-live-gateway-models-docker.sh", "utf8")).toContain( + 'OPENCLAW_LIVE_GATEWAY_DOCKER_RUN_TIMEOUT:-2100s', + ); + expect(readFileSync("scripts/test-live-cli-backend-docker.sh", "utf8")).toContain( + 'OPENCLAW_LIVE_CLI_BACKEND_DOCKER_RUN_TIMEOUT:-2700s', + ); + expect(readFileSync("scripts/test-live-acp-bind-docker.sh", "utf8")).toContain( + 'OPENCLAW_LIVE_ACP_BIND_DOCKER_RUN_TIMEOUT:-2700s', + ); + expect(readFileSync("scripts/test-live-codex-harness-docker.sh", "utf8")).toContain( + 'OPENCLAW_LIVE_CODEX_HARNESS_DOCKER_RUN_TIMEOUT:-2100s', + ); + expect(readFileSync("scripts/test-live-subagent-announce-docker.sh", "utf8")).toContain( + 'OPENCLAW_LIVE_SUBAGENT_DOCKER_RUN_TIMEOUT:-1200s', + ); expect(build).toContain('ROOT_DIR="${OPENCLAW_LIVE_DOCKER_REPO_ROOT:-$SCRIPT_ROOT_DIR}"'); expect(build).toContain('source "$SCRIPT_ROOT_DIR/scripts/lib/docker-build.sh"'); expect(stage).toContain(