Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/helm-verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ jobs:
- name: Install helm-unittest
run: .github/scripts/helm-verify/install-helm-unittest.sh
- name: Run the chart unit tests
run: helm unittest charts/substrate
run: helm unittest charts/substrate charts/substrate-podcert charts/substrate-atelet
7 changes: 5 additions & 2 deletions charts/substrate-atelet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ Use the credentials from the substrate release's `rustfs.accessKey` and

This chart reads the same value paths as the substrate chart for `atelet`,
`objectStorePlugin.node`, `objectStorePlugin.extraEnv`, `preview`, `otel`,
`image`, `imagePullSecrets` and `global`, so the substrate release's values
file can configure both releases.
`image`, `imagePullSecrets`, `podLabels` and `global`, so the substrate release's
values file can configure both releases.

`podLabels` defaults to `{}` and adds labels to the atelet pod template.
It cannot set `app`, which is reserved for the DaemonSet selector.

Object storage is set under `objectStore` instead of `rustfs` and
`atelet.storageBackend`:
Expand Down
10 changes: 10 additions & 0 deletions charts/substrate-atelet/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ substrate release references.
{{- end -}}
{{- end -}}

{{/* The app label is reserved for the atelet DaemonSet selector. */}}
{{- define "substrate.podLabels" -}}
{{- with .Values.podLabels -}}
{{- if hasKey . "app" -}}
{{- fail "podLabels must not set app: it is the selector label of the atelet DaemonSet" -}}
{{- end -}}
{{- toYaml . -}}
{{- end -}}
{{- end -}}

{{/* OTLP endpoint a signal exports to. Copied from the substrate chart. */}}
{{- define "substrate.otel.signalEndpoint" -}}
{{- $signal := index . 0 -}}
Expand Down
1 change: 1 addition & 0 deletions charts/substrate-atelet/templates/atelet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ spec:
metadata:
labels:
app: atelet
{{- with include "substrate.podLabels" . }}{{- . | nindent 8 }}{{- end }}
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
Expand Down
59 changes: 59 additions & 0 deletions charts/substrate-atelet/tests/pod_labels_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright 2026 The Agent Substrate Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

suite: Pod labels
templates:
- atelet.yaml
tests:
- it: keeps only the app label on the atelet pod by default
documentSelector:
path: kind
value: DaemonSet
asserts:
- equal:
path: spec.template.metadata.labels
value:
app: atelet

- it: adds podLabels without changing the DaemonSet selector or labels
set:
podLabels:
example.com/tenant: team-a
example.com/tier: node
documentSelector:
path: kind
value: DaemonSet
asserts:
- equal:
path: spec.template.metadata.labels
value:
app: atelet
example.com/tenant: team-a
example.com/tier: node
- equal:
path: spec.selector.matchLabels
value:
app: atelet
- equal:
path: metadata.labels
value:
app: atelet

- it: refuses a podLabels entry that replaces the app selector label
set:
podLabels:
app: other
asserts:
- failedTemplate:
errorMessage: "podLabels must not set app: it is the selector label of the atelet DaemonSet"
3 changes: 3 additions & 0 deletions charts/substrate-atelet/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ global:
# Pull secrets for every pod this chart renders. Merged with global.imagePullSecrets.
imagePullSecrets: []

# Labels added to the atelet pod alongside its reserved app selector label.
podLabels: {}

image:
# Registry host for the component images, and nothing else. A path inside
# `registry` fails the render.
Expand Down
3 changes: 3 additions & 0 deletions charts/substrate-podcert/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Configure the controller image through `image.registry`, `image.repository`,
and `image.tag`. `global.imageRegistry` overrides the registry, and
`imagePullSecrets` and `global.imagePullSecrets` are merged for the controller pod.

`podLabels` adds labels to the controller pod, next to its `app` label, which
they cannot replace.

For an existing installation, the controller resources must be transferred out
of the application release before the new release can own them. Installing this
chart over resources still owned by the application release fails Helm ownership
Expand Down
14 changes: 14 additions & 0 deletions charts/substrate-podcert/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,17 @@ imagePullSecrets:
{{- toYaml $merged | nindent 0 }}
{{- end -}}
{{- end -}}

{{/*
The podLabels entries for the controller's pod template, as YAML map entries.
Renders nothing when podLabels is empty. `app` is the Deployment's selector
label, so a podLabels entry cannot replace it.
*/}}
{{- define "podcert.podLabels" -}}
{{- with .Values.podLabels -}}
{{- if hasKey . "app" -}}
{{- fail "podLabels must not set app: it is the selector label of the controller Deployment" -}}
{{- end -}}
{{- toYaml . -}}
{{- end -}}
{{- end -}}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ spec:
metadata:
labels:
app: podcertificate-controller
{{- with include "podcert.podLabels" . }}{{- . | nindent 8 }}{{- end }}
spec:
{{- with include "podcert.imagePullSecrets" . }}{{- . | nindent 6 }}{{- end }}
containers:
Expand Down
53 changes: 53 additions & 0 deletions charts/substrate-podcert/tests/pod_labels_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2026 The Agent Substrate Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

suite: Pod labels
templates:
- pod-certificate-controller.yaml
tests:
- it: keeps only the app label on the controller pod by default
documentSelector:
path: kind
value: Deployment
asserts:
- equal:
path: spec.template.metadata.labels
value:
app: podcertificate-controller

- it: adds podLabels to the controller pod next to the app label
set:
podLabels:
giantswarm.io/tenant: team-a
documentSelector:
path: kind
value: Deployment
asserts:
- equal:
path: spec.template.metadata.labels
value:
app: podcertificate-controller
giantswarm.io/tenant: team-a
- equal:
path: spec.selector.matchLabels
value:
app: podcertificate-controller

- it: refuses a podLabels entry that replaces the app selector label
set:
podLabels:
app: other
asserts:
- failedTemplate:
errorMessage: "podLabels must not set app: it is the selector label of the controller Deployment"
4 changes: 4 additions & 0 deletions charts/substrate-podcert/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ global:
imageRegistry: ""
imagePullSecrets: []

# Labels added to the controller pod, next to its own `app` label, which they
# cannot replace.
podLabels: {}

imagePullSecrets: []
image:
registry: ghcr.io
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ See `values.yaml` for the full set; the important keys:
| `ateApi.logLevel` | `info` | API server log level in its mounted config; one of `debug`, `info`, `warn`, or `error` |
| `ateApi.authorization.bootstrapOwners` | `[]` | Global owners; empty defaults to the release's shared `ate-client` ServiceAccount |
| `ateApi.extraArgs` | `[]` | Additional command-line arguments appended to the ateapi defaults |
| `podLabels` | `{}` | Labels added to every long-running pod, next to the chart's own `app` label |
| `otel.endpoint` | `""` | Set to an OTLP endpoint to export traces, metrics, the actor lifecycle events and the router access log |
| `otel.traces.enabled` | `true` | Set to `false` to export no traces from the router; the Go components do not honor this yet |
| `otel.traces.endpoint` | `""` | OTLP endpoint for traces, overriding `otel.endpoint` |
Expand Down
14 changes: 14 additions & 0 deletions charts/substrate/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,20 @@ imagePullSecrets:
{{- end -}}
{{- end -}}

{{/*
The podLabels entries for a pod template, as YAML map entries. Renders nothing
when podLabels is empty. The chart's own `app` label is the selector of every
workload, so a podLabels entry cannot replace it.
*/}}
{{- define "substrate.podLabels" -}}
{{- with .Values.podLabels -}}
{{- if hasKey . "app" -}}
{{- fail "podLabels must not set app: it is the selector label of every workload in the chart" -}}
{{- end -}}
{{- toYaml . -}}
{{- end -}}
{{- end -}}

{{/*
imagePullPolicy: global.imagePullPolicy when set, IfNotPresent otherwise. One
definition so the fallback cannot drift between pods.
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/templates/ate-api-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ spec:
metadata:
labels:
app: ate-api-server
{{- with include "substrate.podLabels" $ }}{{- . | nindent 8 }}{{- end }}
annotations:
checksum/api-config: {{ .Values.ateApi.logLevel | sha256sum }}
checksum/api-envvars: {{ include (print $.Template.BasePath "/ate-api-server-envvars.yaml") . | sha256sum }}
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/templates/ate-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ spec:
metadata:
labels:
app: ate-controller
{{- with include "substrate.podLabels" $ }}{{- . | nindent 8 }}{{- end }}
spec:
serviceAccountName: {{ include "substrate.fullname" (list "ate-controller" .) }}
{{- with include "substrate.imagePullSecrets" . }}{{- . | nindent 6 }}{{- end }}
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/templates/atelet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ spec:
metadata:
labels:
app: atelet
{{- with include "substrate.podLabels" $ }}{{- . | nindent 8 }}{{- end }}
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/templates/atenet-egress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ spec:
metadata:
labels:
app: atenet-egress
{{- with include "substrate.podLabels" $ }}{{- . | nindent 8 }}{{- end }}
spec:
serviceAccountName: {{ include "substrate.fullname" (list "atenet-egress" .) }}
securityContext:
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/templates/atenet-router.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ spec:
metadata:
labels:
app: atenet-router
{{- with include "substrate.podLabels" $ }}{{- . | nindent 8 }}{{- end }}
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "15020"
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/templates/k8s-credential-provider.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ spec:
checksum/namespace-policy: {{ toJson .Values.credentialProvider.namespacePolicies | sha256sum }}
labels:
app: {{ include "substrate.fullname" (list "k8s-credential-provider" .) }}
{{- with include "substrate.podLabels" $ }}{{- . | nindent 8 }}{{- end }}
spec:
serviceAccountName: {{ include "substrate.fullname" (list "k8s-credential-provider" .) }}
{{- with include "substrate.imagePullSecrets" . }}{{- . | nindent 6 }}{{- end }}
Expand Down
1 change: 1 addition & 0 deletions charts/substrate/templates/rustfs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ spec:
metadata:
labels:
app: rustfs
{{- with include "substrate.podLabels" $ }}{{- . | nindent 8 }}{{- end }}
spec:
serviceAccountName: {{ include "substrate.fullname" (list "rustfs" .) }}
securityContext:
Expand Down
25 changes: 25 additions & 0 deletions charts/substrate/tests/pod_labels_guard_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2026 The Agent Substrate Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

suite: Pod labels selector guard
templates:
- ate-controller.yaml
tests:
- it: refuses a podLabels entry that replaces the app selector label
set:
podLabels:
app: other
asserts:
- failedTemplate:
errorMessage: "podLabels must not set app: it is the selector label of every workload in the chart"
Loading
Loading