fix: provision session pvc before runner dispatch (#168)
Co-authored-by: AgentRun Codex <agentrun-codex@users.noreply.github.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import { renderRunnerJobManifest } from "../runner/k8s-job.js";
|
||||
import type { RunnerSessionPvcOptions, RunnerTransientEnv } from "../runner/k8s-job.js";
|
||||
import { staticWorkReadyCapabilitySummary } from "../common/work-ready.js";
|
||||
import { resolveRunnerEnvImage } from "../common/env-image-ref.js";
|
||||
import { ensureSessionPvc } from "./session-pvc.js";
|
||||
|
||||
const reusableCredentialEnvNames = new Set([
|
||||
"AUTH_PASSWORD",
|
||||
@@ -104,14 +105,38 @@ export async function createKubernetesRunnerJob(options: { store: AgentRunStore;
|
||||
if (isTerminalRunStatus(run.status)) throw new AgentRunError(run.failureKind ?? (run.status === "cancelled" ? "cancelled" : "schema-invalid"), `run ${run.id} is already terminal: ${run.status}`, { httpStatus: 409 });
|
||||
if (isTerminalCommandState(command.state) || command.state !== "pending") throw new AgentRunError(command.state === "cancelled" ? "cancelled" : "schema-invalid", `command ${commandId} is not pending: ${command.state}`, { httpStatus: 409 });
|
||||
let sessionPvc: RunnerSessionPvcOptions | undefined;
|
||||
let sessionPvcSummary: JsonRecord | null = null;
|
||||
if (run.sessionRef?.sessionId) {
|
||||
const session = await options.store.getSession(run.sessionRef.sessionId);
|
||||
if (session?.storageKind === "evicted") {
|
||||
throw new AgentRunError("session-store-evicted", `session ${session.sessionId} storage has been evicted; create a new sessionId`, { httpStatus: 409, details: { sessionId: session.sessionId, pvcName: session.storagePvcName ?? null, pvcPhase: session.storagePvcPhase ?? null, valuesPrinted: false } });
|
||||
}
|
||||
if (session?.storageKind === "pvc" && session.storagePvcName) {
|
||||
const subdir = session.codexRolloutSubdir ?? "sessions";
|
||||
sessionPvc = { pvcName: session.storagePvcName, namespace: session.storageNamespace ?? "agentrun-v01", mountPath: `/home/agentrun/.codex-${run.backendProfile}/${subdir}`, codexRolloutSubdir: subdir };
|
||||
if (!session) throw new AgentRunError("schema-invalid", `session ${run.sessionRef.sessionId} was not found`, { httpStatus: 404 });
|
||||
const ensured = await ensureSessionPvc({
|
||||
store: options.store,
|
||||
sessionId: run.sessionRef.sessionId,
|
||||
namespace,
|
||||
options: { ...(options.defaults.kubectlCommand ? { kubectlCommand: options.defaults.kubectlCommand } : {}), defaultCodexRolloutSubdir: session.codexRolloutSubdir ?? "sessions" },
|
||||
});
|
||||
const refreshed = await options.store.getSession(run.sessionRef.sessionId);
|
||||
if (refreshed?.storageKind === "evicted") {
|
||||
throw new AgentRunError("session-store-evicted", `session ${refreshed.sessionId} storage has been evicted; create a new sessionId`, { httpStatus: 409, details: { sessionId: refreshed.sessionId, pvcName: refreshed.storagePvcName ?? null, pvcPhase: refreshed.storagePvcPhase ?? null, valuesPrinted: false } });
|
||||
}
|
||||
const pvcName = refreshed?.storagePvcName ?? ensured.pvcName;
|
||||
if (!pvcName) throw new AgentRunError("infra-failed", `session ${run.sessionRef.sessionId} PVC was not resolved for runner job`, { httpStatus: 502 });
|
||||
const subdir = refreshed?.codexRolloutSubdir ?? ensured.codexRolloutSubdir ?? "sessions";
|
||||
sessionPvc = { pvcName, namespace: refreshed?.storageNamespace ?? ensured.namespace ?? namespace, mountPath: `/home/agentrun/.codex-${run.backendProfile}/${subdir}`, codexRolloutSubdir: subdir };
|
||||
sessionPvcSummary = {
|
||||
sessionId: run.sessionRef.sessionId,
|
||||
pvcName: sessionPvc.pvcName,
|
||||
namespace: sessionPvc.namespace,
|
||||
pvcPhase: refreshed?.storagePvcPhase ?? ensured.pvcPhase ?? null,
|
||||
mountPath: sessionPvc.mountPath,
|
||||
codexRolloutSubdir: sessionPvc.codexRolloutSubdir,
|
||||
valuesPrinted: false,
|
||||
};
|
||||
if (ensured.pvcPhase === "NotFound" || ensured.pvcPhase === "Unknown") {
|
||||
throw new AgentRunError("infra-failed", `session ${run.sessionRef.sessionId} PVC is not ready for runner job`, { httpStatus: 502, details: sessionPvcSummary });
|
||||
}
|
||||
}
|
||||
const renderOptions: Parameters<typeof renderRunnerJobManifest>[0] = {
|
||||
@@ -181,6 +206,7 @@ export async function createKubernetesRunnerJob(options: { store: AgentRunStore;
|
||||
toolCredentials: summarizeToolCredentials(render.toolCredentials, render.namespace),
|
||||
transientEnv: summarizeTransientEnv(transientEnv),
|
||||
transientEnvSecret: transientEnvSecretResponse,
|
||||
sessionPvc: sessionPvcSummary,
|
||||
workReady: staticWorkReadyCapabilitySummary(),
|
||||
retention: {
|
||||
ttlSecondsAfterFinished: render.ttlSecondsAfterFinished,
|
||||
@@ -227,6 +253,7 @@ export async function createKubernetesRunnerJob(options: { store: AgentRunStore;
|
||||
envImage,
|
||||
workReady: staticWorkReadyCapabilitySummary(),
|
||||
toolCredentials: summarizeToolCredentials(render.toolCredentials, render.namespace),
|
||||
sessionPvc: sessionPvcSummary,
|
||||
sessionRef: summarizeSessionRef(run.sessionRef ?? null),
|
||||
resourceBundleRef: summarizeResourceBundleRef(run.resourceBundleRef ?? null),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user