fix(sub2api): enable JD01 sentinel without docker build
This commit is contained in:
@@ -100,16 +100,11 @@ export interface CodexPoolSentinelManifestOptions {
|
||||
}
|
||||
|
||||
export function codexPoolSentinelRuntimeImage(config: CodexPoolSentinelConfig): CodexPoolSentinelImageTarget {
|
||||
const baseTag = config.image
|
||||
.replace(/[^A-Za-z0-9_.-]+/gu, "-")
|
||||
.replace(/^-+|-+$/gu, "")
|
||||
.slice(0, 80) || "python";
|
||||
const tag = `${baseTag}-openai-${config.sdk.openaiPythonVersion}`;
|
||||
const repository = "127.0.0.1:5000/platform-infra/sub2api-account-sentinel";
|
||||
const [repository, tag = "latest"] = config.image.split(":");
|
||||
return {
|
||||
baseImage: config.image,
|
||||
runtimeImage: `${repository}:${tag}`,
|
||||
repository,
|
||||
runtimeImage: config.image,
|
||||
repository: repository ?? config.image,
|
||||
tag,
|
||||
};
|
||||
}
|
||||
@@ -446,14 +441,27 @@ ${proxyEnv}
|
||||
export function sentinelContainerShellCommand(config: CodexPoolSentinelConfig): string {
|
||||
return [
|
||||
"set -eu",
|
||||
"python3 - <<'PY'",
|
||||
`OPENAI_PYTHON_VERSION=${JSON.stringify(config.sdk.openaiPythonVersion)}`,
|
||||
"if ! python3 - <<'PY'",
|
||||
"import importlib.metadata",
|
||||
`expected = ${JSON.stringify(config.sdk.openaiPythonVersion)}`,
|
||||
"import os",
|
||||
"expected = os.environ['OPENAI_PYTHON_VERSION']",
|
||||
"try:",
|
||||
" current = importlib.metadata.version('openai')",
|
||||
"except importlib.metadata.PackageNotFoundError:",
|
||||
" current = None",
|
||||
"if current != expected:",
|
||||
" raise SystemExit(1)",
|
||||
"PY",
|
||||
"then",
|
||||
" python3 -m pip install --no-cache-dir \"openai==$OPENAI_PYTHON_VERSION\"",
|
||||
"fi",
|
||||
"python3 - <<'PY'",
|
||||
"import importlib.metadata",
|
||||
"import os",
|
||||
"expected = os.environ['OPENAI_PYTHON_VERSION']",
|
||||
"current = importlib.metadata.version('openai')",
|
||||
"if current != expected:",
|
||||
" raise SystemExit(f'openai-python-version-mismatch expected={expected} current={current}')",
|
||||
"PY",
|
||||
"exec python3 /opt/sentinel/sentinel.py",
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
import { parseEnvFile, readTextFile, redactRepoPath, requiredEnvValue } from "../secrets";
|
||||
import { runSshCommandCapture, type SshCaptureResult } from "../ssh";
|
||||
|
||||
import type { RemoteCodexPoolMode } from "./remote";
|
||||
import type { CodexPoolConfig, ConfirmOptions, DisclosureOptions, SentinelImageOptions, SentinelProbeOptions, SentinelReportOptions, SyncOptions, TraceOptions } from "./types";
|
||||
import { desiredAccountNames } from "./accounts";
|
||||
import { collectCodexProfiles, readCodexPoolConfig } from "./config";
|
||||
@@ -30,10 +29,10 @@ import { apiKeyPreview, codexConsumerBaseUrl, fetchPoolApiKey, probePublicModels
|
||||
import { manualBindingSourcePlan, poolTarget, prepareTargetPublicExposureSecret, resolvedManualAccountProtections, secretMaterialSummary, sentinelProfileSecrets, targetFrpPublicExposure, targetPublicExposureApplyScript, targetPublicExposureSummary } from "./public-exposure";
|
||||
import { codexPoolConfigSummary, compactProfile, compactSentinelProbeResult, redactProfile, renderSub2ApiTempUnschedulableCredentials } from "./redaction";
|
||||
import { boolField, capture, compactCapture, parseJsonOutput, runRemoteCodexPoolScript } from "./remote";
|
||||
import { cleanupProbesScript, sentinelImageBuildScript, sentinelImageStatusScript, sentinelProbeScript, sentinelReportScript, syncScript, traceScript, validateScript } from "./remote-scripts";
|
||||
import { cleanupProbesScript, sentinelProbeScript, sentinelReportScript, syncScript, traceScript, validateScript } from "./remote-scripts";
|
||||
import { codexPoolSyncSummary, codexPoolValidationSummary, renderSentinelReport, renderTraceReport, renderedCliResult } from "./render";
|
||||
import { codexPoolRuntimeTarget, defaultCodexPoolRuntimeTargetId, targetFlag } from "./runtime-target";
|
||||
import { codexPoolConfigPath, sentinelImageDockerfilePath, serviceName, sub2apiConfigPath } from "./types";
|
||||
import { codexPoolConfigPath, serviceName, sub2apiConfigPath } from "./types";
|
||||
|
||||
export function codexPoolPlan(options?: DisclosureOptions): Record<string, unknown> {
|
||||
const resolvedOptions = options ?? { full: false, raw: false, targetId: defaultCodexPoolRuntimeTargetId() };
|
||||
@@ -242,6 +241,7 @@ export async function codexPoolSentinelImage(config: UniDeskConfig, options: Sen
|
||||
export async function runCodexPoolSentinelImage(config: UniDeskConfig, pool: CodexPoolConfig, options: SentinelImageOptions): Promise<Record<string, unknown>> {
|
||||
const runtimeTarget = codexPoolRuntimeTarget(options.targetId);
|
||||
const target = codexPoolSentinelRuntimeImage(pool.sentinel);
|
||||
void config;
|
||||
if (!runtimeTarget.sentinelEnabled) {
|
||||
return {
|
||||
ok: true,
|
||||
@@ -256,40 +256,37 @@ export async function runCodexPoolSentinelImage(config: UniDeskConfig, pool: Cod
|
||||
valuesPrinted: false,
|
||||
};
|
||||
}
|
||||
if (options.action === "build" && options.dryRun) {
|
||||
const summary = {
|
||||
ok: true,
|
||||
mode: options.action === "status" ? "base-image-runtime" : options.dryRun ? "dry-run-base-image-runtime" : "skipped-build-base-image-runtime",
|
||||
target: {
|
||||
id: runtimeTarget.id,
|
||||
namespace: runtimeTarget.namespace,
|
||||
},
|
||||
image: target.runtimeImage,
|
||||
baseImage: target.baseImage,
|
||||
openaiPythonVersion: pool.sentinel.sdk.openaiPythonVersion,
|
||||
sdkInstall: "container-startup-pinned",
|
||||
dockerRequired: false,
|
||||
registryPushRequired: false,
|
||||
mutation: false,
|
||||
valuesPrinted: false,
|
||||
};
|
||||
if (options.raw) {
|
||||
return {
|
||||
ok: true,
|
||||
action: "platform-infra-sub2api-codex-pool-sentinel-image",
|
||||
mode: "dry-run",
|
||||
image: target,
|
||||
dockerfile: sentinelImageDockerfilePath,
|
||||
mutation: false,
|
||||
next: {
|
||||
confirm: `bun scripts/cli.ts platform-infra sub2api codex-pool sentinel-image build${targetFlag(runtimeTarget)} --confirm`,
|
||||
},
|
||||
};
|
||||
}
|
||||
const mode: RemoteCodexPoolMode = options.action === "status" ? "sentinel-image-status" : "sentinel-image-build";
|
||||
const script = options.action === "status" ? sentinelImageStatusScript(pool, runtimeTarget) : sentinelImageBuildScript(pool, runtimeTarget);
|
||||
const result = await runRemoteCodexPoolScript(config, mode, script, runtimeTarget);
|
||||
const parsed = parseJsonOutput(result.stdout);
|
||||
if (options.raw) {
|
||||
return {
|
||||
ok: result.exitCode === 0 && boolField(parsed, "ok", false),
|
||||
action: "platform-infra-sub2api-codex-pool-sentinel-image",
|
||||
mode: options.action,
|
||||
image: target,
|
||||
remote: compactCapture(result, { full: true }),
|
||||
parsed,
|
||||
parsed: summary,
|
||||
};
|
||||
}
|
||||
return {
|
||||
ok: result.exitCode === 0 && boolField(parsed, "ok", false),
|
||||
ok: true,
|
||||
action: "platform-infra-sub2api-codex-pool-sentinel-image",
|
||||
mode: options.action,
|
||||
image: target,
|
||||
summary: parsed,
|
||||
remote: compactCapture(result, { full: options.full || result.exitCode !== 0 }),
|
||||
summary,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user