fix: preserve PK01 Caddy managed blocks

This commit is contained in:
Codex
2026-06-13 14:04:10 +00:00
parent 5574150c64
commit 153ffb4c47
6 changed files with 467 additions and 301 deletions
+10 -61
View File
@@ -5,6 +5,7 @@ import { join } from "node:path";
import type { UniDeskConfig } from "./config";
import { rootPath } from "./config";
import type { RenderedCliResult } from "./output";
import { applyLocalCaddyManagedSite } from "./pk01-caddy";
import {
codexPoolSentinelSummary,
codexPoolSentinelRuntimeImage,
@@ -2872,55 +2873,21 @@ async function applyMasterCaddySite(pool: CodexPoolConfig): Promise<Record<strin
if (!caddy.enabled) return { ok: true, action: "disabled-by-yaml", valuesPrinted: false };
const path = caddy.configPath;
if (!existsSync(path)) return { ok: false, error: "master-caddy-config-missing", path, valuesPrinted: false };
const before = readFileSync(path, "utf8");
const desiredBlock = renderCaddySiteBlock(caddy.domain, caddy.upstreamBaseUrl, caddy.responseHeaderTimeoutSeconds, caddy.edgeRetry);
const existing = caddySiteBlock(before, caddy.domain);
const alreadyConfigured = existing === desiredBlock;
let backupPath: string | null = null;
let action = "kept-existing";
if (!alreadyConfigured) {
const stamp = new Date().toISOString().replace(/[-:]/gu, "").replace(/\..*$/u, "Z");
backupPath = `${path}.bak-sub2api-https-${stamp}`;
copyFileSync(path, backupPath);
const next = existing === null
? `${before.replace(/\s*$/u, "")}\n\n${desiredBlock}\n`
: before.replace(existing, desiredBlock);
writeFileSync(path, next, "utf8");
chmodSync(path, statSync(backupPath).mode & 0o777);
action = existing === null ? "added-site" : "updated-site";
}
const validate = Bun.spawnSync(["caddy", "validate", "--config", path, "--adapter", "caddyfile"]);
let reload: ReturnType<typeof Bun.spawnSync> | null = null;
if (validate.exitCode === 0 && !alreadyConfigured) {
reload = Bun.spawnSync(["systemctl", "reload", caddy.serviceName]);
}
const active = Bun.spawnSync(["systemctl", "is-active", caddy.serviceName]);
const ok = validate.exitCode === 0 && (reload === null || reload.exitCode === 0) && active.exitCode === 0 && String(active.stdout).trim() === "active";
const applied = applyLocalCaddyManagedSite({
serviceId: "sub2api-codex-pool",
markerName: "sub2api-codex-pool",
configPath: path,
serviceName: caddy.serviceName,
siteBlock: desiredBlock,
legacySiteDomain: caddy.domain,
});
return {
ok,
action,
path,
backupPath,
...applied,
domain: caddy.domain,
upstreamBaseUrl: caddy.upstreamBaseUrl,
serviceName: caddy.serviceName,
responseHeaderTimeoutSeconds: caddy.responseHeaderTimeoutSeconds,
edgeRetry: caddy.edgeRetry,
validate: {
exitCode: validate.exitCode,
stdoutTail: Buffer.from(validate.stdout).toString("utf8").slice(-1000),
stderrTail: Buffer.from(validate.stderr).toString("utf8").slice(-2000),
},
reload: reload === null ? null : {
exitCode: reload.exitCode,
stdoutTail: Buffer.from(reload.stdout).toString("utf8").slice(-1000),
stderrTail: Buffer.from(reload.stderr).toString("utf8").slice(-1000),
},
active: {
exitCode: active.exitCode,
stdoutTail: Buffer.from(active.stdout).toString("utf8").slice(-1000),
stderrTail: Buffer.from(active.stderr).toString("utf8").slice(-1000),
},
valuesPrinted: false,
};
}
@@ -2961,24 +2928,6 @@ ${matchLines.join("\n")}
`;
}
function caddySiteBlock(text: string, domain: string): string | null {
const startMatch = new RegExp(`(^|\\n)${escapeRegExp(domain)}\\s*\\{`, "u").exec(text);
if (startMatch === null) return null;
const start = startMatch.index + (startMatch[1] === "\n" ? 1 : 0);
const open = text.indexOf("{", start);
if (open < 0) return null;
let depth = 0;
for (let index = open; index < text.length; index += 1) {
const ch = text[index];
if (ch === "{") depth += 1;
if (ch === "}") {
depth -= 1;
if (depth === 0) return text.slice(start, index + 1);
}
}
return null;
}
function frpsAllowPortExists(toml: string, port: number): boolean {
const sections = toml.split(/(?=\[\[allowPorts\]\])/u);
return sections.some((section) => {