From 01c39627457d234da25e256afb44fe004d070800 Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Fri, 26 Jun 2026 02:09:02 +0800 Subject: [PATCH] fix: report sentinel caddy apply without node (#922) Co-authored-by: Codex --- scripts/src/hwlab-node-web-sentinel-cicd.ts | 33 ++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/scripts/src/hwlab-node-web-sentinel-cicd.ts b/scripts/src/hwlab-node-web-sentinel-cicd.ts index fe26b6f1..7e07e4d8 100644 --- a/scripts/src/hwlab-node-web-sentinel-cicd.ts +++ b/scripts/src/hwlab-node-web-sentinel-cicd.ts @@ -1757,10 +1757,30 @@ function applySentinelCaddyBlock(state: SentinelCicdState, timeoutSeconds: numbe "grep -Fq \"# BEGIN $marker\" \"$config_path\" 2>/dev/null && after_present=yes", "active=$(systemctl is-active \"$service\" 2>/dev/null || true)", "err=$(cat /tmp/web-probe-sentinel-caddy-python.err /tmp/web-probe-sentinel-caddy-validate.err /tmp/web-probe-sentinel-caddy-install.err /tmp/web-probe-sentinel-caddy-reload.err 2>/dev/null | tr '\\n' ';' | cut -c1-1000 || true)", - "node - \"$python_rc\" \"$validate_rc\" \"$reload_rc\" \"$after_present\" \"$active\" \"$hostname\" \"$config_path\" \"$err\" <<'NODE'", - "const [pythonRc, validateRc, reloadRc, afterPresent, active, hostname, configPath, errorPreview] = process.argv.slice(2);", - "console.log(JSON.stringify({ok:Number(pythonRc)===0&&Number(validateRc)===0&&Number(reloadRc)===0&&afterPresent==='yes',hostname,configPath,pythonExitCode:Number(pythonRc),validateExitCode:Number(validateRc),reloadExitCode:reloadRc===''?null:Number(reloadRc),afterBlockPresent:afterPresent==='yes',active,errorPreview,valuesRedacted:true}));", - "NODE", + "python3 - \"$python_rc\" \"$validate_rc\" \"$reload_rc\" \"$after_present\" \"$active\" \"$hostname\" \"$config_path\" \"$err\" <<'PY'", + "import json, sys", + "python_rc, validate_rc, reload_rc, after_present, active, hostname, config_path, error_preview = sys.argv[1:9]", + "def num(value):", + " if value == '':", + " return None", + " try:", + " return int(value)", + " except ValueError:", + " return None", + "payload = {", + " 'ok': num(python_rc) == 0 and num(validate_rc) == 0 and num(reload_rc) == 0 and after_present == 'yes',", + " 'hostname': hostname,", + " 'configPath': config_path,", + " 'pythonExitCode': num(python_rc),", + " 'validateExitCode': num(validate_rc),", + " 'reloadExitCode': num(reload_rc),", + " 'afterBlockPresent': after_present == 'yes',", + " 'active': active,", + " 'errorPreview': error_preview,", + " 'valuesRedacted': True,", + "}", + "print(json.dumps(payload, ensure_ascii=False))", + "PY", ].join("\n"); const result = runCommand(["trans", stringAt(state.publicExposure, "caddy.route"), "sh", "--", script], repoRoot, { timeoutMs: Math.min(timeoutSeconds, 60) * 1000 }); const parsed = parseJsonObject(result.stdout); @@ -2215,6 +2235,7 @@ function renderControlPlaneResult(result: Record): string { const publish = record(result.publish); const flush = record(result.flush); const publicExposureApply = record(result.publicExposureApply); + const publicExposureCaddy = record(publicExposureApply.caddy); const argoApply = record(result.argoApply); const blocker = record(result.blocker); const targetValidation = record(result.targetValidation); @@ -2250,6 +2271,10 @@ function renderControlPlaneResult(result: Record): string { "", Object.keys(publicExposureApply).length === 0 ? "PUBLIC_EXPOSURE_APPLY\n-" : table(["OK", "SECRET", "CADDY", "HOST"], [[publicExposureApply.ok, record(publicExposureApply.secret).ok, record(publicExposureApply.caddy).ok, publicExposureApply.hostname]]), "", + Object.keys(publicExposureCaddy).length === 0 || publicExposureCaddy.ok === true + ? "CADDY_APPLY_DETAIL\n-" + : table(["PY", "VALIDATE", "RELOAD", "BLOCK", "ACTIVE", "ERROR", "STDOUT", "STDERR"], [[publicExposureCaddy.pythonExitCode, publicExposureCaddy.validateExitCode, publicExposureCaddy.reloadExitCode, publicExposureCaddy.afterBlockPresent, publicExposureCaddy.active, short(publicExposureCaddy.errorPreview), short(record(publicExposureCaddy.result).stdoutPreview), short(record(publicExposureCaddy.result).stderrPreview)]]), + "", Object.keys(argoApply).length === 0 ? "ARGO_APPLY\n-" : table(["OK", "EXIT", "PREVIEW"], [[argoApply.ok, record(argoApply.result).exitCode, record(argoApply.result).stdoutPreview]]), "", warnings.length === 0 ? "WARNINGS\n-" : ["WARNINGS", ...warnings.map((item) => `- ${text(item)}`)].join("\n"),