Files
buzz/deploy/charts/buzz/values.schema.json
Luke Tornquist 5a93e862ee fix(chart): own the Datadog version label on every workload Pod (#7876)
## Summary

Every chart-managed Pod now carries a chart-owned
`tags.datadoghq.com/version` label derived from the deployed image,
instead of a value each wrapper restates once per workload.

Covered Pod templates:
- relay Deployment (`templates/deployment.yaml`)
- pairing relay (`templates/pairing-relay.yaml`)
- storage-accounting CronJob
(`templates/storage-accounting-cronjob.yaml`)
- operator jobs, including the deletion drain
(`templates/_operator-jobs.tpl`)

**Source order:** `image.tag`, then `image.digest`, then
`Chart.AppVersion` (`buzz.imageVersionSource`). Tag-first is deliberate:
- The rendered value matches the `sha-<commit>` pins wrappers already
carry, so upgrading to this chart does not roll any Pods.
- An image promotion only has to write `image.tag` + `image.digest`. No
per-workload label edit is needed.

Exact runtime identity stays exact in two places. The image reference is
`repository@digest` when a digest is pinned.
`BUZZ_STORAGE_SNAPSHOT_CODE_SHA` (persisted as `code_sha`) is still
digest-first.

**Label safety:** `buzz.imageVersionLabel` maps any OCI tag or digest to
a valid label value.
- Valid values already in Datadog's normal form (lowercase, no `__`)
pass through byte for byte, so `sha-<hex>` and `1.2.3-rc.4` are
unchanged. Datadog lowercases tag values and collapses `__`, so any
other value is hashed rather than allowed to report the same version as
a different revision.
- A digest keeps 63 hex characters.
- Anything else is replaced by the first 63 hex characters of its
SHA-256.
- Exactly 63 lowercase hex characters is reserved for the hashed and
digest forms, so a rendered label cannot be fed back as a tag to make
two revisions collide.
- When both tag and digest are set, the label names the tag even if they
disagree; the digest still pins what runs.

**Precedence:** a `tags.datadoghq.com/version` supplied through any
workload's `podLabels` is ignored. Every other label, including
`tags.datadoghq.com/env` and `/service`, passes through unchanged.
Overriding instead of failing means a wrapper with a stale pin is
corrected by the upgrade itself. The chart bump and the wrapper cleanup
don't have to land together.

**What got simpler:** one image identity instead of N. Wrappers delete
their per-workload version pins. Image promotion tooling no longer needs
a "mirror the tag into a label path" feature. One shared helper
(`buzz.podLabelsWithVersion`) replaces four `podLabels` passthroughs.

Chart `0.1.10 → 0.1.11`, with an `artifacthub.io/changes` entry.
Documented in the chart README ("Datadog version label") and
`docs/deployment-identity.md`.

Note: a vendor-namespaced label now renders unconditionally in an OSS
chart. This is in tension with
[VISION_SOVEREIGN.md](../blob/main/VISION_SOVEREIGN.md). The label is
inert without the operator-supplied `tags.datadoghq.com/service`/`env`,
and the chart already ships vendor-specific defaults (e.g.
`sidecar.istio.io/inject`).

### Testing

Run on a Blox (Linux) workstation at tree `41634b7ca` (helm v3.16.4,
helm-unittest 0.8.2, the CI versions):
- `helm lint deploy/charts/buzz`: 0 failed
- `helm unittest deploy/charts/buzz`: 12 suites, **85/85 passed**

New `tests/version_label_test.yaml` checks the relay, pairing relay, and
deletion drain: tag wins over a stale `podLabels` pin, the label is
stamped with no `podLabels`, and digest-only images get a label-safe
value. `tests/storage_accounting_test.yaml` covers the same cases for
the CronJob, plus the `Chart.AppVersion` fallback.

Mutation checks:
- Reverting any one template to the plain `podLabels` passthrough fails
tests.
- Switching the source order to digest-first fails tests.
- Restoring the case-insensitive passthrough fails the three
Datadog-normalization tests (uppercase, `__`, uppercased 63-hex).

No Rust, desktop, web, or mobile sources changed.

## Linear tracking

Related work: [BUZZ-215](https://linear.app/squareup/issue/BUZZ-215).

---------

Signed-off-by: tornquist <tornquist@squareup.com>
Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
2026-10-08 15:12:00 -04:00

356 lines
13 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Buzz Helm chart values",
"description": "Schema for values.yaml. Catches misconfiguration at `helm install` time before _validate.tpl runtime fails. Both layers are intentional: schema rejects malformed inputs; templates reject inconsistent combinations.",
"type": "object",
"additionalProperties": true,
"properties": {
"quickstart": {
"type": "boolean",
"description": "Master toggle for evaluation profile (enables postgresql + redis subcharts and chart-side autogen). Not GitOps-safe."
},
"image": {
"type": "object",
"additionalProperties": false,
"properties": {
"repository": { "type": "string", "minLength": 1 },
"tag": { "type": "string" },
"digest": {
"type": "string",
"pattern": "^$|^sha256:[0-9a-f]{64}$",
"description": "Optional immutable OCI image digest. When set, the chart renders repository@digest and ignores tag."
},
"pullPolicy": { "type": "string", "enum": ["Always", "IfNotPresent", "Never"] },
"pullSecrets": {
"type": "array",
"items": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string" } } }
}
},
"required": ["repository", "pullPolicy"]
},
"replicaCount": {
"type": "integer",
"minimum": 1,
"description": "Replica count for the relay Deployment. replicaCount > 1 requires Redis (for buzz-pubsub) — enforced by _validate.tpl. Git storage does NOT need ReadWriteMany: git state is object-store-backed and repo names live in Postgres, so ReadWriteOnce is fine per replica."
},
"relayUrl": {
"type": "string",
"pattern": "^(wss?://.+)?$",
"description": "Public wss:// URL clients connect to. Required (validated by _validate.tpl). Drives RELAY_URL, default mediaBaseUrl, default ingress host."
},
"mediaBaseUrl": {
"type": "string",
"pattern": "^(https?://.+)?$"
},
"ownerPubkey": {
"type": "string",
"pattern": "^([0-9a-f]{64})?$",
"description": "64-char lowercase hex Nostr pubkey of the relay operator. Required when relay.requireRelayMembership=true."
},
"secrets": {
"type": "object",
"additionalProperties": false,
"properties": {
"existingSecret": { "type": "string", "description": "Name of an externally managed Secret. Production / GitOps path." },
"relayPrivateKey": { "type": "string" },
"gitHookHmacSecret": { "type": "string" }
}
},
"relay": {
"type": "object",
"additionalProperties": true,
"properties": {
"bindAddr": { "type": "string", "minLength": 1 },
"maxConnections": { "type": "integer", "minimum": 1 },
"maxConcurrentHandlers": { "type": "integer", "minimum": 1 },
"sendBuffer": { "type": "integer", "minimum": 1 },
"drainJitterMs": { "type": "integer", "minimum": 0 },
"requireAuthToken": { "type": "boolean" },
"requireRelayMembership": { "type": "boolean" },
"allowNipOaAuth": { "type": "boolean" },
"huddleAudioAvailable": {
"type": ["boolean", "null"],
"description": "Whether relay huddle audio is available. null means chart default: true for one replica, false for replicaCount > 1. Explicit true with replicaCount > 1 means the operator accepts/owns external multi-pod audio/SFU behavior."
},
"pubkeyAllowlist": { "type": "boolean" },
"corsOrigins": {
"type": "array",
"items": { "type": "string" }
},
"ephemeralTtlOverride": { "type": "integer", "minimum": 0 },
"command": {
"type": "array",
"items": { "type": "string" },
"description": "Optional relay container entrypoint override. Empty preserves the image default."
},
"args": {
"type": "array",
"items": { "type": "string" },
"description": "Optional relay container arguments override. Empty preserves the image default."
},
"extraVolumeMounts": {
"type": "array",
"items": { "type": "object" },
"description": "Raw Kubernetes volumeMount fragments appended to the relay container."
}
}
},
"extraInitContainers": {
"type": "array",
"items": { "type": "object" },
"description": "Raw Kubernetes init-container fragments appended to the relay Pod."
},
"extraVolumes": {
"type": "array",
"items": { "type": "object" },
"description": "Raw Kubernetes volume fragments appended to the relay Pod."
},
"service": {
"type": "object",
"additionalProperties": true,
"properties": {
"type": { "type": "string", "enum": ["ClusterIP", "NodePort", "LoadBalancer"] },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"healthPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
"metricsPort": { "type": "integer", "minimum": 1, "maximum": 65535 }
}
},
"serviceAccount": {
"type": "object",
"additionalProperties": false,
"properties": {
"create": { "type": "boolean" },
"name": { "type": "string" },
"annotations": { "type": "object" }
}
},
"podDisruptionBudget": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"minAvailable": { "oneOf": [{ "type": "integer" }, { "type": "string" }] },
"maxUnavailable": { "oneOf": [{ "type": "integer" }, { "type": "string" }] }
}
},
"ingress": {
"type": "object",
"additionalProperties": true,
"properties": {
"enabled": { "type": "boolean" },
"className": { "type": "string" },
"annotations": { "type": "object" },
"hosts": { "type": "array" },
"tls": { "type": "array" }
}
},
"httproute": {
"type": "object",
"additionalProperties": true,
"properties": {
"enabled": { "type": "boolean" },
"parentRefs": { "type": "array" },
"hostnames": { "type": "array", "items": { "type": "string" } },
"rules": { "type": "array" }
}
},
"persistence": {
"type": "object",
"additionalProperties": false,
"properties": {
"git": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"mountPath": { "type": "string", "minLength": 1 },
"storageClass": { "type": "string" },
"accessMode": { "type": "string", "enum": ["ReadWriteOnce", "ReadWriteMany", "ReadOnlyMany", "ReadWriteOncePod"] },
"size": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)?$" },
"annotations": { "type": "object" },
"existingClaim": { "type": "string" }
}
}
}
},
"postgresql": {
"type": "object",
"additionalProperties": true,
"properties": { "enabled": { "type": "boolean" } }
},
"externalPostgresql": {
"type": "object",
"additionalProperties": false,
"properties": {
"url": { "type": "string", "pattern": "^(postgres(ql)?://.+)?$" }
}
},
"redis": {
"type": "object",
"additionalProperties": true,
"properties": { "enabled": { "type": "boolean" } }
},
"externalRedis": {
"type": "object",
"additionalProperties": false,
"properties": {
"url": { "type": "string", "pattern": "^(rediss?://.+)?$" }
}
},
"s3": {
"type": "object",
"additionalProperties": false,
"properties": {
"endpoint": { "type": "string", "pattern": "^(https?://.+)?$" },
"bucket": { "type": "string", "minLength": 1 },
"region": {
"type": "string",
"minLength": 1,
"description": "S3 region used for SigV4 signing by the relay and deletion operator. Defaults to us-east-1 for bundled MinIO/local deployments; set the provider region explicitly when it differs."
},
"addressingStyle": {
"type": "string",
"enum": ["path", "virtual"],
"description": "S3 URL style shared by media and Git/CAS clients. Defaults to path for bundled MinIO compatibility."
},
"accessKey": { "type": "string" },
"secretKey": { "type": "string" }
}
},
"storageAccounting": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"schedule": { "type": "string", "minLength": 1 },
"maxObjects": { "type": "integer", "minimum": 1 },
"activeDeadlineSeconds": { "type": "integer", "minimum": 1 },
"successfulJobsHistoryLimit": { "type": "integer", "minimum": 0 },
"failedJobsHistoryLimit": { "type": "integer", "minimum": 0 },
"relayMode": { "type": "string", "enum": ["inline", "external", "off"] },
"serviceAccountName": { "type": "string" },
"podLabels": {
"type": "object",
"description": "Extra Pod labels. The chart owns tags.datadoghq.com/version and derives it from the deployed image identity, so a value supplied here for that one key is ignored."
},
"podAnnotations": { "type": "object" },
"resources": { "type": "object" }
}
},
"operatorJobs": {
"type": "object",
"additionalProperties": false,
"properties": {
"deletionDrain": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"schedule": { "type": "string", "minLength": 1 },
"activeDeadlineSeconds": { "type": "integer", "minimum": 1, "maximum": 86400 },
"successfulJobsHistoryLimit": { "type": "integer", "minimum": 0, "maximum": 10 },
"failedJobsHistoryLimit": { "type": "integer", "minimum": 0, "maximum": 10 },
"terminationGracePeriodSeconds": { "type": "integer", "minimum": 1, "maximum": 300 },
"serviceAccountName": { "type": "string" },
"podLabels": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"podAnnotations": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"resources": { "type": "object" }
}
}
}
},
"minio": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"image": { "type": "string", "minLength": 1 },
"mcImage": { "type": "string", "minLength": 1 },
"persistence": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"size": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)?$" }
}
}
}
},
"git": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxPackBytes": { "type": "integer", "minimum": 1 },
"packCachePath": { "type": "string", "minLength": 1 },
"packCacheMaxBytes": { "type": "integer", "minimum": 0 },
"packCacheMaxConcurrentPopulations": { "type": "integer", "minimum": 1 },
"packCacheVolumeSize": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)?$" },
"maxReposPerPubkey": { "type": "integer", "minimum": 1 },
"maxConcurrentOps": { "type": "integer", "minimum": 1 }
}
},
"migrate": {
"type": "object",
"additionalProperties": false,
"properties": {
"autoMigrate": { "type": "boolean" },
"preUpgradeJob": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"resources": { "type": "object" },
"backoffLimit": { "type": "integer", "minimum": 0 },
"activeDeadlineSeconds": { "type": "integer", "minimum": 1 }
}
}
}
},
"serviceMonitor": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"namespace": { "type": "string" },
"interval": { "type": "string" },
"scrapeTimeout": { "type": "string" },
"labels": { "type": "object" }
}
},
"pairingRelay": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"url": {
"type": "string",
"pattern": "^(wss?://.+)?$",
"description": "Public WebSocket URL advertised to clients for NIP-AB device pairing."
},
"replicaCount": { "type": "integer", "minimum": 1 },
"service": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": { "type": "string", "enum": ["ClusterIP", "NodePort", "LoadBalancer"] },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"annotations": { "type": "object" }
}
},
"podAnnotations": { "type": "object" },
"podLabels": { "type": "object" },
"resources": { "type": "object" }
}
},
"extraManifests": {
"type": "array"
}
}
}