fix: roll v02 metrics pods on sidecar script changes

This commit is contained in:
Codex Agent
2026-06-05 08:58:49 +08:00
parent dd2487ce02
commit 550eea19d4
2 changed files with 17 additions and 5 deletions
+12 -5
View File
@@ -798,6 +798,10 @@ function v02MetricsSidecarVolume() {
return { name: "hwlab-metrics-sidecar", configMap: { name: "hwlab-v02-metrics-sidecar" } };
}
function v02MetricsSidecarAnnotations(metricsSidecarSha256) {
return metricsSidecarSha256 ? { "hwlab.pikastech.local/metrics-sidecar-sha256": metricsSidecarSha256 } : {};
}
function v02MetricsSidecarContainer({ serviceId, namespace, gitopsTarget }) {
const service = v02ObservableService(serviceId);
assert.ok(service, `unknown v0.2 observable service ${serviceId}`);
@@ -837,7 +841,7 @@ function upsertV02MetricsPort(service) {
service.spec.ports.push({ name: "metrics", port: 9100, targetPort: "metrics" });
}
function transformWorkloads({ workloads, deploy, catalog, source, sourceBranch = defaultBranch, registryPrefix, runtimeEndpoint, webEndpoint, profile = "dev", useDeployImages = false }) {
function transformWorkloads({ workloads, deploy, catalog, source, sourceBranch = defaultBranch, registryPrefix, runtimeEndpoint, webEndpoint, profile = "dev", useDeployImages = false, metricsSidecarSha256 = null }) {
const result = cloneJson(workloads);
const deployServices = deployServicesForProfile(deploy, profile);
const namespace = namespaceNameForProfile(profile);
@@ -888,6 +892,7 @@ function transformWorkloads({ workloads, deploy, catalog, source, sourceBranch =
if (profile === "v02" && v02ObservableServiceIds.has(templateServiceId)) {
label(item.metadata, v02MetricsLabels(templateServiceId));
label(podTemplate.metadata, v02MetricsLabels(templateServiceId));
annotate(podTemplate.metadata, v02MetricsSidecarAnnotations(metricsSidecarSha256));
upsertV02MetricsSidecar(podTemplate.spec, { serviceId: templateServiceId, namespace, gitopsTarget });
}
if ((item.kind === "Deployment" || item.kind === "StatefulSet") && item.spec?.selector?.matchLabels) {
@@ -4046,7 +4051,7 @@ remotePort = ${edgeRemotePort}
};
}
function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defaultRegistryPrefix, catalog = null, useDeployImages = false } = {}) {
function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defaultRegistryPrefix, catalog = null, useDeployImages = false, metricsSidecarSha256 = null } = {}) {
const namespace = namespaceNameForProfile(profile);
const bridgeServiceId = "hwlab-cloud-api";
const digestPin = profile === "v02";
@@ -4072,7 +4077,8 @@ function deepSeekProxyManifest({ profile = "dev", source, registryPrefix = defau
"hwlab.pikastech.local/source-commit": bridgeCommit,
"hwlab.pikastech.local/bridge-source-commit": bridgeCommit,
"hwlab.pikastech.local/bridge-image-tag": bridgeImageTag,
"hwlab.pikastech.local/bridge-image": bridgeImage
"hwlab.pikastech.local/bridge-image": bridgeImage,
...v02MetricsSidecarAnnotations(profile === "v02" ? metricsSidecarSha256 : null)
};
return {
apiVersion: "v1",
@@ -4588,6 +4594,7 @@ async function plannedFiles(args) {
const metricsSidecarScript = args.lane === "v02"
? await readFile(path.join(repoRoot, "internal/dev-entrypoint/metrics-sidecar.mjs"), "utf8")
: null;
const metricsSidecarSha256 = metricsSidecarScript ? createHash("sha256").update(metricsSidecarScript).digest("hex") : null;
const baseLabels = { "hwlab.pikastech.local/gitops-target": settings.gitopsTarget, "hwlab.pikastech.local/source-commit": source.full };
const annotations = { "hwlab.pikastech.local/rendered-by": "scripts/g14-gitops-render.mjs" };
const files = new Map();
@@ -4652,8 +4659,8 @@ async function plannedFiles(args) {
if (profile !== "v02") putJson(`${runtimePath}/code-agent-codex-config.yaml`, transformListNamespace(config, namespace, profileLabels, annotations));
putJson(`${runtimePath}/services.yaml`, transformServices({ services, namespace, labels: profileLabels, annotations, profile }));
putJson(`${runtimePath}/health-contract.yaml`, transformHealthContract(health, namespace, profileLabels, annotations, endpoints.runtimeEndpoint, endpoints.webEndpoint, profile));
putJson(`${runtimePath}/workloads.yaml`, transformWorkloads({ workloads, deploy, catalog: artifactCatalog, source, sourceBranch: args.sourceBranch, registryPrefix: args.registryPrefix, runtimeEndpoint: endpoints.runtimeEndpoint, webEndpoint: endpoints.webEndpoint, profile, useDeployImages: args.useDeployImages }));
putJson(`${runtimePath}/deepseek-proxy.yaml`, deepSeekProxyManifest({ profile, source, registryPrefix: args.registryPrefix, catalog: artifactCatalog, useDeployImages: args.useDeployImages }));
putJson(`${runtimePath}/workloads.yaml`, transformWorkloads({ workloads, deploy, catalog: artifactCatalog, source, sourceBranch: args.sourceBranch, registryPrefix: args.registryPrefix, runtimeEndpoint: endpoints.runtimeEndpoint, webEndpoint: endpoints.webEndpoint, profile, useDeployImages: args.useDeployImages, metricsSidecarSha256 }));
putJson(`${runtimePath}/deepseek-proxy.yaml`, deepSeekProxyManifest({ profile, source, registryPrefix: args.registryPrefix, catalog: artifactCatalog, useDeployImages: args.useDeployImages, metricsSidecarSha256 }));
if (profile === "v02") putJson(`${runtimePath}/postgres.yaml`, v02PostgresManifest({ migrationSql, source }));
if (profile === "v02") putJson(`${runtimePath}/observability.yaml`, observabilityManifest({ namespace, labels: profileLabels, annotations, metricsSidecarScript }));
if (includeDeviceAgent) putJson(`${runtimePath}/device-agent-71-freq.yaml`, deviceAgent71FreqManifest({ profile, source, registryPrefix: args.registryPrefix, catalog: artifactCatalog, useDeployImages: args.useDeployImages }));
+5
View File
@@ -239,6 +239,7 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
assert.ok(sidecar, `missing metrics sidecar for ${serviceId}`);
assert.match(sidecar.image, /hwlab-ci-node-tools:node22-alpine-bun-v1/u);
assert.deepEqual(sidecar.command, ["node", "/metrics/metrics-sidecar.mjs"]);
assert.match(workload.spec.template.metadata.annotations["hwlab.pikastech.local/metrics-sidecar-sha256"], /^[a-f0-9]{64}$/u);
assert.ok(sidecar.env.some((entry) => entry.name === "HWLAB_METRICS_SERVICE_ID" && entry.value === serviceId));
assert.ok(sidecar.ports.some((port) => port.name === "metrics" && port.containerPort === 9100));
}
@@ -247,6 +248,10 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots
assert.ok(deepseekService.spec.ports.some((port) => port.name === "metrics" && port.port === 9100));
const deepseekDeployment = deepseekProxy.items.find((item) => item.kind === "Deployment" && item.metadata?.name === "hwlab-deepseek-proxy");
assert.ok(deepseekDeployment.spec.template.spec.containers.some((container) => container.name === "hwlab-metrics"));
assert.equal(
deepseekDeployment.spec.template.metadata.annotations["hwlab.pikastech.local/metrics-sidecar-sha256"],
workloadsJson.items.find((item) => item.kind === "Deployment" && item.metadata?.name === "hwlab-cloud-api").spec.template.metadata.annotations["hwlab.pikastech.local/metrics-sidecar-sha256"]
);
const observabilityItems = observabilityJson.items ?? [];
const metricsConfig = observabilityItems.find((item) => item.kind === "ConfigMap" && item.metadata?.name === "hwlab-v02-metrics-sidecar");
assert.ok(metricsConfig, "missing metrics sidecar ConfigMap");