From c2f53cf61f684e5cd9fea2bee49ea045e46cdece Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 26 May 2026 14:38:55 +0800 Subject: [PATCH] fix: reuse deploy images for G14 auxiliary workloads --- scripts/g14-gitops-render.mjs | 72 ++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/scripts/g14-gitops-render.mjs b/scripts/g14-gitops-render.mjs index 2c139c98..4e140a5b 100644 --- a/scripts/g14-gitops-render.mjs +++ b/scripts/g14-gitops-render.mjs @@ -234,6 +234,31 @@ function runtimeImageTagForDeployService(deployService, source) { return deployService?.env?.HWLAB_IMAGE_TAG ?? imageTagFromReference(deployService?.image) ?? source.short; } +function deployServiceById(deploy, serviceId) { + return (deploy?.services ?? []).find((service) => service?.serviceId === serviceId) ?? null; +} + +function runtimeImageForService({ deploy, serviceId, source, registryPrefix, useDeployImages = false }) { + const deployService = deployServiceById(deploy, serviceId); + return useDeployImages && deployService?.image + ? deployService.image + : imageFor(registryPrefix, serviceId, source.short); +} + +function runtimeCommitForService({ deploy, serviceId, source, useDeployImages = false }) { + const deployService = deployServiceById(deploy, serviceId); + return useDeployImages + ? runtimeCommitForDeployService(deployService, source) + : source.full; +} + +function runtimeImageTagForService({ deploy, serviceId, source, useDeployImages = false }) { + const deployService = deployServiceById(deploy, serviceId); + return useDeployImages + ? runtimeImageTagForDeployService(deployService, source) + : source.short; +} + function namespaceNameForProfile(profile) { return profile === "prod" ? "hwlab-prod" : "hwlab-dev"; } @@ -1744,9 +1769,12 @@ remotePort = ${edgeRemotePort} }; } -function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defaultRegistryPrefix } = {}) { +function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defaultRegistryPrefix, deploy = null, useDeployImages = false } = {}) { const namespace = namespaceNameForProfile(profile); - const bridgeImage = imageFor(registryPrefix, "hwlab-cloud-api", source.short); + const bridgeServiceId = "hwlab-cloud-api"; + const bridgeImage = runtimeImageForService({ deploy, serviceId: bridgeServiceId, source, registryPrefix, useDeployImages }); + const bridgeCommit = runtimeCommitForService({ deploy, serviceId: bridgeServiceId, source, useDeployImages }); + const bridgeImageTag = runtimeImageTagForService({ deploy, serviceId: bridgeServiceId, source, useDeployImages }); const labels = { "app.kubernetes.io/name": "hwlab-deepseek-proxy", "app.kubernetes.io/part-of": "hwlab", @@ -1754,6 +1782,12 @@ function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defau "hwlab.pikastech.local/gitops-target": "g14", "hwlab.pikastech.local/service-id": "hwlab-deepseek-proxy" }; + const templateAnnotations = { + "hwlab.pikastech.local/bridge-service-id": bridgeServiceId, + "hwlab.pikastech.local/bridge-source-commit": bridgeCommit, + "hwlab.pikastech.local/bridge-image-tag": bridgeImageTag, + "hwlab.pikastech.local/bridge-image": bridgeImage + }; return { apiVersion: "v1", kind: "List", @@ -1769,12 +1803,12 @@ function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defau { apiVersion: "apps/v1", kind: "Deployment", - metadata: { name: "hwlab-deepseek-proxy", namespace, labels, annotations: { "hwlab.pikastech.local/moonbridge-source-ref": moonBridgeSourceRef } }, + metadata: { name: "hwlab-deepseek-proxy", namespace, labels, annotations: { "hwlab.pikastech.local/moonbridge-source-ref": moonBridgeSourceRef, ...templateAnnotations } }, spec: { replicas: 1, selector: { matchLabels: { "app.kubernetes.io/name": "hwlab-deepseek-proxy" } }, template: { - metadata: { labels }, + metadata: { labels, annotations: templateAnnotations }, spec: { initContainers: [{ name: "moonbridge-config", @@ -1794,6 +1828,9 @@ function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defau command: ["node", "/app/cmd/hwlab-deepseek-responses-bridge/main.mjs"], env: [ { name: "PORT", value: "4000" }, + { name: "HWLAB_COMMIT_ID", value: bridgeCommit }, + { name: "HWLAB_IMAGE", value: bridgeImage }, + { name: "HWLAB_IMAGE_TAG", value: bridgeImageTag }, { name: "HWLAB_DEEPSEEK_BRIDGE_UPSTREAM", value: "http://127.0.0.1:4001" }, { name: "HWLAB_DEEPSEEK_BRIDGE_MODEL", value: deepSeekProfileModel } ], @@ -2017,10 +2054,14 @@ function deviceAgent71FreqServerScript() { ].join("\n") + "\n"; } -function deviceAgent71FreqManifest({ profile = "dev", source, registryPrefix }) { +function deviceAgent71FreqManifest({ profile = "dev", source, registryPrefix, deploy = null, useDeployImages = false }) { assert.equal(profile, "dev", "71-freq device-agent is dev-only"); const namespace = namespaceNameForProfile(profile); const name = "device-agent-71-freq"; + const bridgeServiceId = "hwlab-cloud-api"; + const bridgeImage = runtimeImageForService({ deploy, serviceId: bridgeServiceId, source, registryPrefix, useDeployImages }); + const bridgeCommit = runtimeCommitForService({ deploy, serviceId: bridgeServiceId, source, useDeployImages }); + const bridgeImageTag = runtimeImageTagForService({ deploy, serviceId: bridgeServiceId, source, useDeployImages }); const labels = { "app.kubernetes.io/name": name, "app.kubernetes.io/part-of": "hwlab", @@ -2036,7 +2077,15 @@ function deviceAgent71FreqManifest({ profile = "dev", source, registryPrefix }) const selector = { "app.kubernetes.io/name": name }; const script = deviceAgent71FreqServerScript(); const scriptSha256 = createHash("sha256").update(script).digest("hex"); - const templateAnnotations = { ...annotations, "hwlab.pikastech.local/script-sha256": scriptSha256 }; + const templateLabels = { ...labels, ...selector, "hwlab.pikastech.local/source-commit": bridgeCommit }; + const templateAnnotations = { + ...annotations, + "hwlab.pikastech.local/script-sha256": scriptSha256, + "hwlab.pikastech.local/bridge-service-id": bridgeServiceId, + "hwlab.pikastech.local/bridge-source-commit": bridgeCommit, + "hwlab.pikastech.local/bridge-image-tag": bridgeImageTag, + "hwlab.pikastech.local/bridge-image": bridgeImage + }; return { apiVersion: "v1", kind: "List", @@ -2055,15 +2104,18 @@ function deviceAgent71FreqManifest({ profile = "dev", source, registryPrefix }) replicas: 1, selector: { matchLabels: selector }, template: { - metadata: { labels: { ...labels, ...selector }, annotations: templateAnnotations }, + metadata: { labels: templateLabels, annotations: templateAnnotations }, spec: { containers: [{ name: "device-agent", - image: imageFor(registryPrefix, "hwlab-cloud-api", source.short), + image: bridgeImage, imagePullPolicy: "IfNotPresent", command: ["node", "/opt/device-agent/server.mjs"], env: [ { name: "PORT", value: "7601" }, + { name: "HWLAB_COMMIT_ID", value: bridgeCommit }, + { name: "HWLAB_IMAGE", value: bridgeImage }, + { name: "HWLAB_IMAGE_TAG", value: bridgeImageTag }, { name: "DEVICE_ID", value: "71-freq" }, { name: "DEVICE_WORKSPACE_ROOT", value: "F:\\Work\\ConStart" }, { name: "HWLAB_CLOUD_API_URL", value: `http://hwlab-cloud-api.${namespace}.svc.cluster.local:6667` }, @@ -2194,8 +2246,8 @@ async function plannedFiles(args) { putJson(`${runtimePath}/services.yaml`, transformListNamespace(services, namespace, profileLabels, annotations)); putJson(`${runtimePath}/health-contract.yaml`, transformHealthContract(health, namespace, profileLabels, annotations, endpoints.runtimeEndpoint, endpoints.webEndpoint, profile)); putJson(`${runtimePath}/workloads.yaml`, transformWorkloads({ workloads, deploy, source, registryPrefix: args.registryPrefix, runtimeEndpoint: endpoints.runtimeEndpoint, webEndpoint: endpoints.webEndpoint, profile, useDeployImages: args.useDeployImages })); - putJson(`${runtimePath}/deepseek-proxy.yaml`, deepSeekProxyManifest({ profile, source, registryPrefix: args.registryPrefix })); - if (includeDeviceAgent) putJson(`${runtimePath}/device-agent-71-freq.yaml`, deviceAgent71FreqManifest({ profile, source, registryPrefix: args.registryPrefix })); + putJson(`${runtimePath}/deepseek-proxy.yaml`, deepSeekProxyManifest({ profile, source, registryPrefix: args.registryPrefix, deploy, useDeployImages: args.useDeployImages })); + if (includeDeviceAgent) putJson(`${runtimePath}/device-agent-71-freq.yaml`, deviceAgent71FreqManifest({ profile, source, registryPrefix: args.registryPrefix, deploy, useDeployImages: args.useDeployImages })); putJson(`${runtimePath}/g14-frpc.yaml`, g14FrpcManifest({ profile })); } return { files, source };