fix: route D601 git mirror flush through YAML proxy (#568)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-21 12:52:36 +08:00
committed by GitHub
parent c849c95815
commit d25580c57c
2 changed files with 64 additions and 8 deletions
+26
View File
@@ -237,7 +237,9 @@ interface NodeRuntimeGitMirrorTargetSpec {
serviceReadName: string;
serviceWriteName: string;
cachePvcName: string;
cachePvcStorage: string;
cacheHostPath: string | null;
servicePort: number;
secretName: string;
syncConfigMapName: string;
syncJobPrefix: string;
@@ -2995,7 +2997,9 @@ function nodeRuntimeGitMirrorRetryableFailure(
retryMaxAttempts: number,
): Record<string, unknown> | null {
const text = `${result.stdout}\n${result.stderr}`;
const proxyConnectFailure = /hwlab git-mirror proxy-connect:/iu.test(text);
const retryable = partialSuccess !== null
|| proxyConnectFailure
|| /kex_exchange_identification|Connection closed by remote host|Could not read from remote repository|ssh.github.com|github.com|fetch-pack|early EOF/iu.test(text);
if (!retryable) return null;
const retryLabel = `${attempt}/${retryMaxAttempts}`;
@@ -3011,6 +3015,8 @@ function nodeRuntimeGitMirrorRetryableFailure(
nextRetryDelayMs: exhausted ? null : nodeRuntimeGitMirrorRetryDelayMs(attempt),
reason: partialSuccess !== null
? "GitOps push appears to have succeeded, but the post-push fetch/recheck failed. Standard git-mirror stops without host workspace fallback."
: proxyConnectFailure
? "Git mirror job hit a retryable YAML-first proxy CONNECT failure. Standard git-mirror keeps using the configured node-global proxy and stops when retry budget is exhausted."
: "Git mirror job hit a retryable upstream GitHub SSH/fetch failure. Standard git-mirror stops without host workspace fallback.",
refSources: nodeRuntimeGitMirrorRefSources(scoped, mirror),
next: exhausted
@@ -4101,6 +4107,7 @@ function renderNodeRuntimeControlPlaneOnNode(spec: HwlabRuntimeLaneSpec, sourceC
" envRecipe: { ...(lane.envRecipe || {}), downloadStack },",
"};",
"if (overlay.runtimeStore !== undefined) doc.lanes[overlay.lane].runtimeStore = overlay.runtimeStore;",
"if (overlay.gitMirror !== undefined) doc.lanes[overlay.lane].gitMirror = overlay.gitMirror;",
"fs.writeFileSync(path, YAML.stringify(doc));",
"NODE",
"if [ -f scripts/gitops-render.mjs ]; then render_script=scripts/gitops-render.mjs; else echo 'render script missing: scripts/gitops-render.mjs' >&2; exit 43; fi",
@@ -4184,6 +4191,7 @@ function renderNodeRuntimeControlPlaneLocal(spec: HwlabRuntimeLaneSpec, sourceCo
" envRecipe: { ...(lane.envRecipe || {}), downloadStack },",
"};",
"if (overlay.runtimeStore !== undefined) doc.lanes[overlay.lane].runtimeStore = overlay.runtimeStore;",
"if (overlay.gitMirror !== undefined) doc.lanes[overlay.lane].gitMirror = overlay.gitMirror;",
"fs.writeFileSync(path, YAML.stringify(doc));",
"NODE",
"if [ -f scripts/gitops-render.mjs ]; then render_script=scripts/gitops-render.mjs; else echo 'render script missing: scripts/gitops-render.mjs' >&2; exit 43; fi",
@@ -5145,6 +5153,15 @@ function nodeRuntimePipelinePostprocessScript(): string[] {
function nodeRuntimeRenderOverlay(spec: HwlabRuntimeLaneSpec): Record<string, unknown> {
const gitSshProxy = httpProxyEndpoint(spec.networkProfile.proxy.http);
const gitMirror = nodeRuntimeGitMirrorTarget(spec);
const renderGitMirror = {
...gitMirror,
egressProxy: {
...gitMirror.egressProxy,
mode: "node-global",
required: true,
},
};
return {
nodeId: spec.nodeId,
lane: spec.lane,
@@ -5161,6 +5178,7 @@ function nodeRuntimeRenderOverlay(spec: HwlabRuntimeLaneSpec): Record<string, un
gitUrl: spec.gitUrl,
gitReadUrl: spec.gitReadUrl,
gitWriteUrl: spec.gitWriteUrl,
gitMirror: renderGitMirror,
networkProfileId: spec.networkProfileId,
downloadProfileId: spec.downloadProfileId,
gitSshProxyHost: gitSshProxy?.host,
@@ -5225,6 +5243,7 @@ function httpProxyEndpoint(value: string): { host: string; port: number } | null
function nodeRuntimeControlPlaneFiles(spec: HwlabRuntimeLaneSpec, renderDir: string): string[] {
return [
`${renderDir}/devops-infra/git-mirror.yaml`,
`${renderDir}/${spec.runtimeRenderDir}/namespace.yaml`,
`${renderDir}/${spec.tektonDir}/rbac.yaml`,
`${renderDir}/${spec.tektonDir}/pipeline.yaml`,
@@ -5884,7 +5903,9 @@ function nodeRuntimeGitMirrorTarget(spec: HwlabRuntimeLaneSpec): NodeRuntimeGitM
serviceReadName: stringValue(gitMirror.serviceReadName, "gitMirror.serviceReadName"),
serviceWriteName: stringValue(gitMirror.serviceWriteName, "gitMirror.serviceWriteName"),
cachePvcName: stringValue(gitMirror.cachePvcName, "gitMirror.cachePvcName"),
cachePvcStorage: stringValue(gitMirror.cachePvcStorage, "gitMirror.cachePvcStorage"),
cacheHostPath: optionalStringValue(gitMirror.cacheHostPath, "gitMirror.cacheHostPath"),
servicePort: positiveIntegerValue(gitMirror.servicePort, "gitMirror.servicePort"),
secretName: stringValue(gitMirror.secretName, "gitMirror.secretName"),
syncConfigMapName: stringValue(gitMirror.syncConfigMapName, "gitMirror.syncConfigMapName"),
syncJobPrefix: stringValue(gitMirror.syncJobPrefix, "gitMirror.syncJobPrefix"),
@@ -10116,6 +10137,11 @@ function optionalStringValue(value: unknown, path: string): string | null {
return value;
}
function positiveIntegerValue(value: unknown, path: string): number {
if (!Number.isInteger(value) || value <= 0) throw new Error(`${path} must be a positive integer`);
return value;
}
function parseJsonObject(text: string): Record<string, unknown> {
const trimmed = text.trim();
if (trimmed.length === 0) return {};