fix: preserve PK01 Caddy managed blocks
This commit is contained in:
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user