Files
pikasTech-agentrun/src/mgr/runner-job-status.ts
T
2026-06-11 09:19:43 +08:00

60 lines
2.5 KiB
TypeScript

import type { JsonRecord, RunEvent, RunnerJobRecord, TerminalStatus } from "../common/types.js";
import { runnerJobDiagnosis } from "./diagnosis.js";
export function runnerJobStatusSummary(job: RunnerJobRecord, events: RunEvent[] = []): JsonRecord {
const terminalEvent = latestTerminalEvent(events, job.commandId);
const runner = recordAt(job.result, "runner");
const jobIdentity = recordAt(job.result, "jobIdentity");
const kubernetes = recordAt(job.result, "kubernetes");
const retention = recordAt(job.result, "retention");
const envImage = recordAt(job.result, "envImage");
const terminalStatus = terminalEvent?.payload.terminalStatus;
return {
id: job.id,
runId: job.runId,
commandId: job.commandId,
attemptId: job.attemptId,
runnerId: job.runnerId,
namespace: job.namespace,
jobName: job.jobName,
managerUrl: job.managerUrl,
image: job.image,
envImage,
sourceCommit: job.sourceCommit,
serviceAccountName: job.serviceAccountName,
phase: terminalStatus ? `terminal:${terminalStatus}` : kubernetes.created === true ? "created" : "recorded",
terminalStatus: isTerminalStatus(terminalStatus) ? terminalStatus : null,
failureKind: typeof terminalEvent?.payload.failureKind === "string" ? terminalEvent.payload.failureKind : null,
exitCode: null,
startedAt: null,
finishedAt: terminalEvent?.createdAt ?? null,
jobIdentity,
podIdentity: recordAt(job.result, "podIdentity"),
logPath: typeof runner.logPath === "string" ? runner.logPath : null,
retention,
kubernetes,
diagnosis: runnerJobDiagnosis(job, events),
createdAt: job.createdAt,
updatedAt: job.updatedAt,
valuesPrinted: false,
};
}
function latestTerminalEvent(events: RunEvent[], commandId: string): RunEvent | null {
for (const event of [...events].reverse()) {
if (event.payload.commandId && event.payload.commandId !== commandId) continue;
if (event.type === "terminal_status") return event;
if (event.type === "backend_status" && event.payload.phase === "command-terminal" && event.payload.commandId === commandId) return event;
}
return null;
}
function recordAt(record: JsonRecord, key: string): JsonRecord {
const value = record[key];
return typeof value === "object" && value !== null && !Array.isArray(value) ? value as JsonRecord : {};
}
function isTerminalStatus(value: unknown): value is TerminalStatus {
return value === "completed" || value === "failed" || value === "blocked" || value === "cancelled";
}