apiVersion: apps/v1 kind: StatefulSet metadata: name: "{{ .Release.Name }}-{{ .Chart.Name }}-sfs" labels: app: "{{ .Release.Name }}-{{ .Chart.Name }}" spec: serviceName: "{{ .Release.Name }}-{{ .Chart.Name }}-service" replicas: {{ include "homeassistant.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.replicas) }} selector: matchLabels: app: "{{ .Release.Name }}-{{ .Chart.Name }}" template: metadata: 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: {{- include "homeassistant.podSecurityContext" .Values.securityContext | nindent 8 }} containers: - name: "{{ .Release.Name }}-{{ .Chart.Name }}" image: "ghcr.io/home-assistant/home-assistant:{{ .Chart.AppVersion }}" imagePullPolicy: IfNotPresent securityContext: {{- include "homeassistant.containerSecurityContext" .Values.securityContext | nindent 12 }} env: - name: TZ value: "{{ .Values.core.timezone }}" {{- range $value := .Values.env }} {{- if $value.value }} - name: {{ $value.name | quote }} value: {{ tpl $value.value $ | quote }} {{- else if $value.valueFrom }} {{- if $value.valueFrom.secretKeyRef }} - name: {{ $value.name }} valueFrom: secretKeyRef: name: {{ tpl $value.valueFrom.secretKeyRef.name $ | quote }} key: {{ tpl $value.valueFrom.secretKeyRef.key $ | quote }} {{- else if $value.valueFrom.configMapKeyRef }} - name: {{ $value.name }} valueFrom: configMapKeyRef: name: {{ tpl $value.valueFrom.configMapKeyRef.name $ | quote }} key: {{ tpl $value.valueFrom.configMapKeyRef.key $ | quote }} {{- end }} {{- end }} {{- end }} ports: - name: http containerPort: 8123 protocol: TCP livenessProbe: {{- include "homeassistant.livenessProbe" .Values.livenessProbe | nindent 12 }} readinessProbe: {{- include "homeassistant.readinessProbe" .Values.readinessProbe | nindent 12 }} startupProbe: {{- include "homeassistant.startupProbe" .Values.startupProbe | nindent 12 }} resources: {{- include "homeassistant.effectiveResources" .Values.resources | nindent 12 }} volumeMounts: - mountPath: /config/configuration.yaml subPath: configuration.yaml name: core-config - mountPath: /config/http-config.yaml subPath: http-config.yaml name: http-config - mountPath: /config/recorder-config.yaml subPath: recorder-config.yaml name: recorder-config - mountPath: /config name: hass-volume subPath: hass-config # Writable emptyDirs so the root filesystem can stay read-only: # s6-overlay needs /run, Home Assistant writes temp files to /tmp. - mountPath: /tmp name: tmp - mountPath: /run name: run volumes: - name: tmp emptyDir: {} - name: run emptyDir: {} - name: core-config secret: secretName: {{ .Release.Name }}-{{ .Chart.Name }}-config-secret items: - key: config path: configuration.yaml - name: http-config secret: secretName: {{ .Release.Name }}-{{ .Chart.Name }}-config-secret items: - key: http-config path: http-config.yaml - name: recorder-config secret: secretName: {{ .Release.Name }}-{{ .Chart.Name }}-config-secret items: - key: recorder-config path: recorder-config.yaml - name: hass-volume persistentVolumeClaim: claimName: {{ .Release.Name }}-{{ .Chart.Name }}-pvc # TODO: bind to local nodes