From 7d7cd8a8d49830ec0e79bdd10cd52facfa0c1bb8 Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 26 Jun 2026 17:24:58 +0800 Subject: [PATCH] fix: use internal caserun API orchestration URL --- internal/cloud/server-caserun-http.test.ts | 4 +++- internal/cloud/server-caserun-http.ts | 23 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/internal/cloud/server-caserun-http.test.ts b/internal/cloud/server-caserun-http.test.ts index 6579dfe0..f294a38b 100644 --- a/internal/cloud/server-caserun-http.test.ts +++ b/internal/cloud/server-caserun-http.test.ts @@ -27,7 +27,7 @@ test("cloud-api exposes web CaseRun cases, run status, events and aggregate", as }; const server = createCloudApiServer({ accessController, - env: { PATH: process.env.PATH, HWLAB_CASERUN_CASE_REPO: root, HWLAB_CASERUN_STATE_DIR: stateRoot }, + env: { PATH: process.env.PATH, HWLAB_CASERUN_CASE_REPO: root, HWLAB_CASERUN_STATE_DIR: stateRoot, HWLAB_ENVIRONMENT: "v03", HWLAB_CLOUD_API_PORT: "6667" }, caseRunExecutor: async (context: any, emit: any) => { seen.push(context.parsed); await emit("prepared", { runDir: context.parsed.runDir }); @@ -60,11 +60,13 @@ test("cloud-api exposes web CaseRun cases, run status, events and aggregate", as assert.equal(startResponse.status, 202); assert.ok(["queued", "running"].includes(startPayload.status)); assert.match(startPayload.runId, /^web-d601-f103-v2-compile-/u); + assert.equal(startPayload.runtimeApiUrl, serverUrl(server)); const runPayload = await waitForRun(server, startPayload.runId, "completed"); assert.equal(runPayload.summary.jobId, "job-test"); assert.equal(seen[0].noCaseRepoRecord, true); assert.equal(seen[0].caseRepo, root); + assert.equal(seen[0].apiUrl, "http://hwlab-cloud-api.hwlab-v03.svc.cluster.local:6667"); const eventsResponse = await fetch(`${serverUrl(server)}/v1/caserun/runs/${startPayload.runId}/events`); const eventsPayload = await eventsResponse.json(); diff --git a/internal/cloud/server-caserun-http.ts b/internal/cloud/server-caserun-http.ts index cf49aa56..91df5a50 100644 --- a/internal/cloud/server-caserun-http.ts +++ b/internal/cloud/server-caserun-http.ts @@ -141,13 +141,14 @@ async function defaultCaseRunExecutor(context: any, emit: (stage: string, payloa } function caseContextForRecord(record: any, input: any) { + const internalApiUrl = internalRuntimeApiUrlForCaseRun(record, input.env ?? {}); const parsed = { _: [], caseId: record.caseId, runId: record.runId, runDir: record.runDir, caseRepo: input.caseRepo, - apiUrl: record.runtimeApiUrl, + apiUrl: internalApiUrl, noCaseRepoRecord: true, stateDir: path.join(input.stateRoot, "cli") }; @@ -157,7 +158,8 @@ function caseContextForRecord(record: any, input: any) { ...process.env, ...input.env, HWLAB_CASE_REPO: input.caseRepo, - HWLAB_RUNTIME_API_URL: record.runtimeApiUrl, + HWLAB_RUNTIME_API_URL: internalApiUrl, + HWLAB_CASERUN_PUBLIC_RUNTIME_API_URL: record.runtimeApiUrl, HWLAB_RUNTIME_ENDPOINT_LOCKED: "1" }, fetchImpl: input.fetchImpl ?? globalThis.fetch, @@ -323,6 +325,23 @@ function runtimeApiUrlFromRequest(request: IncomingMessage, env: Record) { + const explicit = String(env.HWLAB_CASERUN_INTERNAL_API_URL ?? env.HWLAB_RUNTIME_INTERNAL_API_URL ?? "").trim(); + if (explicit) return explicit.replace(/\/+$/u, ""); + const namespace = String(env.HWLAB_NAMESPACE ?? env.POD_NAMESPACE ?? env.KUBERNETES_NAMESPACE ?? namespaceFromEnvironment(env.HWLAB_ENVIRONMENT) ?? "").trim(); + const port = String(env.HWLAB_CLOUD_API_PORT ?? env.HWLAB_PORT ?? env.PORT ?? "6667").trim() || "6667"; + if (namespace) return `http://hwlab-cloud-api.${namespace}.svc.cluster.local:${port}`; + return String(record.runtimeApiUrl ?? "").replace(/\/+$/u, ""); +} + +function namespaceFromEnvironment(value: string | undefined) { + const text = String(value ?? "").trim(); + if (!text) return ""; + if (/^hwlab-[a-z0-9-]+$/u.test(text)) return text; + if (/^[a-z0-9-]+$/u.test(text)) return `hwlab-${text}`; + return ""; +} + async function readJsonBody(request: IncomingMessage, limitBytes: number) { let size = 0; const chunks = [] as Buffer[];