fix: require explicit trans shell operations

This commit is contained in:
Codex
2026-06-15 04:01:04 +00:00
parent b2c2819fe2
commit b8fb3c41a8
18 changed files with 241 additions and 273 deletions
+26 -26
View File
@@ -972,11 +972,11 @@ function shortSha(sha: string): string {
}
function precheckWorkspace(): CommandJsonResult {
return cliJson(["ssh", `${G14_PROVIDER}:${G14_WORKSPACE}`, "script", "--", "pwd; git fetch origin G14 --prune; git status --short --branch; git remote -v | sed -n '1,4p'"], 120_000);
return cliJson(["ssh", `${G14_PROVIDER}:${G14_WORKSPACE}`, "sh", "--", "pwd; git fetch origin G14 --prune; git status --short --branch; git remote -v | sed -n '1,4p'"], 120_000);
}
function g14HostScript(script: string, timeoutMs = 120_000): CommandJsonResult {
return cliJson(["ssh", G14_PROVIDER, "script", "--", script], timeoutMs);
return cliJson(["ssh", G14_PROVIDER, "sh", "--", script], timeoutMs);
}
function g14K3s(args: string[], timeoutMs = 60_000): CommandJsonResult {
@@ -984,7 +984,7 @@ function g14K3s(args: string[], timeoutMs = 60_000): CommandJsonResult {
}
function g14K3sInlineScriptWithInput(script: string, input: string, timeoutMs = 60_000): CommandJsonResult {
return commandJsonWithInput(["bun", "scripts/cli.ts", "ssh", `${G14_PROVIDER}:k3s`, "script", "--", script], input, timeoutMs);
return commandJsonWithInput(["bun", "scripts/cli.ts", "ssh", `${G14_PROVIDER}:k3s`, "sh", "--", script], input, timeoutMs);
}
function remoteAsyncStatusDir(label: string): string {
@@ -1119,7 +1119,7 @@ function parseRemoteAsyncPayload(result: CommandJsonResult): Record<string, unkn
function runG14K3sRemoteAsync(spec: RemoteAsyncCommandSpec): CommandJsonResult {
const startedAtMs = Date.now();
const start = g14K3s(["script", "--", remoteAsyncStartScript(spec)], 55_000);
const start = g14K3s(["sh", "--", remoteAsyncStartScript(spec)], 55_000);
const startPayload = parseRemoteAsyncPayload(start);
if (!isCommandSuccess(start) || startPayload.ok !== true) return start;
const deadlineMs = startedAtMs + Math.max(1, spec.timeoutSeconds) * 1000;
@@ -1129,7 +1129,7 @@ function runG14K3sRemoteAsync(spec: RemoteAsyncCommandSpec): CommandJsonResult {
attempts += 1;
const wait = runCommand(["sleep", attempts <= 1 ? "1" : "2"], repoRoot, { timeoutMs: 3_000 });
if (wait.exitCode !== 0 && wait.timedOut) break;
const status = g14K3s(["script", "--", remoteAsyncStatusScript(spec.label, spec.token)], 55_000);
const status = g14K3s(["sh", "--", remoteAsyncStatusScript(spec.label, spec.token)], 55_000);
lastStatus = status;
const payload = parseRemoteAsyncPayload(status);
const state = typeof payload.state === "string" ? payload.state : null;
@@ -1156,7 +1156,7 @@ function runG14K3sRemoteAsync(spec: RemoteAsyncCommandSpec): CommandJsonResult {
};
}
}
const killed = g14K3s(["script", "--", remoteAsyncKillScript(spec.label, spec.token)], 55_000);
const killed = g14K3s(["sh", "--", remoteAsyncKillScript(spec.label, spec.token)], 55_000);
const payload = parseRemoteAsyncPayload(killed);
return {
ok: false,
@@ -1358,7 +1358,7 @@ function getV02TriggerSnapshot(): V02TriggerSnapshot {
"printf 'message\\t%s\\n' \"$(printf '%s\\n' \"$status_text\" | sed -n '3p')\"",
"printf 'pipelineRunStderr\\t%s\\n' \"$(one_line < \"$tmp_dir/pipelinerun.err\")\"",
].join("\n");
const result = g14K3s(["script", "--", script], 180_000);
const result = g14K3s(["sh", "--", script], 180_000);
return parseV02TriggerSnapshot(result, Date.now());
}
@@ -1629,7 +1629,7 @@ function v02ControlPlaneStatusBundle(target: V02ControlPlaneStatusTarget = {}):
`section gitMirrorCache kubectl exec -n ${shellQuote(GIT_MIRROR_NAMESPACE)} deploy/git-mirror-http -- sh -lc ${shellQuote(gitMirrorCacheProbeScript())}`,
`section webAssets sh -c ${shellQuote(v02WebAssetsProbeScript())}`,
].join("\n");
return g14K3s(["script", "--", script], 60_000);
return g14K3s(["sh", "--", script], 60_000);
}
function v02SourceHeadsProbeScript(): string {
@@ -2373,7 +2373,7 @@ export function v02CloseoutVerdict(status: Record<string, unknown>): Record<stri
exitCode: sourceHeadsTarget.ancestorExitCode ?? null,
command: sourceCommit === null
? null
: `trans G14:/root/hwlab-v02 script -- 'git fetch origin v0.2 && git merge-base --is-ancestor ${sourceCommit} origin/v0.2'`,
: `trans G14:/root/hwlab-v02 sh -- 'git fetch origin v0.2 && git merge-base --is-ancestor ${sourceCommit} origin/v0.2'`,
};
const recommendedNext = v02CloseoutRecommendedNext({
closeable,
@@ -3052,7 +3052,7 @@ function runControlPlaneReleasedPvCleanup(options: G14ControlPlaneOptions): Reco
deletion,
followUp: {
diskPressure: "trans G14:k3s kubectl get node ubuntu-rog-zephyrus-g14-ga401iv-ga401iv -o jsonpath='{range .status.conditions[*]}{.type}{\"=\"}{.status}{\" \"}{.reason}{\"\\n\"}{end}'",
storage: "trans G14 script -- 'df -h /; sudo du -xh -d 1 /var/lib/rancher/k3s/storage 2>/dev/null | sort -h | tail -20'",
storage: "trans G14 sh -- 'df -h /; sudo du -xh -d 1 /var/lib/rancher/k3s/storage 2>/dev/null | sort -h | tail -20'",
},
};
}
@@ -3342,7 +3342,7 @@ function applyRuntimeLaneControlPlaneFiles(spec: HwlabRuntimeLaneSpec, renderDir
? ["set -eu", shellCommand.replace(/^exec /, ""), ...cleanupCommands].join("\n")
: shellCommand;
const visibleCommand = cleanupCommands.length > 0
? ["bun", "scripts/cli.ts", "ssh", `${G14_PROVIDER}:k3s`, "script", "--", script]
? ["bun", "scripts/cli.ts", "ssh", `${G14_PROVIDER}:k3s`, "sh", "--", script]
: command;
return runG14K3sRemoteAsync({
script,
@@ -3642,7 +3642,7 @@ function createRuntimeLanePipelineRun(spec: HwlabRuntimeLaneSpec, sourceCommit:
"fi",
`kubectl get pipelinerun -n ${shellQuote(CI_NAMESPACE)} ${shellQuote(pipelineRun)} -o jsonpath='{.metadata.name}{\"\\n\"}{.metadata.labels.hwlab\\.pikastech\\.local/source-commit}{\"\\n\"}{.status.conditions[0].status}{\"\\n\"}{.status.conditions[0].reason}{\"\\n\"}'`,
].join("\n");
return g14K3s(["script", "--", script], timeoutSeconds * 1000);
return g14K3s(["sh", "--", script], timeoutSeconds * 1000);
}
function createV02PipelineRun(sourceCommit: string, timeoutSeconds: number): CommandJsonResult {
@@ -3927,7 +3927,7 @@ function runtimeLaneControlPlaneStatusBundle(spec: HwlabRuntimeLaneSpec, target:
shellQuote(pipelineRunRowsJsonPath()),
].join(" "),
].join("\n");
return g14K3s(["script", "--", script], 120_000);
return g14K3s(["sh", "--", script], 120_000);
}
function runtimeLanePublicProbeScript(spec: HwlabRuntimeLaneSpec): string {
@@ -4174,7 +4174,7 @@ function runtimeLaneArgoRefreshScript(spec: HwlabRuntimeLaneSpec, dryRun: boolea
}
function refreshRuntimeLaneArgoApplication(spec: HwlabRuntimeLaneSpec, options: G14ControlPlaneOptions): Record<string, unknown> {
const result = g14K3s(["script", "--", runtimeLaneArgoRefreshScript(spec, options.dryRun)], options.timeoutSeconds * 1000);
const result = g14K3s(["sh", "--", runtimeLaneArgoRefreshScript(spec, options.dryRun)], options.timeoutSeconds * 1000);
const fields = keyValueLinesFromText(statusText(result));
const ok = isCommandSuccess(result);
return {
@@ -5315,7 +5315,7 @@ function runG14Secret(options: G14SecretOptions): Record<string, unknown> {
: null;
const result = options.preset === "master-server-admin-api-key"
? g14K3sInlineScriptWithInput(script, localAdminApiKey?.key ?? "", options.timeoutSeconds * 1000 + 2000)
: g14K3s(["script", "--", script], options.timeoutSeconds * 1000);
: g14K3s(["sh", "--", script], options.timeoutSeconds * 1000);
const status = v02SecretStatusFromText(statusText(result), isCommandSuccess(result), result.exitCode, result.stderr);
const dryRunOk = options.action === "ensure" && options.dryRun && isCommandSuccess(result);
const deleteDryRunOk = options.action === "delete" && options.dryRun && isCommandSuccess(result);
@@ -5482,7 +5482,7 @@ function legacyG14RetirementStatusScript(): string {
}
function legacyG14RetirementStatus(): Record<string, unknown> {
const result = g14K3s(["script", "--", legacyG14RetirementStatusScript()], 60_000);
const result = g14K3s(["sh", "--", legacyG14RetirementStatusScript()], 60_000);
const sections = parseShellSections(statusText(result));
const legacyApplications = parseSectionJsonArray(sections.legacyApplications).map(applicationSummary);
const legacyNamespaces = parseSectionJsonArray(sections.legacyNamespaces).map(namespaceSummary);
@@ -5628,7 +5628,7 @@ function runLegacyG14Retirement(options: G14LegacyRetirementOptions): Record<str
const markerBeforeDelete = writeLegacyG14RetirementMarker("retiring", options.reason, { command: "hwlab g14 retirement execute --confirm" });
const localJobs = cancelLegacyG14MonitorJobs(false);
const deleteResult = g14K3s(["script", "--", legacyG14RetirementDeleteScript()], Math.max(60_000, options.timeoutSeconds * 1000));
const deleteResult = g14K3s(["sh", "--", legacyG14RetirementDeleteScript()], Math.max(60_000, options.timeoutSeconds * 1000));
const deleteSections = parseShellSections(statusText(deleteResult));
const afterDelete = legacyG14RetirementStatus();
const wait = options.wait ? waitForLegacyG14Retirement(options.timeoutSeconds) : null;
@@ -6387,7 +6387,7 @@ function runGitMirrorStatus(lane: HwlabRuntimeLane = "v02"): Record<string, unkn
shellQuote(gitMirrorCacheProbeScript()),
].join(" "),
].join("\n");
const bundle = g14K3s(["script", "--", script], 60_000);
const bundle = g14K3s(["sh", "--", script], 60_000);
const sections = parseShellSections(statusText(bundle));
const resources = sections.resources;
const legacyCronJob = sections.legacyCronJob;
@@ -6518,7 +6518,7 @@ function runGitMirrorSync(options: G14GitMirrorOptions): Record<string, unknown>
`kubectl exec -n ${shellQuote(GIT_MIRROR_NAMESPACE)} deploy/git-mirror-http -- sh -lc ${shellQuote(`cat /cache/HWLAB.last-sync.json 2>/dev/null || true; printf "\\n"; git --git-dir=/cache/pikasTech/HWLAB.git rev-parse refs/heads/${spec.sourceBranch} refs/mirror-stage/heads/${spec.sourceBranch} refs/heads/${spec.gitopsBranch} refs/mirror-stage/heads/${spec.gitopsBranch} 2>/dev/null || true`)}`,
].join("\n"),
].join("\n");
const result = g14K3s(["script", "--", script], options.timeoutSeconds * 1000 + 30_000);
const result = g14K3s(["sh", "--", script], options.timeoutSeconds * 1000 + 30_000);
const syncCommand = spec.lane === "v02"
? "bun scripts/cli.ts hwlab g14 git-mirror sync --lane v02 --confirm"
: `bun scripts/cli.ts hwlab nodes git-mirror sync --node ${spec.nodeId} --lane ${spec.lane} --confirm`;
@@ -6574,7 +6574,7 @@ function runGitMirrorFlush(options: G14GitMirrorOptions): Record<string, unknown
`kubectl exec -n ${shellQuote(GIT_MIRROR_NAMESPACE)} deploy/git-mirror-http -- sh -lc ${shellQuote(`cat /cache/HWLAB.last-flush.json 2>/dev/null || true; printf "\\n"; git --git-dir=/cache/pikasTech/HWLAB.git rev-parse refs/heads/${options.lane === "v02" ? "v0.2-gitops" : hwlabRuntimeLaneSpec(options.lane).gitopsBranch} refs/mirror-stage/heads/${options.lane === "v02" ? "v0.2-gitops" : hwlabRuntimeLaneSpec(options.lane).gitopsBranch} 2>/dev/null || true`)}`,
].join("\n"),
].join("\n");
const result = g14K3s(["script", "--", script], options.timeoutSeconds * 1000 + 30_000);
const result = g14K3s(["sh", "--", script], options.timeoutSeconds * 1000 + 30_000);
return {
ok: isCommandSuccess(result),
command: "hwlab g14 git-mirror flush",
@@ -7367,7 +7367,7 @@ function g14ObservabilityStatus(): Record<string, unknown> {
`section workloadMonitors kubectl get servicemonitor,prometheusrule -n ${shellQuote(V02_RUNTIME_NAMESPACE)} -l hwlab.pikastech.local/monitoring=enabled -o json`,
`section query kubectl get --raw ${shellQuote(queryPath)}`,
].join("\n");
const bundle = g14K3s(["script", "--", script], 120_000);
const bundle = g14K3s(["sh", "--", script], 120_000);
const sections = parseShellSections(statusText(bundle));
const namespace = parseSectionJson(sections.namespace);
const discoveryNamespace = parseSectionJson(sections.discoveryNamespace);
@@ -7538,7 +7538,7 @@ function runG14ObservabilityApply(options: G14ObservabilityOptions): Record<stri
const manifest = g14PrometheusManifest();
const manifestB64 = Buffer.from(JSON.stringify(manifest), "utf8").toString("base64");
const script = g14ObservabilityApplyScript(options, manifestB64);
const result = g14K3s(["script", "--", script], options.timeoutSeconds * 1000 + 90_000);
const result = g14K3s(["sh", "--", script], options.timeoutSeconds * 1000 + 90_000);
const ok = isCommandSuccess(result);
return {
ok,
@@ -7629,7 +7629,7 @@ function runG14ObservabilityTargets(options: G14ObservabilityOptions): Record<st
`section podResourceMetrics kubectl get --raw ${shellQuote(`/apis/metrics.k8s.io/v1beta1/namespaces/${V02_RUNTIME_NAMESPACE}/pods`)}`,
...queryCommands,
].join("\n");
const bundle = g14K3s(["script", "--", script], options.timeoutSeconds * 1000);
const bundle = g14K3s(["sh", "--", script], options.timeoutSeconds * 1000);
const sections = parseShellSections(statusText(bundle));
const pods = k8sItems(parseSectionJson(sections.pods));
const monitors = k8sItems(parseSectionJson(sections.monitors));
@@ -7730,7 +7730,7 @@ function runG14ObservabilityBoundary(options: G14ObservabilityOptions): Record<s
`section workloadMonitoring kubectl get servicemonitor,podmonitor,prometheusrule,prometheus,alertmanager -n ${shellQuote(V02_RUNTIME_NAMESPACE)} -o json`,
`section infraControlPlane kubectl get prometheus,alertmanager -n ${shellQuote(G14_OBSERVABILITY_NAMESPACE)} -o json`,
].join("\n");
const bundle = g14K3s(["script", "--", script], options.timeoutSeconds * 1000);
const bundle = g14K3s(["sh", "--", script], options.timeoutSeconds * 1000);
const sections = parseShellSections(statusText(bundle));
const workloadItems = k8sItems(parseSectionJson(sections.workloadMonitoring));
const infraItems = k8sItems(parseSectionJson(sections.infraControlPlane));
@@ -7969,7 +7969,7 @@ function startGitMirrorJob(options: G14GitMirrorOptions): Record<string, unknown
}
function g14HostScript(script: string, timeoutMs = 120_000): CommandJsonResult {
return cliJson(["ssh", G14_PROVIDER, "script", "--", script], timeoutMs);
return cliJson(["ssh", G14_PROVIDER, "sh", "--", script], timeoutMs);
}
function g14CiToolsImage(tag: string): string {
@@ -8223,7 +8223,7 @@ function mergePullRequest(number: number, dryRun: boolean): CommandJsonResult {
}
function getG14Head(): string | null {
const result = cliJson(["ssh", `${G14_PROVIDER}:${G14_WORKSPACE}`, "script", "--", "git fetch origin G14 --prune >/dev/null 2>&1; git rev-parse origin/G14"], 120_000);
const result = cliJson(["ssh", `${G14_PROVIDER}:${G14_WORKSPACE}`, "sh", "--", "git fetch origin G14 --prune >/dev/null 2>&1; git rev-parse origin/G14"], 120_000);
if (!isCommandSuccess(result)) return null;
const output = String(nested(result.parsed, ["data", "stdout"]) ?? result.stdout).trim();
const match = /[0-9a-f]{40}/iu.exec(output);