fix: compact agentrun status diagnostics
This commit is contained in:
+118
-18
@@ -2115,6 +2115,7 @@ async function statusYamlLane(config: UniDeskConfig, options: StatusOptions, tar
|
||||
const secrets = record(runtimePayload.secrets);
|
||||
const localPostgres = record(runtimePayload.localPostgres);
|
||||
const expectedGitopsRevision = stringOrNull(mirrorPayload.gitopsCommit);
|
||||
const mirrorSourceCommit = stringOrNull(mirrorPayload.sourceCommit);
|
||||
const pipelineRunSourceCommit = stringOrNull(pipelineRunStatus.sourceCommit);
|
||||
const sourceCommit = options.sourceCommit
|
||||
?? (options.pipelineRun !== null ? pipelineRunSourceCommit ?? initialSourceCommit : initialSourceCommit);
|
||||
@@ -2167,16 +2168,94 @@ async function statusYamlLane(config: UniDeskConfig, options: StatusOptions, tar
|
||||
...(secrets.ready === true ? [] : ["lane-secret-missing"]),
|
||||
...(spec.database.localPostgresExpectedAbsent && localPostgres.absent !== true ? ["local-postgres-present"] : []),
|
||||
];
|
||||
const ciBlockerNames = new Set(["ci-namespace-missing", "pipeline-missing", "pipelinerun-missing", "pipelinerun-not-succeeded", "ci-serviceaccount-missing"]);
|
||||
const ciBlockers = blockers.filter((blocker) => ciBlockerNames.has(blocker));
|
||||
const runtimeBlockers = blockers.filter((blocker) => !ciBlockerNames.has(blocker));
|
||||
const aligned = blockers.length === 0 && pipelineSucceeded && argoSyncedToGitops && managerSourceMatchesExpected;
|
||||
const runtimeAligned = runtimeBlockers.length === 0 && argoSyncedToGitops && managerSourceMatchesExpected;
|
||||
const ciEvidenceMissing = pipelineRunName !== null && pipelineRunStatus.exists !== true;
|
||||
const mirrorAlreadySynced = mirrorPayload.readReady === true
|
||||
&& mirrorPayload.writeReady === true
|
||||
&& sourceCommit !== null
|
||||
&& mirrorSourceCommit === sourceCommit
|
||||
&& expectedGitopsRevision !== null;
|
||||
const runtimeAlignment = {
|
||||
pipelineSucceeded,
|
||||
argoRevision: stringOrNull(argo.revision),
|
||||
argoSyncedToGitops,
|
||||
managerSourceCommit: stringOrNull(manager.sourceCommit),
|
||||
managerSourceMatchesExpected,
|
||||
runtimeAligned,
|
||||
};
|
||||
const summary = {
|
||||
const statusFullCommand = agentRunControlPlaneStatusCommand(spec, options, true);
|
||||
const triggerCurrentCommand = `bun scripts/cli.ts agentrun control-plane trigger-current --node ${spec.nodeId} --lane ${spec.lane} --confirm`;
|
||||
const nextAction = aligned
|
||||
? { code: "none", summary: "lane aligned; no action required", command: null }
|
||||
: ciEvidenceMissing && runtimeAligned && mirrorAlreadySynced
|
||||
? { code: "ci-evidence-missing", summary: "runtime and git mirror are aligned, but the expected PipelineRun evidence is missing; rerun trigger-current to recreate CI evidence", command: triggerCurrentCommand }
|
||||
: sourceBranchAdvanced
|
||||
? { code: "target-superseded", summary: "target commit is no longer the branch tip; trigger-current against latest source before closeout", command: triggerCurrentCommand }
|
||||
: ciBlockers.length > 0
|
||||
? { code: "ci-blocked", summary: `CI evidence is blocked: ${ciBlockers.join(", ")}`, command: statusFullCommand }
|
||||
: runtimeBlockers.length > 0
|
||||
? { code: "runtime-blocked", summary: `runtime alignment is blocked: ${runtimeBlockers.join(", ")}`, command: statusFullCommand }
|
||||
: { code: "inspect-full-status", summary: "alignment is inconclusive; inspect full status details", command: statusFullCommand };
|
||||
const compactSourceStatus = {
|
||||
workspaceExists: sourcePayload.workspaceExists ?? false,
|
||||
workspaceClean: sourcePayload.workspaceClean ?? null,
|
||||
branch: sourcePayload.branch ?? null,
|
||||
remoteBranchExists: sourcePayload.remoteBranchExists ?? false,
|
||||
remoteBranchCommit: sourcePayload.remoteBranchCommit ?? null,
|
||||
workspaceDetached: sourceWorktreeDetached,
|
||||
};
|
||||
const compactGitMirrorStatus = {
|
||||
readReady: mirrorPayload.readReady ?? false,
|
||||
writeReady: mirrorPayload.writeReady ?? false,
|
||||
cachePvcExists: mirrorPayload.cachePvcExists ?? false,
|
||||
sourceCommit: mirrorSourceCommit,
|
||||
gitopsCommit: expectedGitopsRevision,
|
||||
alreadySynced: mirrorAlreadySynced,
|
||||
};
|
||||
const compactCiStatus = {
|
||||
namespaceExists: runtimePayload.ciNamespaceExists ?? false,
|
||||
serviceAccountExists: runtimePayload.serviceAccountExists ?? false,
|
||||
pipelineExists: pipeline.exists ?? false,
|
||||
pipelineRun: {
|
||||
name: pipelineRunName,
|
||||
exists: pipelineRunStatus.exists ?? false,
|
||||
status: pipelineRunStatus.status ?? null,
|
||||
reason: pipelineRunStatus.reason ?? null,
|
||||
sourceCommit: pipelineRunSourceCommit,
|
||||
},
|
||||
evidenceMissing: ciEvidenceMissing,
|
||||
blockers: ciBlockers,
|
||||
};
|
||||
const compactArgoStatus = {
|
||||
exists: argo.exists ?? false,
|
||||
application: argo.application ?? null,
|
||||
revision: stringOrNull(argo.revision),
|
||||
syncStatus: argo.syncStatus ?? null,
|
||||
healthStatus: argo.healthStatus ?? null,
|
||||
syncedToGitops: argoSyncedToGitops,
|
||||
};
|
||||
const compactRuntimeStatus = {
|
||||
namespaceExists: runtimePayload.runtimeNamespaceExists ?? false,
|
||||
manager: {
|
||||
deploymentExists: manager.deploymentExists ?? false,
|
||||
serviceExists: manager.serviceExists ?? false,
|
||||
sourceCommit: stringOrNull(manager.sourceCommit),
|
||||
sourceMatchesExpected: managerSourceMatchesExpected,
|
||||
},
|
||||
databaseSecretPresent: database.secretPresent ?? null,
|
||||
secretsReady: secrets.ready ?? null,
|
||||
localPostgresAbsent: localPostgres.absent ?? null,
|
||||
blockers: runtimeBlockers,
|
||||
};
|
||||
const detailedSummary = {
|
||||
aligned,
|
||||
runtimeAligned,
|
||||
ciEvidenceMissing,
|
||||
mirrorAlreadySynced,
|
||||
blockers,
|
||||
warnings,
|
||||
sourceCommit,
|
||||
@@ -2198,14 +2277,17 @@ async function statusYamlLane(config: UniDeskConfig, options: StatusOptions, tar
|
||||
writeReady: mirrorPayload.writeReady ?? false,
|
||||
cachePvcExists: mirrorPayload.cachePvcExists ?? false,
|
||||
repositoryCount: Array.isArray(mirrorPayload.repositories) ? mirrorPayload.repositories.length : null,
|
||||
sourceCommit: stringOrNull(mirrorPayload.sourceCommit),
|
||||
sourceCommit: mirrorSourceCommit,
|
||||
gitopsCommit: expectedGitopsRevision,
|
||||
alreadySynced: mirrorAlreadySynced,
|
||||
},
|
||||
ci: {
|
||||
namespaceExists: runtimePayload.ciNamespaceExists ?? false,
|
||||
serviceAccountExists: runtimePayload.serviceAccountExists ?? false,
|
||||
pipeline,
|
||||
pipelineRun: pipelineRunStatus,
|
||||
evidenceMissing: ciEvidenceMissing,
|
||||
blockers: ciBlockers,
|
||||
},
|
||||
argo,
|
||||
runtime: {
|
||||
@@ -2223,17 +2305,39 @@ async function statusYamlLane(config: UniDeskConfig, options: StatusOptions, tar
|
||||
secrets: compactLaneSecretsStatus(secrets),
|
||||
localPostgres,
|
||||
},
|
||||
nextAction,
|
||||
};
|
||||
const commanderSummary = {
|
||||
aligned,
|
||||
runtimeAligned,
|
||||
ciEvidenceMissing,
|
||||
mirrorAlreadySynced,
|
||||
blockers,
|
||||
warnings,
|
||||
sourceCommit,
|
||||
expectedPipelineRun: pipelineRunName,
|
||||
expectedGitopsRevision,
|
||||
runtimeAlignment,
|
||||
branchDrift,
|
||||
source: compactSourceStatus,
|
||||
gitMirror: compactGitMirrorStatus,
|
||||
ci: compactCiStatus,
|
||||
argo: compactArgoStatus,
|
||||
runtime: compactRuntimeStatus,
|
||||
nextAction,
|
||||
};
|
||||
const statusFullCommand = agentRunControlPlaneStatusCommand(spec, options, true);
|
||||
const result: Record<string, unknown> = {
|
||||
ok: sourceProbe.value.exitCode === 0 && runtimeProbe.value.exitCode === 0 && mirrorProbe.value.exitCode === 0 && blockers.length === 0,
|
||||
command: "agentrun control-plane status",
|
||||
mode: "yaml-declared-node-lane",
|
||||
configPath: target.configPath,
|
||||
target: options.full || options.raw ? agentRunLaneSummary(spec) : compactAgentRunLaneStatusTarget(spec),
|
||||
summary,
|
||||
summary: options.full || options.raw ? detailedSummary : commanderSummary,
|
||||
alignment: {
|
||||
aligned,
|
||||
runtimeAligned,
|
||||
ciEvidenceMissing,
|
||||
mirrorAlreadySynced,
|
||||
blockers,
|
||||
warnings,
|
||||
sourceCommit,
|
||||
@@ -2248,29 +2352,33 @@ async function statusYamlLane(config: UniDeskConfig, options: StatusOptions, tar
|
||||
gitMirrorMs: mirrorProbe.elapsedMs,
|
||||
totalMs: sourceProbe.elapsedMs + Math.max(runtimeProbe.elapsedMs, mirrorProbe.elapsedMs),
|
||||
},
|
||||
captures: {
|
||||
source: compactCapture(sourceProbe.value, { full: options.full || options.raw || sourceProbe.value.exitCode !== 0 }),
|
||||
runtime: compactCapture(runtimeProbe.value, { full: options.full || options.raw || runtimeProbe.value.exitCode !== 0 }),
|
||||
gitMirror: compactCapture(mirrorProbe.value, { full: options.full || options.raw || mirrorProbe.value.exitCode !== 0 }),
|
||||
},
|
||||
disclosure: {
|
||||
output: options.full || options.raw ? "full" : "compact-summary",
|
||||
full: options.full,
|
||||
raw: options.raw,
|
||||
omittedWhenCompact: options.full || options.raw ? [] : ["full target YAML summary", "source", "runtime", "gitMirror", "capture stdout/stderr tails for successful probes"],
|
||||
omittedWhenCompact: options.full || options.raw ? [] : ["full target YAML summary", "detailed source/runtime/gitMirror objects", "capture stdout/stderr tails for successful probes"],
|
||||
fullCommand: statusFullCommand,
|
||||
},
|
||||
next: {
|
||||
action: nextAction,
|
||||
plan: `bun scripts/cli.ts agentrun control-plane plan --node ${spec.nodeId} --lane ${spec.lane}`,
|
||||
postgresStatus: spec.database.configRef ? `bun scripts/cli.ts platform-db postgres status --config ${spec.database.configRef}` : null,
|
||||
postgresApply: spec.database.configRef ? `bun scripts/cli.ts platform-db postgres apply --config ${spec.database.configRef} --confirm` : null,
|
||||
secretSync: `bun scripts/cli.ts agentrun control-plane secret-sync --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
|
||||
restart: `bun scripts/cli.ts agentrun control-plane restart --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
|
||||
statusFull: statusFullCommand,
|
||||
triggerCurrent: ciEvidenceMissing || sourceBranchAdvanced ? triggerCurrentCommand : null,
|
||||
triggerLatest: sourceBranchAdvanced ? `bun scripts/cli.ts agentrun control-plane trigger-current --node ${spec.nodeId} --lane ${spec.lane} --confirm` : null,
|
||||
},
|
||||
valuesPrinted: false,
|
||||
};
|
||||
if (options.full || options.raw || sourceProbe.value.exitCode !== 0 || runtimeProbe.value.exitCode !== 0 || mirrorProbe.value.exitCode !== 0) {
|
||||
result.captures = {
|
||||
source: compactCapture(sourceProbe.value, { full: options.full || options.raw || sourceProbe.value.exitCode !== 0 }),
|
||||
runtime: compactCapture(runtimeProbe.value, { full: options.full || options.raw || runtimeProbe.value.exitCode !== 0 }),
|
||||
gitMirror: compactCapture(mirrorProbe.value, { full: options.full || options.raw || mirrorProbe.value.exitCode !== 0 }),
|
||||
};
|
||||
}
|
||||
if (options.full || options.raw) {
|
||||
result.source = sourcePayload;
|
||||
result.runtime = runtimePayload;
|
||||
@@ -2322,24 +2430,19 @@ function compactAgentRunLaneStatusTarget(spec: AgentRunLaneSpec): Record<string,
|
||||
source: {
|
||||
repository: spec.source.repository,
|
||||
branch: spec.source.branch,
|
||||
workspace: spec.source.workspace,
|
||||
},
|
||||
runtime: {
|
||||
namespace: spec.runtime.namespace,
|
||||
managerDeployment: spec.runtime.managerDeployment,
|
||||
managerService: spec.runtime.managerService,
|
||||
internalBaseUrl: spec.runtime.internalBaseUrl,
|
||||
},
|
||||
ci: {
|
||||
namespace: spec.ci.namespace,
|
||||
pipeline: spec.ci.pipeline,
|
||||
pipelineRunPrefix: spec.ci.pipelineRunPrefix,
|
||||
registryPrefix: spec.ci.registryPrefix,
|
||||
},
|
||||
gitops: {
|
||||
branch: spec.gitops.branch,
|
||||
path: spec.gitops.path,
|
||||
argoNamespace: spec.gitops.argoNamespace,
|
||||
argoApplication: spec.gitops.argoApplication,
|
||||
},
|
||||
gitMirror: {
|
||||
@@ -2352,9 +2455,6 @@ function compactAgentRunLaneStatusTarget(spec: AgentRunLaneSpec): Record<string,
|
||||
mode: spec.database.mode,
|
||||
provider: spec.database.provider,
|
||||
configRef: spec.database.configRef,
|
||||
database: spec.database.database,
|
||||
user: spec.database.user,
|
||||
secretRef: spec.database.secretRef,
|
||||
localPostgresExpectedAbsent: spec.database.localPostgresExpectedAbsent,
|
||||
valuesPrinted: false,
|
||||
},
|
||||
|
||||
+7
-2
@@ -241,13 +241,14 @@ function summarizeJobProgress(job: JobRecord, maxBytes = 96_000, tails?: { stdou
|
||||
|| /^hwlab_nodes_v[0-9]{2}_git-mirror_(sync|flush)$/u.test(job.name);
|
||||
const ciInstallWorkflow = job.name === "ci_install";
|
||||
if (ciInstallWorkflow) return summarizeCiInstallJobProgress(job, tails?.stderrTail, nowMs);
|
||||
if (!knownWorkflow && !v02PrMonitorWorkflow && !runtimeLaneTriggerWorkflow && !agentRunYamlLaneTriggerWorkflow && !gitMirrorWorkflow) return genericJobProgress(job, tails?.stderrTail);
|
||||
const progressTailBytes = Math.max(4096, Math.floor(maxBytes));
|
||||
const stderrTail = tails?.stderrTail ?? tailFile(job.stderrFile, progressTailBytes);
|
||||
const agentRunYamlLaneProgressObserved = agentRunYamlLaneTriggerWorkflow || hasAgentRunYamlLaneProgressEvents(stderrTail);
|
||||
if (!knownWorkflow && !v02PrMonitorWorkflow && !runtimeLaneTriggerWorkflow && !agentRunYamlLaneProgressObserved && !gitMirrorWorkflow) return genericJobProgress(job, stderrTail);
|
||||
const stdoutTail = tails?.stdoutTail ?? tailFile(job.stdoutFile, progressTailBytes);
|
||||
if (gitMirrorWorkflow) return summarizeGitMirrorJobProgress(job, stdoutTail, stderrTail, nowMs);
|
||||
if (runtimeLaneTriggerWorkflow) return summarizeRuntimeLaneTriggerJobProgress(job, stdoutTail, stderrTail, nowMs);
|
||||
if (agentRunYamlLaneTriggerWorkflow) return summarizeAgentRunYamlLaneTriggerJobProgress(job, stdoutTail, stderrTail, nowMs);
|
||||
if (agentRunYamlLaneProgressObserved) return summarizeAgentRunYamlLaneTriggerJobProgress(job, stdoutTail, stderrTail, nowMs);
|
||||
const events = v02PrMonitorWorkflow
|
||||
? [
|
||||
...parseJsonLineEvents(stderrTail, "hwlab.v02.pr-monitor.progress"),
|
||||
@@ -509,6 +510,10 @@ const agentRunYamlLaneProgressEvents = [
|
||||
{ event: "agentrun.yaml-lane.git-mirror.progress", stage: "git-mirror" },
|
||||
] as const;
|
||||
|
||||
function hasAgentRunYamlLaneProgressEvents(text: string): boolean {
|
||||
return agentRunYamlLaneProgressEvents.some(({ event }) => parseJsonLineEvents(text, event).length > 0);
|
||||
}
|
||||
|
||||
function summarizeAgentRunYamlLaneTriggerJobProgress(job: JobRecord, stdoutTail: string, stderrTail: string, nowMs = Date.now()): JobProgressSummary {
|
||||
const events = agentRunYamlLaneProgressEvents
|
||||
.flatMap(({ event, stage }) => parseJsonLineEvents(stderrTail, event).map((item) => ({ ...item, stage })))
|
||||
|
||||
Reference in New Issue
Block a user