fix: compact branch follower state
This commit is contained in:
+99
-6
@@ -1971,6 +1971,7 @@ function kubeConfigMapFollowerState(registry: BranchFollowerRegistry, options: P
|
||||
return { ok: true, stateByFollower: {}, present: false, error: "" };
|
||||
}
|
||||
present = true;
|
||||
if (result.omitted) continue;
|
||||
if (result.value === null || result.value.length === 0) continue;
|
||||
const parsed = parseJsonObject(result.value);
|
||||
if (parsed === null) {
|
||||
@@ -1987,8 +1988,9 @@ function kubeConfigMapFollowerState(registry: BranchFollowerRegistry, options: P
|
||||
};
|
||||
}
|
||||
|
||||
function kubeConfigMapDataValue(registry: BranchFollowerRegistry, options: ParsedOptions, key: string): { ok: boolean; present: boolean; value: string | null; error: string } {
|
||||
function kubeConfigMapDataValue(registry: BranchFollowerRegistry, options: ParsedOptions, key: string): { ok: boolean; present: boolean; value: string | null; omitted: boolean; error: string } {
|
||||
const template = `{{ with index .data ${JSON.stringify(key)} }}{{ . }}{{ end }}`;
|
||||
const maxValueBytes = 4096;
|
||||
const script = [
|
||||
"set -eu",
|
||||
"tmpdir=$(mktemp -d)",
|
||||
@@ -1996,18 +1998,24 @@ function kubeConfigMapDataValue(registry: BranchFollowerRegistry, options: Parse
|
||||
"trap cleanup EXIT INT TERM",
|
||||
`NAMESPACE=${shQuote(registry.controller.namespace)}`,
|
||||
`CONFIGMAP=${shQuote(registry.controller.stateConfigMapName)}`,
|
||||
"export NAMESPACE CONFIGMAP",
|
||||
`MAX_VALUE_BYTES=${maxValueBytes}`,
|
||||
"export NAMESPACE CONFIGMAP MAX_VALUE_BYTES",
|
||||
`if ! value=$(kubectl -n "$NAMESPACE" get configmap "$CONFIGMAP" -o go-template=${shQuote(template)} 2>"$tmpdir/error"); then`,
|
||||
" error_b64=$(tail -c 800 \"$tmpdir/error\" | base64 | tr -d '\\n')",
|
||||
" if grep -qi 'not found' \"$tmpdir/error\"; then",
|
||||
" printf '{\"ok\":true,\"present\":false,\"valueB64\":null,\"errorB64\":\"%s\"}' \"$error_b64\"",
|
||||
" printf '{\"ok\":true,\"present\":false,\"valueB64\":null,\"omitted\":false,\"errorB64\":\"%s\"}' \"$error_b64\"",
|
||||
" exit 0",
|
||||
" fi",
|
||||
" printf '{\"ok\":false,\"present\":false,\"valueB64\":null,\"errorB64\":\"%s\"}' \"$error_b64\"",
|
||||
" printf '{\"ok\":false,\"present\":false,\"valueB64\":null,\"omitted\":false,\"errorB64\":\"%s\"}' \"$error_b64\"",
|
||||
" exit 0",
|
||||
"fi",
|
||||
"value_bytes=$(printf '%s' \"$value\" | wc -c | tr -d ' ')",
|
||||
"if [ \"${value_bytes:-0}\" -gt \"$MAX_VALUE_BYTES\" ]; then",
|
||||
" printf '{\"ok\":true,\"present\":true,\"valueB64\":null,\"omitted\":true,\"valueBytes\":%s,\"errorB64\":\"\"}' \"$value_bytes\"",
|
||||
" exit 0",
|
||||
"fi",
|
||||
"value_b64=$(printf '%s' \"$value\" | base64 | tr -d '\\n')",
|
||||
"printf '{\"ok\":true,\"present\":true,\"valueB64\":\"%s\",\"errorB64\":\"\"}' \"$value_b64\"",
|
||||
"printf '{\"ok\":true,\"present\":true,\"valueB64\":\"%s\",\"omitted\":false,\"valueBytes\":%s,\"errorB64\":\"\"}' \"$value_b64\" \"$value_bytes\"",
|
||||
].join("\n");
|
||||
const result = runKubeScript(registry, options, script, "", 10_000);
|
||||
const parsed = result.exitCode === 0 ? parseJsonObject(result.stdout) : null;
|
||||
@@ -2016,6 +2024,7 @@ function kubeConfigMapDataValue(registry: BranchFollowerRegistry, options: Parse
|
||||
ok: false,
|
||||
present: false,
|
||||
value: null,
|
||||
omitted: false,
|
||||
error: redactText(tailText(result.stderr || result.stdout, 800)),
|
||||
};
|
||||
}
|
||||
@@ -2023,11 +2032,13 @@ function kubeConfigMapDataValue(registry: BranchFollowerRegistry, options: Parse
|
||||
const error = errorB64.length === 0 ? "" : Buffer.from(errorB64, "base64").toString("utf8");
|
||||
const ok = parsed.ok === true;
|
||||
const present = parsed.present === true;
|
||||
const omitted = parsed.omitted === true;
|
||||
const valueB64 = typeof parsed.valueB64 === "string" ? parsed.valueB64 : null;
|
||||
return {
|
||||
ok,
|
||||
present,
|
||||
value: valueB64 === null ? null : Buffer.from(valueB64, "base64").toString("utf8"),
|
||||
omitted,
|
||||
error: redactText(error),
|
||||
};
|
||||
}
|
||||
@@ -2089,8 +2100,90 @@ function runKubeScript(registry: BranchFollowerRegistry, options: ParsedOptions,
|
||||
return runCommand([transPath(), registry.controller.kubeRoute, "sh"], repoRoot, { input: `${script}\n`, timeoutMs });
|
||||
}
|
||||
|
||||
function compactFollowerStateForConfigMap(state: FollowerState): Record<string, unknown> {
|
||||
return {
|
||||
id: state.id,
|
||||
adapter: state.adapter,
|
||||
enabled: state.enabled,
|
||||
phase: state.phase,
|
||||
source: state.source,
|
||||
target: state.target,
|
||||
lastTriggeredSha: state.lastTriggeredSha,
|
||||
lastSucceededSha: state.lastSucceededSha,
|
||||
pipelineRun: state.pipelineRun,
|
||||
inFlightJob: state.inFlightJob,
|
||||
budgetSource: state.budgetSource,
|
||||
controller: state.controller,
|
||||
decision: state.decision,
|
||||
dryRun: state.dryRun,
|
||||
updatedAt: state.updatedAt,
|
||||
warnings: state.warnings.slice(0, 6),
|
||||
stateFormat: "compact-v1",
|
||||
command: compactStateCommand(state.command),
|
||||
};
|
||||
}
|
||||
|
||||
function compactStateCommand(command: Record<string, unknown> | undefined): Record<string, unknown> | undefined {
|
||||
if (command === undefined) return undefined;
|
||||
const closeout = asOptionalRecord(command.closeout);
|
||||
const closeoutSummary = asOptionalRecord(closeout?.summary);
|
||||
const payload = compactNativePayload(asOptionalRecord(command.payload)) ?? closeoutSummary;
|
||||
return {
|
||||
mode: stringOrNull(command.mode) ?? stringOrNull(command.status),
|
||||
namespace: stringOrNull(command.namespace),
|
||||
pipelineRun: stringOrNull(command.pipelineRun),
|
||||
sourceCommit: stringOrNull(command.sourceCommit),
|
||||
sourceStageRef: stringOrNull(command.sourceStageRef),
|
||||
wait: command.wait === true ? true : undefined,
|
||||
pipelineRunCompleted: command.pipelineRunCompleted === true ? true : undefined,
|
||||
stillRunning: command.stillRunning === true ? true : undefined,
|
||||
closeout: closeout === null
|
||||
? null
|
||||
: {
|
||||
ok: closeout.ok === true,
|
||||
completed: closeout.completed === true,
|
||||
timedOut: closeout.timedOut === true,
|
||||
polls: numberOrNull(closeout.polls),
|
||||
elapsedMs: numberOrNull(closeout.elapsedMs),
|
||||
summary: closeoutSummary,
|
||||
statusAuthority: stringOrNull(closeout.statusAuthority),
|
||||
parsedDownstreamCliOutput: false,
|
||||
},
|
||||
payload,
|
||||
exitCode: numberOrNull(command.exitCode),
|
||||
timedOut: command.timedOut === true,
|
||||
statusAuthority: stringOrNull(command.statusAuthority),
|
||||
parsedDownstreamCliOutput: false,
|
||||
};
|
||||
}
|
||||
|
||||
function compactNativePayload(payload: Record<string, unknown> | null): Record<string, unknown> | null {
|
||||
if (payload === null) return null;
|
||||
return {
|
||||
source: compactSourcePayload(asOptionalRecord(payload.source)),
|
||||
tekton: asOptionalRecord(payload.tekton),
|
||||
argo: asOptionalRecord(payload.argo),
|
||||
runtime: asOptionalRecord(payload.runtime),
|
||||
errors: Array.isArray(payload.errors) ? payload.errors.slice(0, 5) : [],
|
||||
statusAuthority: stringOrNull(payload.statusAuthority),
|
||||
parsedDownstreamCliOutput: false,
|
||||
};
|
||||
}
|
||||
|
||||
function compactSourcePayload(source: Record<string, unknown> | null): Record<string, unknown> | null {
|
||||
if (source === null) return null;
|
||||
return {
|
||||
commit: stringOrNull(source.commit),
|
||||
branch: stringOrNull(source.branch),
|
||||
repository: stringOrNull(source.repository),
|
||||
stageRef: stringOrNull(source.stageRef),
|
||||
sourceAuthority: stringOrNull(source.sourceAuthority),
|
||||
repoPath: stringOrNull(source.repoPath),
|
||||
};
|
||||
}
|
||||
|
||||
function writeFollowerState(registry: BranchFollowerRegistry, state: FollowerState, options: ParsedOptions): CommandResult {
|
||||
const json = JSON.stringify(state);
|
||||
const json = JSON.stringify(compactFollowerStateForConfigMap(state));
|
||||
const dataPatch = JSON.stringify({ data: { [state.id]: json, _updatedAt: new Date().toISOString(), _specRef: SPEC_REF } });
|
||||
if (options.controller) {
|
||||
const patchBase64 = Buffer.from(dataPatch, "utf8").toString("base64");
|
||||
|
||||
Reference in New Issue
Block a user