fix: move sub2api runtime to PK01 host docker

This commit is contained in:
Codex
2026-06-28 14:24:08 +00:00
parent 1d07df3df1
commit d225fd1a61
18 changed files with 1088 additions and 186 deletions
@@ -33,6 +33,7 @@ export function poolTarget(pool = readCodexPoolConfig(), target = codexPoolRunti
id: target.id,
route: target.route,
namespace: target.namespace,
runtimeMode: target.runtimeMode,
service: serviceName,
serviceDns: target.serviceDns,
publicBaseUrl: target.publicBaseUrl,
@@ -102,6 +103,9 @@ export function resolveManualProxyBinding(binding: CodexPoolManualAccountProxyBi
if (binding.enabled && source.provider === "target-egress-proxy" && (target.egressProxy === null || target.egressProxy.enabled !== true)) {
throw new Error(`${codexPoolConfigPath}.manualAccounts.bindingSources.${source.id} requires ${sub2apiConfigPath}.targets[${target.id}].egressProxy.enabled=true`);
}
if (binding.enabled && source.provider === "fixed-http-proxy" && source.fixedProxy === null) {
throw new Error(`${codexPoolConfigPath}.manualAccounts.bindingSources.${source.id} requires fixedProxy`);
}
return {
enabled: binding.enabled,
source: source.id,
@@ -118,6 +122,7 @@ export function resolveManualProxyBinding(binding: CodexPoolManualAccountProxyBi
noProxy: target.egressProxy.noProxy,
}
: null,
fixedProxy: source.provider === "fixed-http-proxy" ? source.fixedProxy : null,
},
};
}
@@ -149,6 +154,7 @@ export function manualBindingSourcePlan(source: CodexPoolManualBindingSource): R
kind: source.kind,
provider: source.provider,
description: source.description,
fixedProxy: source.fixedProxy,
};
}
@@ -162,14 +168,17 @@ export function targetPublicExposureSummary(target: CodexPoolRuntimeTarget): Rec
id: target.id,
route: target.route,
namespace: target.namespace,
runtimeMode: target.runtimeMode,
serviceDns: target.serviceDns,
},
urls: {
publicBaseUrl: exposure.publicBaseUrl,
consumerBaseUrl: target.publicBaseUrl === null ? null : `${target.publicBaseUrl.replace(/\/+$/u, "")}/`,
},
mode: exposure.mode,
dns: exposure.dns,
frpc: {
local: exposure.local,
frpc: exposure.frpc === null ? null : {
deploymentName: exposure.frpc.deploymentName,
secretName: exposure.frpc.secretName,
secretKey: exposure.frpc.secretKey,
@@ -188,16 +197,31 @@ export function targetPublicExposureSummary(target: CodexPoolRuntimeTarget): Rec
};
}
export function targetFrpPublicExposure(target: CodexPoolRuntimeTarget): PublicServiceExposure {
const exposure = target.publicExposure;
if (exposure === null) throw new Error(`${sub2apiConfigPath}.targets[${target.id}].publicExposure is required`);
if (exposure.mode !== "frp" || exposure.frpc === null) {
throw new Error(`${sub2apiConfigPath}.targets[${target.id}].publicExposure.frpc is required when using codex-pool expose frp operations`);
}
return {
enabled: exposure.enabled,
publicBaseUrl: exposure.publicBaseUrl,
dns: exposure.dns,
frpc: exposure.frpc,
pk01: exposure.pk01,
};
}
export function prepareTargetPublicExposureSecret(target: CodexPoolRuntimeTarget): ReturnType<typeof prepareFrpcSecret> {
if (target.publicExposure === null) throw new Error(`${sub2apiConfigPath}.targets[${target.id}].publicExposure is required`);
const exposure = targetFrpPublicExposure(target);
return prepareFrpcSecret({
secretRoot: target.secretsRoot,
exposure: target.publicExposure,
exposure,
sourcePathRedactor: redactRepoPath,
parseEnvFile,
requiredEnvValue,
readTextFile: (sourcePath) => {
if (!existsSync(sourcePath)) throw new Error(`publicExposure requires ${redactRepoPath(sourcePath)} with ${target.publicExposure?.frpc.tokenSourceKey}; materialize the PK01 frps token source first`);
if (!existsSync(sourcePath)) throw new Error(`publicExposure requires ${redactRepoPath(sourcePath)} with ${exposure.frpc.tokenSourceKey}; materialize the PK01 frps token source first`);
return readTextFile(sourcePath);
},
});
@@ -215,13 +239,13 @@ export function secretMaterialSummary(secret: ReturnType<typeof prepareFrpcSecre
}
export function targetPublicExposureApplyScript(target: CodexPoolRuntimeTarget, secret: ReturnType<typeof prepareFrpcSecret>): string {
if (target.publicExposure === null) throw new Error(`${sub2apiConfigPath}.targets[${target.id}].publicExposure is required`);
const exposure = targetFrpPublicExposure(target);
const manifest = renderFrpcManifest({
id: target.id,
route: target.route,
namespace: target.namespace,
replicas: 1,
publicExposure: target.publicExposure,
publicExposure: exposure,
} satisfies PublicServiceTarget);
const manifestB64 = Buffer.from(manifest, "utf8").toString("base64");
const frpcTomlB64 = Buffer.from(secret.frpcToml, "utf8").toString("base64");
@@ -263,7 +287,7 @@ if [ "$ns_rc" -eq 0 ] && [ "$secret_rc" -eq 0 ]; then
kubectl apply --server-side --force-conflicts --field-manager=${fieldManager} -f "$manifest" >"$apply_out" 2>"$apply_err"
apply_rc=$?
if [ "$apply_rc" -eq 0 ]; then
kubectl -n ${target.namespace} rollout status deployment/${target.publicExposure.frpc.deploymentName} --timeout=60s >"$rollout_out" 2>"$rollout_err"
kubectl -n ${target.namespace} rollout status deployment/${exposure.frpc.deploymentName} --timeout=60s >"$rollout_out" 2>"$rollout_err"
rollout_rc=$?
else
printf '%s\\n' 'skipped because apply failed' >"$rollout_err"
@@ -274,9 +298,9 @@ else
: >"$rollout_out"
printf '%s\\n' 'skipped because namespace or secret step failed' >"$rollout_err"
fi
kubectl -n ${target.namespace} get pods -l app.kubernetes.io/name=${target.publicExposure.frpc.deploymentName} -o json >"$pods_json" 2>"$pods_err"
kubectl -n ${target.namespace} get pods -l app.kubernetes.io/name=${exposure.frpc.deploymentName} -o json >"$pods_json" 2>"$pods_err"
pods_rc=$?
kubectl -n ${target.namespace} logs deployment/${target.publicExposure.frpc.deploymentName} --tail=80 >"$logs_out" 2>"$logs_err"
kubectl -n ${target.namespace} logs deployment/${exposure.frpc.deploymentName} --tail=80 >"$logs_out" 2>"$logs_err"
logs_rc=$?
python3 - "$tmp" "$ns_rc" "$secret_rc" "$apply_rc" "$rollout_rc" "$pods_rc" "$logs_rc" <<'PY'
import json
@@ -320,17 +344,17 @@ payload = {
"namespace": "${target.namespace}",
"source": "${sub2apiConfigPath}.targets[${target.id}].publicExposure",
"proxy": {
"name": "${target.publicExposure.frpc.proxyName}",
"remotePort": ${JSON.stringify(target.publicExposure.frpc.remotePort)},
"publicBaseUrl": "${target.publicExposure.publicBaseUrl}",
"localIP": "${target.publicExposure.frpc.localIP}",
"localPort": ${JSON.stringify(target.publicExposure.frpc.localPort)},
"name": "${exposure.frpc.proxyName}",
"remotePort": ${JSON.stringify(exposure.frpc.remotePort)},
"publicBaseUrl": "${exposure.publicBaseUrl}",
"localIP": "${exposure.frpc.localIP}",
"localPort": ${JSON.stringify(exposure.frpc.localPort)},
},
"resources": {
"secret": "${secret.secretName}",
"secretKey": "${secret.secretKey}",
"deployment": "${target.publicExposure.frpc.deploymentName}",
"image": "${target.publicExposure.frpc.image}",
"deployment": "${exposure.frpc.deploymentName}",
"image": "${exposure.frpc.image}",
},
"steps": {
"namespace": {"exitCode": ns_rc, "stdout": text("ns.out"), "stderr": text("ns.err")},