fix(hwlab): expose d518 code agent runtime config

This commit is contained in:
Codex
2026-06-27 16:04:20 +00:00
parent f8f0741073
commit 4227211544
5 changed files with 316 additions and 9 deletions
+174
View File
@@ -94,6 +94,21 @@ export function nodeRuntimeRenderOverlay(spec: HwlabRuntimeLaneSpec): Record<str
stepEnv: spec.stepEnv,
observability: spec.observability,
runtimeStore: spec.runtimeStore,
codeAgentRuntime: spec.codeAgentRuntime === undefined ? undefined : {
enabled: spec.codeAgentRuntime.enabled,
adapter: spec.codeAgentRuntime.adapter,
managerUrl: spec.codeAgentRuntime.managerUrl,
apiKeySecretName: spec.codeAgentRuntime.apiKeySecretName,
apiKeySecretKey: spec.codeAgentRuntime.apiKeySecretKey,
runnerNamespace: spec.codeAgentRuntime.runnerNamespace,
secretNamespace: spec.codeAgentRuntime.secretNamespace,
repoUrlFrom: spec.codeAgentRuntime.repoUrlFrom,
repoUrl: spec.gitReadUrl,
providerIdFrom: spec.codeAgentRuntime.providerIdFrom,
providerId: spec.nodeId,
defaultProviderProfile: spec.codeAgentRuntime.defaultProviderProfile,
valuesPrinted: false,
},
runtimeImageRewrites: spec.runtimeImageRewrites,
runtimeImageBuilds: spec.runtimeImageBuilds,
registryPrefix: spec.registryPrefix,
@@ -1286,6 +1301,165 @@ export function isLocalPostgresObject(name: string, spec: HwlabRuntimeLaneSpec):
return true;
}
export function nodeRuntimeCodeAgentRuntimeStatus(spec: HwlabRuntimeLaneSpec, namespaceExists: boolean): Record<string, unknown> {
const runtime = spec.codeAgentRuntime;
if (runtime === undefined || runtime.enabled === false) return { required: false, ready: true, enabled: runtime?.enabled ?? false };
if (!namespaceExists) return { required: true, ready: false, enabled: true, degradedReason: "runtime-namespace-missing" };
const managerTarget = nodeRuntimeCodeAgentManagerTarget(runtime.managerUrl, runtime.runnerNamespace);
const runnerNamespace = runNodeK3sArgs(spec, ["kubectl", "get", "ns", runtime.runnerNamespace, "-o", "name"], 60);
const secretNamespace = runNodeK3sArgs(spec, ["kubectl", "get", "ns", runtime.secretNamespace, "-o", "name"], 60);
const managerNamespace = runNodeK3sArgs(spec, ["kubectl", "get", "ns", managerTarget.namespace, "-o", "name"], 60);
const managerService = runNodeK3sArgs(spec, ["kubectl", "-n", managerTarget.namespace, "get", "service", managerTarget.serviceName, "-o", "name"], 60);
const managerDeployment = runNodeK3sArgs(spec, ["kubectl", "-n", managerTarget.namespace, "get", "deployment", managerTarget.serviceName, "-o", "jsonpath={.status.readyReplicas}{\"\\n\"}{.spec.replicas}{\"\\n\"}"], 60);
const [managerReadyReplicasRaw = "", managerDesiredReplicasRaw = ""] = managerDeployment.stdout.split(/\r?\n/u);
const managerReadyReplicas = numericField(managerReadyReplicasRaw);
const managerDesiredReplicas = numericField(managerDesiredReplicasRaw);
const managerDeploymentReady = managerDeployment.exitCode === 0 && (managerReadyReplicas ?? 0) >= Math.max(1, managerDesiredReplicas ?? 1);
const apiKey = secretKeyStatus(spec, runtime.apiKeySecretName, runtime.apiKeySecretKey);
const cloudApiEnv = nodeRuntimeCodeAgentCloudApiEnvStatus(spec, runtime);
const ready = runnerNamespace.exitCode === 0
&& secretNamespace.exitCode === 0
&& managerNamespace.exitCode === 0
&& managerService.exitCode === 0
&& managerDeploymentReady
&& apiKey.present === true
&& cloudApiEnv.ready === true;
const degradedReason = ready
? undefined
: runnerNamespace.exitCode !== 0
? "agentrun-runner-namespace-missing"
: secretNamespace.exitCode !== 0
? "agentrun-secret-namespace-missing"
: managerNamespace.exitCode !== 0
? "agentrun-manager-namespace-missing"
: managerService.exitCode !== 0
? "agentrun-manager-service-missing"
: !managerDeploymentReady
? "agentrun-manager-deployment-not-ready"
: apiKey.present !== true
? "agentrun-api-key-secret-missing"
: "hwlab-cloud-api-code-agent-env-mismatch";
return {
required: true,
enabled: true,
ready,
degradedReason,
adapter: runtime.adapter,
managerUrl: runtime.managerUrl,
manager: {
namespace: managerTarget.namespace,
serviceName: managerTarget.serviceName,
serviceExists: managerService.exitCode === 0,
deploymentReady: managerDeploymentReady,
readyReplicas: managerReadyReplicas,
desiredReplicas: managerDesiredReplicas,
namespaceResult: compactRuntimeCommand(managerNamespace),
serviceResult: compactRuntimeCommand(managerService),
deploymentResult: compactRuntimeCommand(managerDeployment),
},
runnerNamespace: {
name: runtime.runnerNamespace,
exists: runnerNamespace.exitCode === 0,
result: compactRuntimeCommand(runnerNamespace),
},
secretNamespace: {
name: runtime.secretNamespace,
exists: secretNamespace.exitCode === 0,
result: compactRuntimeCommand(secretNamespace),
},
apiKey,
cloudApiEnv,
repoUrlFrom: runtime.repoUrlFrom,
providerIdFrom: runtime.providerIdFrom,
valuesPrinted: false,
};
}
function nodeRuntimeCodeAgentManagerTarget(managerUrl: string, fallbackNamespace: string): { namespace: string; serviceName: string } {
let parsed: URL | null = null;
try {
parsed = new URL(managerUrl);
} catch {
parsed = null;
}
const host = parsed?.hostname ?? "";
const parts = host.split(".").filter(Boolean);
if (parts.length >= 3 && parts[2] === "svc") return { serviceName: parts[0], namespace: parts[1] };
return { serviceName: parts[0] || "agentrun-mgr", namespace: parts[1] || fallbackNamespace };
}
function nodeRuntimeCodeAgentCloudApiEnvStatus(spec: HwlabRuntimeLaneSpec, runtime: NonNullable<HwlabRuntimeLaneSpec["codeAgentRuntime"]>): Record<string, unknown> {
const deployment = runNodeK3sArgs(spec, ["kubectl", "-n", spec.runtimeNamespace, "get", "deployment", "hwlab-cloud-api", "-o", "json"], 60);
if (deployment.exitCode !== 0) {
return {
ready: false,
deploymentExists: false,
mismatches: [{ name: "hwlab-cloud-api", reason: "deployment-missing" }],
result: compactCodeAgentDeploymentProbeResult(deployment),
valuesPrinted: false,
};
}
let parsed: unknown;
try {
parsed = JSON.parse(deployment.stdout) as unknown;
} catch (error) {
return {
ready: false,
deploymentExists: true,
mismatches: [{ name: "hwlab-cloud-api", reason: "deployment-json-invalid", message: error instanceof Error ? error.message : String(error) }],
result: compactCodeAgentDeploymentProbeResult(deployment),
valuesPrinted: false,
};
}
const deploy = record(parsed);
const specRecord = record(record(record(deploy.spec).template).spec);
const containers = Array.isArray(specRecord.containers) ? specRecord.containers.map(record) : [];
const container = containers.find((item) => item.name === "hwlab-cloud-api") ?? containers[0];
const env = Array.isArray(container?.env) ? container.env.map(record) : [];
const envByName = new Map(env.map((item) => [String(item.name || ""), item]));
const mismatches: Array<Record<string, unknown>> = [];
const expectValue = (name: string, expected: string): void => {
const item = envByName.get(name);
const value = typeof item?.value === "string" ? item.value : null;
if (value !== expected) mismatches.push({ name, expected, value, kind: "value" });
};
const expectSecret = (name: string, expectedSecret: string, expectedKey: string): void => {
const item = envByName.get(name);
const secretRef = record(record(item?.valueFrom).secretKeyRef);
if (secretRef.name !== expectedSecret || secretRef.key !== expectedKey) {
mismatches.push({ name, expectedSecret, expectedKey, secret: secretRef.name ?? null, key: secretRef.key ?? null, kind: "secretKeyRef" });
}
};
expectValue("HWLAB_CODE_AGENT_ADAPTER", runtime.adapter);
expectValue("AGENTRUN_MGR_URL", runtime.managerUrl);
expectSecret("AGENTRUN_API_KEY", runtime.apiKeySecretName, runtime.apiKeySecretKey);
expectValue("HWLAB_CODE_AGENT_AGENTRUN_RUNNER_NAMESPACE", runtime.runnerNamespace);
expectValue("HWLAB_CODE_AGENT_AGENTRUN_SECRET_NAMESPACE", runtime.secretNamespace);
expectValue("HWLAB_CODE_AGENT_AGENTRUN_REPO_URL", spec.gitReadUrl);
expectValue("HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID", spec.nodeId);
expectValue("HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE", runtime.defaultProviderProfile);
return {
ready: mismatches.length === 0,
deploymentExists: true,
deploymentName: "hwlab-cloud-api",
containerName: container?.name ?? null,
checkedEnvCount: 8,
mismatches,
result: compactCodeAgentDeploymentProbeResult(deployment),
valuesPrinted: false,
};
}
function compactCodeAgentDeploymentProbeResult(result: CommandResult): Record<string, unknown> {
return {
exitCode: result.exitCode,
stdoutBytes: Buffer.byteLength(result.stdout, "utf8"),
stderrBytes: Buffer.byteLength(result.stderr, "utf8"),
stderrTail: result.stderr.slice(-600),
timedOut: result.timedOut === true,
};
}
export function externalPostgresBridgeStatus(spec: HwlabRuntimeLaneSpec, namespaceExists: boolean): Record<string, unknown> {
const pg = hwlabRuntimeActiveExternalPostgres(spec);
if (pg === undefined) return { required: false, ready: true };