ci: migrate sentinel to gitea pac
This commit is contained in:
@@ -82,6 +82,7 @@ import {
|
||||
type WebProbeSentinelDashboardAction,
|
||||
type WebProbeSentinelOptions,
|
||||
type WebProbeSentinelReportView,
|
||||
type WebProbeSentinelSourceAuthority,
|
||||
} from "./hwlab-node-web-sentinel-cicd-shared";
|
||||
import {
|
||||
applySentinelArgoApplication,
|
||||
@@ -108,6 +109,8 @@ export type {
|
||||
WebProbeSentinelDashboardAction,
|
||||
WebProbeSentinelOptions,
|
||||
WebProbeSentinelReportView,
|
||||
WebProbeSentinelSourceAuthority,
|
||||
WebProbeSentinelSourceOverrideOptions,
|
||||
} from "./hwlab-node-web-sentinel-cicd-shared";
|
||||
export {
|
||||
arrayAt,
|
||||
@@ -143,13 +146,13 @@ export interface SentinelSourceOverride {
|
||||
readonly commit: string;
|
||||
readonly stageRef?: string | null;
|
||||
readonly mirrorCommit?: string | null;
|
||||
readonly sourceAuthority: "git-mirror-snapshot";
|
||||
readonly sourceAuthority: WebProbeSentinelSourceAuthority;
|
||||
}
|
||||
|
||||
export function runWebProbeSentinelCommand(spec: HwlabRuntimeLaneSpec, options: WebProbeSentinelOptions): RenderedCliResult {
|
||||
if (options.kind === "config") return withWebProbeSentinelConfigRendered(webProbeSentinelConfigPlan(spec, options.action, options.sentinelId));
|
||||
requireSentinelIdForRegistry(spec, options.sentinelId, `web-probe sentinel ${options.kind}`);
|
||||
const state = loadSentinelCicdState(spec, options.sentinelId, options.timeoutSeconds, sentinelSourceResolveMode(options));
|
||||
const state = loadSentinelCicdState(spec, options.sentinelId, options.timeoutSeconds, sentinelSourceResolveMode(options), sentinelSourceOverrideFromOptions(options));
|
||||
if (options.kind === "image") return runSentinelImage(state, options);
|
||||
if (options.kind === "control-plane") return runSentinelControlPlane(state, options);
|
||||
if (options.kind === "publish") return runSentinelPublishCurrent(state, options);
|
||||
@@ -159,6 +162,19 @@ export function runWebProbeSentinelCommand(spec: HwlabRuntimeLaneSpec, options:
|
||||
return runSentinelReport(state, options);
|
||||
}
|
||||
|
||||
function sentinelSourceOverrideFromOptions(options: WebProbeSentinelOptions): SentinelSourceOverride | null {
|
||||
if (options.kind !== "image" && options.kind !== "control-plane" && options.kind !== "publish") return null;
|
||||
const override = options.sourceOverride;
|
||||
if (override.sourceCommit === null && override.sourceStageRef === null && override.sourceMirrorCommit === null && override.sourceAuthority === null) return null;
|
||||
if (override.sourceCommit === null) throw new Error("--source-commit is required when overriding web-probe sentinel source");
|
||||
return {
|
||||
commit: override.sourceCommit,
|
||||
stageRef: override.sourceStageRef,
|
||||
mirrorCommit: override.sourceMirrorCommit,
|
||||
sourceAuthority: override.sourceAuthority ?? "git-mirror-snapshot",
|
||||
};
|
||||
}
|
||||
|
||||
function sentinelSourceResolveMode(options: WebProbeSentinelOptions): SourceResolveMode {
|
||||
if (options.kind === "image" && options.action === "build" && options.confirm && options.wait) return "sync";
|
||||
if (options.kind === "control-plane" && options.action === "trigger-current" && options.confirm && options.wait) return "sync";
|
||||
@@ -347,6 +363,51 @@ function runSentinelPublishCurrentConfirmedInner(state: SentinelCicdState, optio
|
||||
lane: state.spec.lane,
|
||||
sentinelId: state.sentinelId,
|
||||
});
|
||||
if (process.env.KUBERNETES_SERVICE_HOST && process.env.KUBERNETES_SERVICE_PORT) {
|
||||
const publish = runSentinelPublishJob(state, true, Math.max(1, remainingBudgetSeconds()), options.rerun);
|
||||
const elapsedMs = Date.now() - startedAt;
|
||||
const ok = record(publish).ok === true;
|
||||
const result = {
|
||||
ok,
|
||||
command,
|
||||
node: state.spec.nodeId,
|
||||
lane: state.spec.lane,
|
||||
sentinelId: state.sentinelId,
|
||||
mode: "pac-publish-only",
|
||||
mutation: true,
|
||||
specRef: SPEC_REF,
|
||||
source: state.sourceHead,
|
||||
image: state.image,
|
||||
pipelineRun: record(publish).jobName ?? sentinelPipelineRunName(state, options.rerun),
|
||||
controlPlane: {
|
||||
ok,
|
||||
mode: "pac-publish-only",
|
||||
mutation: true,
|
||||
source: state.sourceHead,
|
||||
publish,
|
||||
argo: {
|
||||
namespace: stringAt(state.cicd, "argo.namespace"),
|
||||
applicationName: stringAt(state.cicd, "argo.applicationName"),
|
||||
},
|
||||
valuesRedacted: true,
|
||||
},
|
||||
health: { ok: false, skipped: true, reason: "pac-publish-only-runtime-closeout-read-by-platform-infra-status", valuesRedacted: true },
|
||||
elapsedMs,
|
||||
timings: publishCurrentStageTimings({ publish }, null, elapsedMs),
|
||||
slowStages: publishCurrentSlowStages(state, publishCurrentStageTimings({ publish }, null, elapsedMs), budgetSeconds),
|
||||
withinBudget: elapsedMs <= budgetSeconds * 1000,
|
||||
warnings: [
|
||||
"PaC in-cluster publish-current submits the native sentinel publish PipelineRun and leaves Argo/runtime closeout to platform-infra pipelines-as-code status.",
|
||||
...sentinelCicdElapsedWarnings(record(publish).elapsedMs, "sentinel publish", controlPlaneWaitWarningSeconds(state)),
|
||||
...sentinelRemoteJobTimeoutWarnings(publish, "sentinel publish"),
|
||||
],
|
||||
blocker: ok ? null : { code: "sentinel-pac-publish-not-ready", reason: "sentinel publish PipelineRun did not complete successfully" },
|
||||
recoveryNext: controlPlaneRecoveryNext(state, ok, publish, null, false),
|
||||
next: publishCurrentNext(state),
|
||||
valuesRedacted: true,
|
||||
};
|
||||
return rendered(ok, command, renderPublishCurrentResult(result));
|
||||
}
|
||||
if (state.configReady && state.sourceHead.ok && remainingBudgetSeconds() >= 5) {
|
||||
interruptContext.phase = "already-current-registry-probe";
|
||||
const registryProbe = probeImageRegistry(state, Math.max(1, Math.min(remainingBudgetSeconds(), 5)));
|
||||
@@ -377,6 +438,7 @@ function runSentinelPublishCurrentConfirmedInner(state: SentinelCicdState, optio
|
||||
wait: true,
|
||||
timeoutSeconds: Math.max(1, remainingBudgetSeconds()),
|
||||
rerun: options.rerun,
|
||||
sourceOverride: options.sourceOverride,
|
||||
});
|
||||
let health: Record<string, unknown>;
|
||||
let healthElapsedMs: number | null = null;
|
||||
@@ -632,7 +694,7 @@ function sourceHeadFromOverride(cicd: Record<string, unknown>, override: Sentine
|
||||
timedOut: false,
|
||||
stdoutBytes: 0,
|
||||
stderrBytes: 0,
|
||||
stdoutPreview: "source supplied by cicd branch-follower k8s git-mirror snapshot",
|
||||
stdoutPreview: `source supplied by ${override.sourceAuthority}`,
|
||||
stderrPreview: "",
|
||||
},
|
||||
};
|
||||
@@ -755,8 +817,8 @@ function validateSentinelSourceAuthority(cicd: Record<string, unknown>): void {
|
||||
const allowHostGit = booleanAt(cicd, "sourceAuthority.allowHostGit");
|
||||
const allowGithubDirectInPipeline = booleanAt(cicd, "sourceAuthority.allowGithubDirectInPipeline");
|
||||
const missingObjectPolicy = stringAt(cicd, "sourceSnapshot.missingObjectPolicy");
|
||||
if (mode !== "gitMirrorSnapshot") throw new Error("sourceAuthority.mode must be gitMirrorSnapshot");
|
||||
if (resolver !== "k8s-git-mirror") throw new Error("sourceAuthority.resolver must be k8s-git-mirror");
|
||||
const supported = (mode === "gitMirrorSnapshot" && resolver === "k8s-git-mirror") || (mode === "giteaSnapshot" && resolver === "gitea-mirror");
|
||||
if (!supported) throw new Error("sourceAuthority must be gitMirrorSnapshot/k8s-git-mirror or giteaSnapshot/gitea-mirror");
|
||||
if (allowHostGit !== false) throw new Error("sourceAuthority.allowHostGit must be false");
|
||||
if (allowGithubDirectInPipeline !== false) throw new Error("sourceAuthority.allowGithubDirectInPipeline must be false");
|
||||
if (missingObjectPolicy !== "fail-fast") throw new Error("sourceSnapshot.missingObjectPolicy must be fail-fast");
|
||||
@@ -1597,8 +1659,13 @@ function sentinelControlPlaneConfirmedResult(state: SentinelCicdState, options:
|
||||
const deadline = startedAt + waitBudgetSeconds * 1000;
|
||||
const remainingCicdWaitSeconds = () => strictRemainingSeconds(deadline, waitBudgetSeconds);
|
||||
const remainingCommandSeconds = () => Math.max(1, remainingCicdWaitSeconds());
|
||||
const sourceMirrorProbe = applyOnly ? null : probeSourceMirror(state, Math.min(remainingCommandSeconds(), 20));
|
||||
const sourceMirrorSync = applyOnly ? null : record(sourceMirrorProbe).ok === true ? sentinelSourceMirrorAlreadyPresentResult(state, sourceMirrorProbe) : runSentinelSourceMirrorSyncJob(state, remainingCommandSeconds());
|
||||
const giteaSource = state.sourceHead.sourceAuthority === "gitea-snapshot" || state.sourceHead.sourceAuthority === "gitea-cache";
|
||||
const sourceMirrorProbe = applyOnly || giteaSource ? null : probeSourceMirror(state, Math.min(remainingCommandSeconds(), 20));
|
||||
const sourceMirrorSync = applyOnly
|
||||
? null
|
||||
: giteaSource
|
||||
? sentinelSourceMirrorAlreadyPresentResult(state, { ok: true, mode: "gitea-controlled-mirror-snapshot", stageRef: state.sourceHead.stageRef, sourceCommit: state.sourceHead.commit, valuesRedacted: true })
|
||||
: record(sourceMirrorProbe).ok === true ? sentinelSourceMirrorAlreadyPresentResult(state, sourceMirrorProbe) : runSentinelSourceMirrorSyncJob(state, remainingCommandSeconds());
|
||||
const sourceMirrorReady = applyOnly || record(sourceMirrorSync).ok === true;
|
||||
const publish = applyOnly
|
||||
? null
|
||||
|
||||
Reference in New Issue
Block a user