Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions deploy/charts/buzz/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: |
PostgreSQL and Redis. Configurable for single-node evaluation
(subcharts on) and HA production (external services, existingSecret).
type: application
version: 0.1.6
version: 0.1.7
appVersion: "0.1.0"
home: https://github.com/block/buzz
sources:
Expand All @@ -24,7 +24,7 @@ maintainers:
annotations:
artifacthub.io/changes: |
- kind: added
description: Optional READ_DATABASE_URL env (secretKeyRef) enabling relay read-replica routing; absent key preserves prior behavior.
description: Generic init-container, volume, volume-mount, command, and args extension points for the relay Pod.
artifacthub.io/license: Apache-2.0

# Optional eval-only subcharts. Production deploys disable both and point
Expand Down
51 changes: 51 additions & 0 deletions deploy/charts/buzz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,57 @@ See:

The chart fails at `helm install` / `helm template` time with a clear message if any of these are missing or malformed (see `templates/_validate.tpl`).

## Relay Pod extensions

The chart exposes narrow extension points for init containers, volumes, relay
volume mounts, and image command/argument overrides. `extraManifests` creates
independent Kubernetes resources but cannot modify the chart-managed relay
Deployment. These extension values insert fields into that Deployment, avoiding
duplication of its environment, probes, security context, secrets, and
chart-owned volumes.

For example, an init container can copy a wrapper binary into a shared volume
and make that wrapper the relay entrypoint:

```yaml
extraInitContainers:
- name: install-wrapper
image: example.com/wrapper-init:v1
args: [/opt/wrapper/wrapper]
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
resources:
requests:
cpu: 10m
memory: 16Mi
volumeMounts:
- name: wrapper
mountPath: /opt/wrapper

extraVolumes:
- name: wrapper
emptyDir: {}

relay:
command: [/opt/wrapper/wrapper]
args: [/usr/local/bin/buzz-relay]
extraVolumeMounts:
- name: wrapper
mountPath: /opt/wrapper
```

These values are raw Kubernetes fragments rendered with `toYaml`, not `tpl`.
The chart does not validate cross-field relationships: extension names must not
collide with chart-owned containers or volumes, mounts must reference existing
volumes, and each init container must define an appropriate security context
and resources. Empty `relay.command` and `relay.args` arrays preserve the image
defaults; non-empty values override its entrypoint and arguments respectively.

## Device pairing relay

The chart can run Buzz's stateless pairing WebSocket relay as an independent
Expand Down
21 changes: 20 additions & 1 deletion deploy/charts/buzz/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ spec:
topologySpreadConstraints:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if or .Values.minio.enabled .Values.extraInitContainers }}
initContainers:
{{- if .Values.minio.enabled }}
# Quickstart only: the bundled MinIO bucket is created by a concurrent
# init Job (templates/quickstart-minio-init.yaml). The relay's A3 S3
# conformance probe is startup-fatal, so without this gate the relay Pods
# CrashLoopBackOff (with growing backoff) until the bucket appears. Block
# relay start until the bucket exists — deterministic, no crash-loops.
initContainers:
- name: wait-for-bucket
image: {{ .Values.minio.mcImage | quote }}
securityContext:
Expand Down Expand Up @@ -90,12 +91,24 @@ spec:
done
echo "bucket {{ .Values.s3.bucket }} present"
{{- end }}
{{- with .Values.extraInitContainers }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
containers:
- name: relay
image: {{ include "buzz.image" . }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.relay.containerSecurityContext | nindent 12 }}
{{- with .Values.relay.command }}
command:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.relay.args }}
args:
{{- toYaml . | nindent 12 }}
{{- end }}
ports:
- { name: app, containerPort: 3000, protocol: TCP }
- { name: health, containerPort: {{ .Values.service.healthPort }}, protocol: TCP }
Expand Down Expand Up @@ -225,6 +238,9 @@ spec:
volumeMounts:
- { name: git-repos, mountPath: {{ .Values.persistence.git.mountPath | quote }} }
- { name: git-pack-cache, mountPath: {{ .Values.git.packCachePath | quote }} }
{{- with .Values.relay.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}

volumes:
- name: git-repos
Expand All @@ -238,3 +254,6 @@ spec:
- name: git-pack-cache
emptyDir:
sizeLimit: {{ .Values.git.packCacheVolumeSize | quote }}
{{- with .Values.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
115 changes: 115 additions & 0 deletions deploy/charts/buzz/tests/render_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,118 @@ tests:
- hasDocuments:
count: 0
template: templates/pvc-git.yaml

- it: preserves image defaults when Pod extensions are empty
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: http://minio:9000
s3.accessKey: a
s3.secretKey: s
asserts:
- notExists:
path: spec.template.spec.initContainers
template: templates/deployment.yaml
- notExists:
path: spec.template.spec.containers[0].command
template: templates/deployment.yaml
- notExists:
path: spec.template.spec.containers[0].args
template: templates/deployment.yaml

- it: appends generic Pod extensions and overrides the relay command
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
externalPostgresql.url: postgres://u:p@h:5432/d
externalRedis.url: redis://h:6379
s3.endpoint: http://minio:9000
s3.accessKey: a
s3.secretKey: s
relay.command:
- /opt/wrapper/wrapper
relay.args:
- /usr/local/bin/buzz-relay
relay.extraVolumeMounts:
- name: wrapper
mountPath: /opt/wrapper
extraInitContainers:
- name: install-wrapper
image: example.com/wrapper-init:v1
args:
- /opt/wrapper/wrapper
env:
- name: LITERAL_TEMPLATE
value: '{{ .Release.Name }}'
securityContext:
runAsNonRoot: true
resources:
requests:
cpu: 10m
memory: 16Mi
volumeMounts:
- name: wrapper
mountPath: /opt/wrapper
extraVolumes:
- name: wrapper
emptyDir: {}
asserts:
- equal:
path: spec.template.spec.initContainers[0].name
value: install-wrapper
template: templates/deployment.yaml
- equal:
path: spec.template.spec.initContainers[0].securityContext.runAsNonRoot
value: true
template: templates/deployment.yaml
# Extension fragments are deliberately rendered with toYaml, not tpl.
- equal:
path: spec.template.spec.initContainers[0].env[0].value
value: '{{ .Release.Name }}'
template: templates/deployment.yaml
- equal:
path: spec.template.spec.containers[0].command
value:
- /opt/wrapper/wrapper
template: templates/deployment.yaml
- equal:
path: spec.template.spec.containers[0].args
value:
- /usr/local/bin/buzz-relay
template: templates/deployment.yaml
- contains:
path: spec.template.spec.containers[0].volumeMounts
content:
name: wrapper
mountPath: /opt/wrapper
template: templates/deployment.yaml
- contains:
path: spec.template.spec.volumes
content:
name: wrapper
emptyDir: {}
template: templates/deployment.yaml

- it: appends generic init containers after the bundled MinIO readiness gate
release:
name: rel
set:
relayUrl: wss://buzz.example.com
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
postgresql.enabled: true
redis.enabled: true
minio.enabled: true
extraInitContainers:
- name: install-wrapper
image: example.com/wrapper-init:v1
asserts:
- equal:
path: spec.template.spec.initContainers[0].name
value: wait-for-bucket
template: templates/deployment.yaml
- equal:
path: spec.template.spec.initContainers[1].name
value: install-wrapper
template: templates/deployment.yaml
27 changes: 26 additions & 1 deletion deploy/charts/buzz/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,34 @@
"type": "array",
"items": { "type": "string" }
},
"ephemeralTtlOverride": { "type": "integer", "minimum": 0 }
"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,
Expand Down
15 changes: 15 additions & 0 deletions deploy/charts/buzz/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,24 @@ relay:
readOnlyRootFilesystem: false # git writes need a writable repo path
terminationGracePeriodSeconds: 60

# Optional image entrypoint/arguments overrides. Empty arrays preserve the
# relay image's defaults. Consumers own compatibility with the selected image.
command: []
args: []
# Appended to the chart-owned relay mounts. Names must match extraVolumes (or
# another volume supplied by the platform) and must not collide with built-ins.
extraVolumeMounts: []

extraEnv: []
extraEnvFrom: []

# ── Pod extensions ──────────────────────────────────────────────────────────
# Raw Kubernetes fragments appended to the relay Pod. They are rendered with
# toYaml, not tpl. Init containers must define their own securityContext and
# resources; names must not collide with chart-owned containers or volumes.
extraInitContainers: []
extraVolumes: []

# ── Device pairing relay ─────────────────────────────────────────────────────
# Optional, stateless NIP-AB relay. When enabled, the main relay advertises
# pairingRelay.url in NIP-11 and Buzz clients use it instead of the legacy
Expand Down
Loading