From 46c316b6b1a3feb153542e87394691c2918462b1 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 17 Jun 2026 16:22:14 +0000 Subject: [PATCH] fix: fallback hwlab git mirror source sync --- scripts/src/hwlab-node.ts | 71 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/scripts/src/hwlab-node.ts b/scripts/src/hwlab-node.ts index 24d17ae1..e61a4599 100644 --- a/scripts/src/hwlab-node.ts +++ b/scripts/src/hwlab-node.ts @@ -2266,25 +2266,30 @@ function nodeRuntimeGitMirrorRun(scoped: ReturnType { + const writeUrl = nodeRuntimeGitMirrorHostWriteUrl(spec, mirror); + if (writeUrl === null) { + return { + ok: false, + mode: "host-workspace-fallback", + degradedReason: "node-runtime-git-mirror-write-service-unresolved", + next: { status: `bun scripts/cli.ts hwlab nodes git-mirror status --node ${spec.nodeId} --lane ${spec.lane}` }, + }; + } + const script = [ + "set -eu", + `repository=${shellQuote(mirror.sourceRepository)}`, + `source_branch=${shellQuote(mirror.sourceBranch)}`, + `gitops_branch=${shellQuote(mirror.gitopsBranch)}`, + `mirror_write=${shellQuote(writeUrl)}`, + "github_remote=\"ssh://git@ssh.github.com:443/${repository}.git\"", + "tmp_ns=\"refs/unidesk/git-mirror-sync/${source_branch}/$(date +%s)-$$\"", + "source_tmp=\"$tmp_ns/source\"", + "gitops_tmp=\"$tmp_ns/gitops\"", + "cleanup() { git update-ref -d \"$source_tmp\" >/dev/null 2>&1 || true; git update-ref -d \"$gitops_tmp\" >/dev/null 2>&1 || true; }", + "trap cleanup EXIT", + "export GIT_SSH_COMMAND='ssh -o HostKeyAlias=ssh.github.com -o StrictHostKeyChecking=accept-new -o ConnectTimeout=20 -o ServerAliveInterval=5 -o ServerAliveCountMax=1'", + "git fetch --no-tags \"$github_remote\" \"+refs/heads/${source_branch}:${source_tmp}\"", + "source_sha=$(git rev-parse --verify \"${source_tmp}^{commit}\")", + "git push \"$mirror_write\" \"$source_sha:refs/heads/${source_branch}\" \"$source_sha:refs/mirror-stage/heads/${source_branch}\"", + "gitops_sha=", + "if git fetch --no-tags \"$github_remote\" \"+refs/heads/${gitops_branch}:${gitops_tmp}\"; then", + " gitops_sha=$(git rev-parse --verify \"${gitops_tmp}^{commit}\")", + " git push \"$mirror_write\" \"$gitops_sha:refs/mirror-stage/heads/${gitops_branch}\"", + "fi", + "printf '{\"ok\":true,\"mode\":\"host-workspace-fallback\",\"sourceCommit\":\"%s\",\"gitopsCommit\":\"%s\",\"mirrorWrite\":\"%s\"}\\n' \"$source_sha\" \"$gitops_sha\" \"$mirror_write\"", + ].join("\n"); + const result = runTransWorkspaceStdinScript(spec.nodeId, spec.workspace, script, Math.max(60, Math.min(timeoutSeconds, 300))); + return { + ok: isCommandSuccess(result), + mode: "host-workspace-fallback", + reason: "k3s git-mirror sync job could not reach GitHub SSH; fallback updates the node-local mirror from the target workspace through ssh.github.com:443", + mirrorWrite: writeUrl, + result: compactRuntimeCommand(result), + degradedReason: isCommandSuccess(result) ? undefined : "node-runtime-git-mirror-host-fallback-failed", + valuesPrinted: false, + }; +} + +function nodeRuntimeGitMirrorHostWriteUrl(spec: HwlabRuntimeLaneSpec, mirror: NodeRuntimeGitMirrorTargetSpec): string | null { + const result = runNodeK3sArgs(spec, ["kubectl", "-n", mirror.namespace, "get", "service", mirror.serviceWriteName, "-o", "jsonpath={.spec.clusterIP}{\":\"}{.spec.ports[0].port}"], 60); + const value = result.stdout.trim(); + if (result.exitCode !== 0 || value.length === 0 || value.startsWith(":")) return null; + return `http://${value}/${mirror.sourceRepository}.git`; +} + function nodeRuntimeEnsureGitMirrorSourceCurrent(scoped: ReturnType, sourceCommit: string, pipelineRun: string): Record { const full = nodeScopedFullOutput(scoped); const before = nodeRuntimeGitMirrorStatus({ ...scoped, action: "status", dryRun: true, confirm: false }); @@ -2435,6 +2497,7 @@ function compactNodeRuntimeGitMirrorRun(result: Record): Record mutation: result.mutation === true, jobName: result.jobName ?? null, partialSuccess: result.partialSuccess ?? null, + fallback: result.fallback ?? null, degradedReason: result.degradedReason ?? null, statusSummary: Object.keys(status).length > 0 ? compactNodeRuntimeGitMirrorStatus(status) : null, next: result.next ?? null,