fix: use k8s git mirror source snapshots

This commit is contained in:
Codex
2026-07-01 10:32:05 +00:00
parent 79e419ce98
commit c90ad04bff
19 changed files with 481 additions and 168 deletions
+65 -4
View File
@@ -103,10 +103,71 @@ export function nodeRuntimeGitopsRoot(spec: HwlabRuntimeLaneSpec): string {
}
export function resolveNodeRuntimeLaneHead(spec: HwlabRuntimeLaneSpec): { sourceCommit: string | null; result: CommandResult } {
const result = runCommand(["git", "ls-remote", spec.gitUrl, `refs/heads/${spec.sourceBranch}`], repoRoot, { timeoutMs: 45_000 });
if (!isCommandSuccess(result)) return { sourceCommit: null, result };
const match = /[0-9a-f]{40}/iu.exec(statusText(result));
return { sourceCommit: match?.[0].toLowerCase() ?? null, result };
const mirror = nodeRuntimeSourceMirrorTarget(spec);
const script = [
"set +e",
`namespace=${shellQuote(mirror.namespace)}`,
`read_deploy=${shellQuote(mirror.serviceReadName)}`,
`repo_path=${shellQuote(`/cache/${mirror.sourceRepository}.git`)}`,
`source_branch=${shellQuote(mirror.sourceBranch)}`,
"read_ref() {",
" ref=\"$1\"",
" kubectl -n \"$namespace\" exec deploy/\"$read_deploy\" -- sh -lc 'repo_path=$1; ref=$2; git --git-dir=\"$repo_path\" rev-parse --verify \"$ref^{commit}\" 2>/dev/null' sh \"$repo_path\" \"$ref\" 2>/dev/null",
"}",
"mirror_stage=$(read_ref \"refs/mirror-stage/heads/$source_branch\")",
"mirror_stage_rc=$?",
"local_head=$(read_ref \"refs/heads/$source_branch\")",
"local_head_rc=$?",
"source_commit=\"$mirror_stage\"",
"source_ref=\"refs/mirror-stage/heads/$source_branch\"",
"if ! printf '%s' \"$source_commit\" | grep -Eq '^[0-9a-fA-F]{40}$'; then",
" source_commit=\"$local_head\"",
" source_ref=\"refs/heads/$source_branch\"",
"fi",
"node - \"$mirror_stage_rc\" \"$local_head_rc\" \"$mirror_stage\" \"$local_head\" \"$source_commit\" \"$source_ref\" \"$repo_path\" \"$source_branch\" <<'NODE'",
"const [mirrorStageRc, localHeadRc, mirrorStage, localHead, sourceCommit, sourceRef, repoPath, branch] = process.argv.slice(2);",
"const isSha = (value) => /^[0-9a-f]{40}$/i.test(value || '');",
"const ok = isSha(sourceCommit);",
"console.log(JSON.stringify({ ok, mode: 'k8s-git-mirror-cache', sourceAuthority: 'git-mirror-cache', sourceCommit: ok ? sourceCommit.toLowerCase() : null, sourceRef: ok ? sourceRef : null, mirrorStage: isSha(mirrorStage) ? mirrorStage.toLowerCase() : null, localHead: isSha(localHead) ? localHead.toLowerCase() : null, mirrorStageRc: Number(mirrorStageRc), localHeadRc: Number(localHeadRc), branch, repoPath, valuesRedacted: true }));",
"NODE",
].join("\n");
const result = runNodeK3sScript(spec, script, 45);
const payload = parseJsonObject(result.stdout);
const payloadCommit = typeof payload.sourceCommit === "string" && /^[0-9a-f]{40}$/iu.test(payload.sourceCommit) ? payload.sourceCommit.toLowerCase() : null;
const match = payloadCommit ?? /[0-9a-f]{40}/iu.exec(statusText(result))?.[0].toLowerCase() ?? null;
return { sourceCommit: result.exitCode === 0 ? match : null, result };
}
interface NodeRuntimeSourceMirrorTarget {
readonly namespace: string;
readonly serviceReadName: string;
readonly sourceRepository: string;
readonly sourceBranch: string;
}
function nodeRuntimeSourceMirrorTarget(spec: HwlabRuntimeLaneSpec): NodeRuntimeSourceMirrorTarget {
const configPath = rootPath(HWLAB_NODE_CONTROL_PLANE_CONFIG_PATH);
const parsed = runtimeRecord(Bun.YAML.parse(readFileSync(configPath, "utf8")));
const targets = Array.isArray(parsed.targets) ? parsed.targets.map((item) => runtimeRecord(item)) : [];
const target = targets.find((item) => item.node === spec.nodeId && item.lane === spec.lane);
if (target === undefined) throw new Error(`no control-plane target for node=${spec.nodeId} lane=${spec.lane} in ${HWLAB_NODE_CONTROL_PLANE_CONFIG_PATH}`);
const gitMirror = runtimeRecord(target.gitMirror);
const source = runtimeRecord(target.source);
return {
namespace: runtimeString(gitMirror.namespace, "gitMirror.namespace"),
serviceReadName: runtimeString(gitMirror.serviceReadName, "gitMirror.serviceReadName"),
sourceRepository: runtimeString(source.repository, "source.repository"),
sourceBranch: runtimeString(source.branch, "source.branch"),
};
}
function runtimeRecord(value: unknown): Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};
}
function runtimeString(value: unknown, path: string): string {
if (typeof value !== "string" || value.length === 0) throw new Error(`${path} must be a non-empty string`);
return value;
}
export function runtimeLaneCicdRepoEnsureScript(spec: HwlabRuntimeLaneSpec): string {