fix: preserve PK01 Caddy managed blocks
This commit is contained in:
@@ -4,6 +4,7 @@ import { isAbsolute, join } from "node:path";
|
||||
import type { UniDeskConfig } from "./config";
|
||||
import { rootPath } from "./config";
|
||||
import { startJob } from "./jobs";
|
||||
import { applyPk01CaddyBlock } from "./platform-infra-public-service";
|
||||
import { runSshCommandCapture, type SshCaptureResult } from "./ssh";
|
||||
|
||||
const configFile = rootPath("config", "platform-infra", "langbot.yaml");
|
||||
@@ -477,7 +478,7 @@ async function apply(config: UniDeskConfig, options: ApplyOptions): Promise<Reco
|
||||
const confirmedYaml = renderManifest(langbot, target, secretMaterial.fingerprint);
|
||||
const result = await capture(config, target.route, ["script"], applyScript(confirmedYaml, langbot, target, secretMaterial, frpcSecret));
|
||||
const parsed = parseJsonOutput(result.stdout);
|
||||
const caddy = await applyPk01Caddy(config, target);
|
||||
const caddy = await applyPk01CaddyBlock(config, serviceName, target.publicExposure, { start: caddyManagedStart, end: caddyManagedEnd });
|
||||
return {
|
||||
ok: result.exitCode === 0 && boolField(parsed, "ok", false) && caddy.ok === true,
|
||||
action: "platform-infra-langbot-apply",
|
||||
@@ -1183,99 +1184,6 @@ PY
|
||||
`;
|
||||
}
|
||||
|
||||
async function applyPk01Caddy(config: UniDeskConfig, target: LangBotTarget): Promise<Record<string, unknown>> {
|
||||
const exposure = target.publicExposure;
|
||||
if (!exposure.enabled) return { ok: true, action: "not-enabled" };
|
||||
const block = `${caddyManagedStart}
|
||||
${exposure.dns.hostname} {
|
||||
reverse_proxy 127.0.0.1:${exposure.frpc.remotePort} {
|
||||
transport http {
|
||||
response_header_timeout ${exposure.pk01.responseHeaderTimeoutSeconds}s
|
||||
}
|
||||
}
|
||||
}
|
||||
${caddyManagedEnd}
|
||||
`;
|
||||
const blockB64 = Buffer.from(block, "utf8").toString("base64");
|
||||
const script = `
|
||||
set -u
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
block="$tmp/langbot.caddy"
|
||||
printf '%s' '${blockB64}' | base64 -d >"$block"
|
||||
sudo python3 - ${shQuote(exposure.pk01.caddyConfigPath)} "$block" ${shQuote(caddyManagedStart)} ${shQuote(caddyManagedEnd)} >"$tmp/update.out" 2>"$tmp/update.err" <<'PY'
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
config_path = pathlib.Path(sys.argv[1])
|
||||
block_path = pathlib.Path(sys.argv[2])
|
||||
start = sys.argv[3]
|
||||
end = sys.argv[4]
|
||||
text = config_path.read_text(encoding="utf-8") if config_path.exists() else ""
|
||||
block = block_path.read_text(encoding="utf-8").strip() + "\\n"
|
||||
if start in text and end in text:
|
||||
before = text.split(start, 1)[0].rstrip()
|
||||
tail = text.split(end, 1)[1].lstrip()
|
||||
next_text = before + "\\n\\n" + block + "\\n" + tail
|
||||
action = "update"
|
||||
else:
|
||||
next_text = text.rstrip() + "\\n\\n" + block
|
||||
action = "append"
|
||||
tmp = config_path.with_suffix(config_path.suffix + ".unidesk-langbot.tmp")
|
||||
tmp.write_text(next_text, encoding="utf-8")
|
||||
tmp.replace(config_path)
|
||||
print(action)
|
||||
PY
|
||||
update_rc=$?
|
||||
if [ "$update_rc" -eq 0 ]; then
|
||||
sudo caddy fmt --overwrite ${shQuote(exposure.pk01.caddyConfigPath)} >"$tmp/fmt.out" 2>"$tmp/fmt.err"
|
||||
fmt_rc=$?
|
||||
else
|
||||
: >"$tmp/fmt.out"; : >"$tmp/fmt.err"; fmt_rc=1
|
||||
fi
|
||||
if [ "$fmt_rc" -eq 0 ]; then
|
||||
sudo caddy validate --config ${shQuote(exposure.pk01.caddyConfigPath)} >"$tmp/validate.out" 2>"$tmp/validate.err"
|
||||
validate_rc=$?
|
||||
else
|
||||
: >"$tmp/validate.out"; : >"$tmp/validate.err"; validate_rc=1
|
||||
fi
|
||||
if [ "$validate_rc" -eq 0 ]; then
|
||||
sudo systemctl reload ${shQuote(exposure.pk01.caddyServiceName)} >"$tmp/reload.out" 2>"$tmp/reload.err" || sudo systemctl restart ${shQuote(exposure.pk01.caddyServiceName)} >>"$tmp/reload.out" 2>>"$tmp/reload.err"
|
||||
reload_rc=$?
|
||||
else
|
||||
: >"$tmp/reload.out"; : >"$tmp/reload.err"; reload_rc=1
|
||||
fi
|
||||
python3 - "$update_rc" "$fmt_rc" "$validate_rc" "$reload_rc" "$tmp/update.out" "$tmp/update.err" "$tmp/fmt.out" "$tmp/fmt.err" "$tmp/validate.out" "$tmp/validate.err" "$tmp/reload.out" "$tmp/reload.err" <<'PY'
|
||||
import json, sys
|
||||
rcs = [int(value) for value in sys.argv[1:5]]
|
||||
def text(path):
|
||||
try:
|
||||
return open(path, encoding="utf-8", errors="replace").read()[-3000:]
|
||||
except FileNotFoundError:
|
||||
return ""
|
||||
payload = {
|
||||
"ok": all(rc == 0 for rc in rcs),
|
||||
"hostname": "${exposure.dns.hostname}",
|
||||
"remotePort": ${exposure.frpc.remotePort},
|
||||
"caddyConfigPath": "${exposure.pk01.caddyConfigPath}",
|
||||
"service": "${exposure.pk01.caddyServiceName}",
|
||||
"managedBlock": {"start": "${caddyManagedStart}", "end": "${caddyManagedEnd}"},
|
||||
"steps": {
|
||||
"update": {"exitCode": rcs[0], "stdout": text(sys.argv[5]), "stderr": text(sys.argv[6])},
|
||||
"fmt": {"exitCode": rcs[1], "stdout": text(sys.argv[7]), "stderr": text(sys.argv[8])},
|
||||
"validate": {"exitCode": rcs[2], "stdout": text(sys.argv[9]), "stderr": text(sys.argv[10])},
|
||||
"reload": {"exitCode": rcs[3], "stdout": text(sys.argv[11]), "stderr": text(sys.argv[12])},
|
||||
},
|
||||
}
|
||||
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
||||
sys.exit(0 if payload["ok"] else 1)
|
||||
PY
|
||||
`;
|
||||
const result = await capture(config, exposure.pk01.route, ["script"], script);
|
||||
const parsed = parseJsonOutput(result.stdout);
|
||||
return parsed ?? { ok: false, capture: compactCapture(result, { full: true }) };
|
||||
}
|
||||
|
||||
function statusScript(langbot: LangBotConfig, target: LangBotTarget): string {
|
||||
return `
|
||||
set -u
|
||||
|
||||
Reference in New Issue
Block a user