Merge pull request #842 from pikasTech/fix/web-probe-direct-mode-warning-20260624

fix: 修复 web-probe direct proxy 与 trigger 超时 warning
This commit is contained in:
Lyon
2026-06-25 00:47:35 +08:00
committed by GitHub
+42 -6
View File
@@ -304,6 +304,7 @@ const CODE_AGENT_PROVIDER_SOURCE_NAMESPACE = "hwlab-v02";
const CODE_AGENT_PROVIDER_SOURCE_SECRET = "hwlab-v02-code-agent-provider";
const HWLAB_CI_NAMESPACE = "hwlab-ci";
const NODE_RUNTIME_CICD_WAIT_WARNING_SECONDS = 120;
const NODE_RUNTIME_TRIGGER_SEVERE_WARNING_MS = NODE_RUNTIME_CICD_WAIT_WARNING_SECONDS * 1000;
export async function runHwlabNodeCommand(_config: Config, args: string[]): Promise<Record<string, unknown> | RenderedCliResult> {
if (args.length === 0) return hwlabNodeHelp();
@@ -2785,6 +2786,8 @@ function nodeRuntimeTriggerCurrentOutput(scoped: ReturnType<typeof parseNodeScop
function nodeRuntimeTriggerCurrent(scoped: ReturnType<typeof parseNodeScopedDelegatedOptions>): Record<string, unknown> {
const spec = scoped.spec;
const pipelineWaitSeconds = nodeRuntimeCicdWaitSeconds(scoped);
const triggerStartedAt = Date.now();
const triggerElapsedMs = () => Date.now() - triggerStartedAt;
printNodeRuntimeTriggerProgress(spec, { stage: "source-head", status: "started" });
const head = resolveNodeRuntimeLaneHead(spec);
const sourceCommit = head.sourceCommit;
@@ -2838,6 +2841,9 @@ function nodeRuntimeTriggerCurrent(scoped: ReturnType<typeof parseNodeScopedDele
: null;
const pipelinePending = pipelineWait.status === "pending";
const ok = pipelineWait.ok === true && (postFlush === null || postFlush.ok === true);
const elapsedMs = triggerElapsedMs();
const triggerWarning = pipelinePending ? null : nodeRuntimeTriggerElapsedWarning(spec, pipelineRun, elapsedMs);
if (triggerWarning !== null) printNodeRuntimeTriggerProgress(spec, { stage: "trigger-current", status: "warning", ...triggerWarning });
return {
ok,
command: `hwlab nodes control-plane trigger-current --node ${scoped.node} --lane ${scoped.lane}`,
@@ -2845,7 +2851,8 @@ function nodeRuntimeTriggerCurrent(scoped: ReturnType<typeof parseNodeScopedDele
lane: scoped.lane,
mode: "confirmed-trigger",
completion: pipelinePending ? "pending" : ok ? "completed" : "failed",
warning: pipelinePending ? pipelineWait.warning ?? nodeRuntimeCicdWaitWarning(spec, pipelineRun, pipelineWait) : undefined,
warning: pipelinePending ? pipelineWait.warning ?? nodeRuntimeCicdWaitWarning(spec, pipelineRun, pipelineWait) : triggerWarning ?? undefined,
triggerElapsedMs: elapsedMs,
sourceCommit,
pipelineRun,
before,
@@ -2935,6 +2942,9 @@ function nodeRuntimeTriggerCurrent(scoped: ReturnType<typeof parseNodeScopedDele
const postFlushOk = postFlush === null || postFlush.ok === true;
const pipelinePending = pipelineWait !== null && pipelineWait.status === "pending";
const ok = createOk && (pipelineReady || pipelinePending) && postFlushOk;
const elapsedMs = triggerElapsedMs();
const triggerWarning = pipelinePending ? null : nodeRuntimeTriggerElapsedWarning(spec, pipelineRun, elapsedMs);
if (triggerWarning !== null) printNodeRuntimeTriggerProgress(spec, { stage: "trigger-current", status: "warning", ...triggerWarning });
return {
ok,
command: `hwlab nodes control-plane trigger-current --node ${scoped.node} --lane ${scoped.lane}`,
@@ -2942,7 +2952,8 @@ function nodeRuntimeTriggerCurrent(scoped: ReturnType<typeof parseNodeScopedDele
lane: scoped.lane,
mode: "confirmed-trigger",
completion: pipelinePending ? "pending" : ok ? "completed" : "failed",
warning: pipelinePending ? pipelineWait?.warning ?? nodeRuntimeCicdWaitWarning(spec, pipelineRun, pipelineWait) : undefined,
warning: pipelinePending ? pipelineWait?.warning ?? nodeRuntimeCicdWaitWarning(spec, pipelineRun, pipelineWait) : triggerWarning ?? undefined,
triggerElapsedMs: elapsedMs,
mutation: createOk,
sourceCommit,
pipelineRun,
@@ -2985,6 +2996,18 @@ function nodeRuntimeCicdWaitWarning(spec: HwlabRuntimeLaneSpec, pipelineRun: str
};
}
function nodeRuntimeTriggerElapsedWarning(spec: HwlabRuntimeLaneSpec, pipelineRun: string, elapsedMs: number): Record<string, unknown> | null {
if (elapsedMs < NODE_RUNTIME_TRIGGER_SEVERE_WARNING_MS) return null;
return {
code: "node-runtime-trigger-over-120s",
message: `trigger-current total elapsed time exceeded ${NODE_RUNTIME_CICD_WAIT_WARNING_SECONDS}s; this is a severe timeout even if the PipelineRun eventually succeeded and requires follow-up investigation of slow control-plane, Tekton and git-mirror stages.`,
thresholdMs: NODE_RUNTIME_TRIGGER_SEVERE_WARNING_MS,
elapsedMs,
inspectEnvReuse: `bun scripts/cli.ts hwlab nodes control-plane status --node ${spec.nodeId} --lane ${spec.lane} --pipeline-run ${pipelineRun} --full`,
inspectGitMirror: `bun scripts/cli.ts hwlab nodes git-mirror status --node ${spec.nodeId} --lane ${spec.lane}`,
};
}
function withNodeRuntimeTriggerRendered(result: Record<string, unknown>, scoped: ReturnType<typeof parseNodeScopedDelegatedOptions>): RenderedCliResult {
const pipelineWait = record(result.pipelineWait);
const pipelineRunRecord = record(pipelineWait.pipelineRun ?? result.after ?? result.before);
@@ -3013,6 +3036,7 @@ function withNodeRuntimeTriggerRendered(result: Record<string, unknown>, scoped:
["create", create.exitCode === 0 || result.mutation === true ? "ok" : create.exitCode === undefined ? "-" : "failed", result.createObservedAfterTimeout === true ? "observed-after-timeout" : `exit=${webObserveText(create.exitCode)}`],
["pipeline-wait", webObserveText(pipelineWait.status), `pipeline=${webObserveText(pipelineStatus)} polls=${webObserveText(pipelineWait.polls)} elapsed=${formatElapsedMs(pipelineWait.elapsedMs)}`],
["post-flush", postFlush.ok === true ? "ok" : postFlush.ok === false ? "failed" : "-", webObserveText(postFlush.mode ?? postFlush.degradedReason)],
["total", result.triggerElapsedMs === undefined ? "-" : "elapsed", formatElapsedMs(result.triggerElapsedMs)],
],
),
"",
@@ -3052,7 +3076,7 @@ function withNodeRuntimeTriggerRendered(result: Record<string, unknown>, scoped:
"",
"Disclosure:",
" default view is a bounded CICD summary; use --full or --raw for the complete JSON payload.",
` default wait is ${NODE_RUNTIME_CICD_WAIT_WARNING_SECONDS}s; if exceeded, inspect env-reuse and git-mirror before rerun.`,
` ${NODE_RUNTIME_CICD_WAIT_WARNING_SECONDS}s is the severe timeout warning threshold for both PipelineRun wait and total trigger elapsed time.`,
].join("\n");
return { ...result, renderedText, contentType: "text/plain" };
}
@@ -7793,7 +7817,19 @@ interface NodeWebProbeHostProxyEnv {
readonly summary: Record<string, unknown>;
}
function nodeWebProbeHostProxyEnv(spec: HwlabRuntimeLaneSpec): NodeWebProbeHostProxyEnv {
function nodeWebProbeHostProxyEnv(spec: HwlabRuntimeLaneSpec, browserProxyMode: WebProbeBrowserProxyMode = "auto"): NodeWebProbeHostProxyEnv {
if (browserProxyMode === "direct") {
return {
envAssignments: [],
summary: {
source: "option",
mode: "direct",
networkProfileId: spec.networkProfileId,
proxy: { enabled: false },
valuesPrinted: false,
},
};
}
const proxy = spec.networkProfile.proxy;
const serviceCache = new Map<string, string>();
const http = resolveNodeWebProbeHostProxyUrl(spec, proxy.http, serviceCache);
@@ -7930,7 +7966,7 @@ function runNodeWebProbeObserveStart(
const stateDir = options.stateDir ?? defaultStateDir;
const runnerB64 = Buffer.from(nodeWebObserveRunnerSource(), "utf8").toString("base64");
const runnerB64Body = runnerB64.match(/.{1,76}/gu)?.join("\n") ?? runnerB64;
const webProbeProxy = nodeWebProbeHostProxyEnv(spec);
const webProbeProxy = nodeWebProbeHostProxyEnv(spec, options.browserProxyMode);
const alertThresholds = nodeWebProbeAlertThresholds(spec);
const runnerEnvAssignments = [
...webProbeProxy.envAssignments,
@@ -10702,7 +10738,7 @@ function runNodeWebProbeScript(
material: BootstrapAdminPasswordMaterial,
credential: Record<string, unknown>,
): Record<string, unknown> {
const webProbeProxy = nodeWebProbeHostProxyEnv(spec);
const webProbeProxy = nodeWebProbeHostProxyEnv(spec, options.browserProxyMode);
const script = nodeWebProbeScriptRemoteShell(options, secretSpec, material.password ?? "", webProbeProxy);
const result = runTransWorkspaceStdinScript(options.node, spec.workspace, script, options.commandTimeoutSeconds);
const commandTimedOut = result.timedOut || result.exitCode === 124;