Merge pull request #92 from jk-cluster/feat/checksum-config-homeassistant

homeassistant: Secret-Verweis abdecken, Inhalts-Lücke dokumentieren (#82)
This commit is contained in:
jklein authored and GitHub committed 2026-08-23 17:24:55 +00:00
commit c39c1b080d
4 files changed
+49 -1

No files matched your search

+9
View File
@@ -141,6 +141,15 @@ These guidelines are **binding for every current and future chart** in this repo
- **The annotation is content-based, not time-based**: the hash is taken over the rendered ConfigMap, so an unchanged config renders an identical hash and `helm upgrade` is a no-op. It never degenerates into a restart-on-every-upgrade.
- Adding the annotation to an existing chart is a **major** bump (§2): runtime behavior changes — a config change now costs a restart. Name that cost in the PR (some workloads take minutes to come back).
- **Secrets from `OnePasswordItem` cannot use this mechanism.** Helm never sees their content — the 1Password operator fills the Secret in-cluster after rendering, so there is nothing to hash. A chart that mounts such a Secret as a file documents the limitation in its `values.yaml` where it cannot close the gap.
- **What *can* be covered is the secret's `op://` path**, via a **separately named** `checksum/secret-ref` annotation over the rendered `OnePasswordItem`:
```yaml
checksum/secret-ref: {{ include (print $.Template.BasePath "/<chart>.secret.yaml") . | sha256sum }}
```
Repointing `secrets.<name>SecretRef` at a different vault item then takes effect instead of silently leaving the old credentials in the running pod. The separate name is deliberate: `checksum/config` promises "the config changed", `checksum/secret-ref` only "the config *source* changed" — merging them into one annotation would overstate the weaker guarantee. Reference implementations: `minecraft-server`, `homeassistant`.
- **`operator.1password.io/auto-restart` only works for Deployments — do not set it on a StatefulSet.** Verified against onepassword-operator **1.12.0** (`pkg/onepassword/secret_update_handler.go`): `restartWorkloadsWithUpdatedSecrets` enumerates exactly one workload type, `appsv1.DeploymentList`, and `getPodTemplate` accepts only `*appsv1.Deployment`. The RBAC role grants `statefulsets`, and v1.11.0 generalized the restart code (`restartWorkload`, pod-template stamping via `operator.1password.io/last-restarted`), but the PR that would add StatefulSets is still open — so the annotation on a StatefulSet is a silent no-op. Setting it there is **worse than not setting it**: it advertises a guarantee that does not exist. Affected charts (`matrix-synapse`, `samba`, `homeassistant`) instead document the manual `kubectl rollout restart statefulset <release>-<chart>-sfs`. Re-check this when the operator version is bumped; a Deployment-based chart may set the annotation.
- If a Deployment-based chart ever does set it, mind the precedence: the annotation on the **`OnePasswordItem`** is copied onto the Kubernetes Secret and read first, so a `false` there **overrides** a `true` on the workload — the opposite of what the operator's usage guide suggests. Lookup order is Secret (from the `OnePasswordItem`) → workload → namespace → the operator-global `AUTO_RESTART` env var. The trigger is the 1Password item's **version counter**, not its content, so a re-save with identical values still restarts.
### 10. Environment variables
+1 -1
View File
@@ -4,7 +4,7 @@ description: A Helm chart to deploy Home Assistant on Kubernetes
icon: https://www.home-assistant.io/images/home-assistant-logo.svg
type: application
version: 4.2.0+up2026.8.3
version: 5.0.0+up2026.8.3
appVersion: "2026.8.3"
@@ -15,6 +15,18 @@ spec:
labels:
app: "{{ .Release.Name }}-{{ .Chart.Name }}"
name: "{{ .Release.Name }}-{{ .Chart.Name }}-sfs"
annotations:
# Deliberately NOT a hash of the secret's content: the Kubernetes Secret
# is materialized by the 1Password operator, so Helm never sees what is
# in it. This hash covers the rendered OnePasswordItem, i.e. the op://
# item path - repointing secrets.configSecretRef at a different item now
# takes effect instead of silently leaving the old configuration in the
# running pod. A change of the item's CONTENT inside the vault is not
# covered; see the comment on secrets in values.yaml for why that gap
# cannot be closed here and what it means operationally.
# The name differs from checksum/config on purpose - that one promises
# "the config changed", this one only "the config source changed".
checksum/secret-ref: {{ include (print $.Template.BasePath "/homeassistant-core-config.secret.yaml") . | sha256sum }}
spec:
automountServiceAccountToken: false
securityContext:
+27
View File
@@ -122,5 +122,32 @@ core:
# - config
# - http-config
# - recorder-config
#
# Changing the op:// path below IS covered: the StatefulSet carries a
# checksum/secret-ref annotation over the rendered OnePasswordItem, so pointing
# this value at a different vault item restarts the pod.
#
# Known limitation (#82): changing the CONTENT of that item in the vault does
# NOT restart Home Assistant. The operator updates the Kubernetes Secret, but
# the running pod keeps the old files - they are mounted with subPath, which the
# kubelet never refreshes, and Home Assistant reads its configuration only at
# start. The change then takes effect at some unrelated later restart, possibly
# months afterwards, and a broken value surfaces long after the edit that caused
# it. That is especially likely for this release, which is currently kept at
# zero replicas via scaleDown: whoever brings it back up gets whatever the vault
# holds at that moment.
#
# The checksum/config mechanism the other charts use cannot close this gap:
# Helm never sees the content (the operator fills the Secret in-cluster after
# rendering), so there is nothing to hash. The operator's own
# "operator.1password.io/auto-restart" annotation does not close it either - it
# only ever restarts Deployments, never StatefulSets. Verified against
# onepassword-operator 1.12.0: pkg/onepassword/secret_update_handler.go lists
# exactly one workload type (appsv1.DeploymentList), and the PR adding
# StatefulSets is still open. Setting the annotation here would look like a fix
# and do nothing, so this chart deliberately does not set it.
#
# After changing the item, restart Home Assistant by hand:
# kubectl rollout restart statefulset <release>-homeassistant-sfs
secrets:
configSecretRef: null