fix: prepare writable codex home for runner jobs
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { accessSync, constants as fsConstants } from "node:fs";
|
||||
import { chmod, copyFile, mkdir } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import * as readline from "node:readline";
|
||||
import type { BackendEvent, BackendTurnResult, FailureKind, JsonRecord, JsonValue, TerminalStatus } from "../common/types.js";
|
||||
@@ -256,6 +257,8 @@ export class CodexStdioClient {
|
||||
|
||||
export async function runCodexStdioTurn(options: CodexStdioTurnOptions): Promise<BackendTurnResult> {
|
||||
const codexHome = resolveCodexHome(options);
|
||||
const projectionFailure = await prepareProjectedCodexHome(codexHome, options.env?.AGENTRUN_CODEX_SECRET_HOME ?? process.env.AGENTRUN_CODEX_SECRET_HOME);
|
||||
if (projectionFailure) return projectionFailure;
|
||||
const secretFailure = codexHomeReadiness(codexHome);
|
||||
if (secretFailure) return secretFailure;
|
||||
const env = childEnv(options, codexHome);
|
||||
@@ -347,6 +350,38 @@ export async function runCodexStdioTurn(options: CodexStdioTurnOptions): Promise
|
||||
return { terminalStatus: terminal.status, failureKind: terminal.failureKind, failureMessage: terminal.message, events: events.map((event) => ({ ...event, payload: redactJson(event.payload) })), ...(threadId ? { threadId } : {}), ...(turnId ? { turnId } : {}) };
|
||||
}
|
||||
|
||||
async function prepareProjectedCodexHome(codexHome: string, projectedHome: string | undefined): Promise<BackendTurnResult | null> {
|
||||
if (!projectedHome || projectedHome.trim().length === 0) return null;
|
||||
if (path.resolve(projectedHome) === path.resolve(codexHome)) return null;
|
||||
try {
|
||||
await mkdir(codexHome, { recursive: true, mode: 0o700 });
|
||||
for (const fileName of ["auth.json", "config.toml"]) {
|
||||
await copyFile(path.join(projectedHome, fileName), path.join(codexHome, fileName));
|
||||
await chmod(path.join(codexHome, fileName), 0o600);
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
const payload = {
|
||||
failureKind: "secret-unavailable",
|
||||
projection: {
|
||||
source: pathSummary(projectedHome),
|
||||
destination: pathSummary(codexHome),
|
||||
valuesPrinted: false,
|
||||
},
|
||||
message: error instanceof Error ? redactText(error.message) : "failed to prepare writable Codex home",
|
||||
} satisfies JsonRecord;
|
||||
return {
|
||||
terminalStatus: "blocked",
|
||||
failureKind: "secret-unavailable",
|
||||
failureMessage: "Codex Secret projection could not be copied to writable CODEX_HOME",
|
||||
events: [
|
||||
{ type: "error", payload },
|
||||
{ type: "terminal_status", payload: { terminalStatus: "blocked", failureKind: "secret-unavailable" } },
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function codexHomeReadiness(codexHome: string): BackendTurnResult | null {
|
||||
const auth = fileReadable(`${codexHome}/auth.json`);
|
||||
const config = fileReadable(`${codexHome}/config.toml`);
|
||||
|
||||
Reference in New Issue
Block a user