Files
helm-gitea/templates/gitea/deployment.yaml
T
volker.raschekandCopilot 3535611d4d feat(secrets)!: replace the signing object with secrets.gpg
The `signing` object was the last Secret-related configuration living outside of the `secrets` section introduced in the
previous commit. Keeping it separate meant that the GPG key Secret was the only one without configurable annotations,
labels and a proper `existingSecret` reference, and users had to learn two different conventions for the same concept.

`signing` is therefore removed and fully replaced by `secrets.gpg`:

  signing.enabled        -> secrets.gpg.enabled
  signing.gpgHome        -> secrets.gpg.new.gpgHome
  signing.privateKey     -> secrets.gpg.new.privateKey
  signing.existingSecret -> secrets.gpg.existingSecret.{enabled,secretName}

`gpgHome` is now stored as a key inside the GPG key Secret and consumed via `secretKeyRef` instead of being rendered as
a plain environment variable value. This keeps the whole GPG configuration in a single object, so an operator can hand
over one Secret that fully describes the signing setup instead of splitting it across values and Secret data. The key
names of an externally provided Secret are configurable via `secrets.gpg.existingSecret.gpgHomeKey` and
`secrets.gpg.existingSecret.privateKeyKey`, because chart-defined key names cannot be assumed for Secrets that are
managed by an external system such as an operator or a secret store.

To avoid silently ignoring a now unknown value, `deprecation.yaml` fails the render when `signing` is still set and
points to `secrets.gpg`. As with the other deprecation guards it can be bypassed via `checkDeprecation: false`.

The unit tests are migrated accordingly and the `GNUPGHOME` assertions now verify the `secretKeyRef` shape. Two new
cases cover custom `gpgHomeKey` and `privateKeyKey` values of an existing Secret.

The README gains a `To 13.0.0` upgrade section documenting this change together with the `secrets.*` block and the
Secret renames of the preceding commits.

BREAKING CHANGE: The `signing` object has been removed and is replaced by `secrets.gpg`. Rendering fails if `signing`
is still set. Secrets referenced via `secrets.gpg.existingSecret` now additionally require a `gpgHome` key next to
`privateKey`.

Co-authored-by: Copilot <copilot@github.com>
2026-09-03 17:36:33 +02:00

482 lines
20 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "gitea.fullname" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
annotations:
{{- if .Values.deployment.annotations }}
{{- toYaml .Values.deployment.annotations | nindent 4 }}
{{- end }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
{{- if .Values.deployment.labels }}
{{- toYaml .Values.deployment.labels | nindent 4 }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount }}
strategy:
type: {{ .Values.strategy.type }}
{{- if eq .Values.strategy.type "RollingUpdate" }}
rollingUpdate:
maxUnavailable: {{ .Values.strategy.rollingUpdate.maxUnavailable }}
maxSurge: {{ .Values.strategy.rollingUpdate.maxSurge }}
{{- end }}
selector:
matchLabels:
{{- include "gitea.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
{{- if and .Values.secrets.config.addSHASumAnnotation (not .Values.secrets.config.existingSecret.enabled) }}
checksum/config: {{ include (print $.Template.BasePath "/gitea/secret_config.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.gpg.addSHASumAnnotation (not .Values.secrets.gpg.existingSecret.enabled) }}
checksum/gpg: {{ include (print $.Template.BasePath "/gitea/secret_gpg.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.init.addSHASumAnnotation (not .Values.secrets.init.existingSecret.enabled) }}
checksum/init: {{ include (print $.Template.BasePath "/gitea/secret_init.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.inlineConfig.addSHASumAnnotation (not .Values.secrets.inlineConfig.existingSecret.enabled) }}
checksum/inlineConfig: {{ include (print $.Template.BasePath "/gitea/secret_inlineConfig.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.metrics.addSHASumAnnotation (not .Values.secrets.metrics.existingSecret.enabled) }}
checksum/metrics: {{ include (print $.Template.BasePath "/gitea/secret_metrics.yaml") . | sha256sum }}
{{- end }}
{{- range $idx, $value := .Values.gitea.ldap }}
checksum/ldap_{{ $idx }}: {{ include "gitea.ldap_settings" (list $idx $value) | sha256sum }}
{{- end }}
{{- range $idx, $value := .Values.gitea.oauth }}
checksum/oauth_{{ $idx }}: {{ include "gitea.oauth_settings" (list $idx $value) | sha256sum }}
{{- end }}
{{- with .Values.gitea.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "gitea.labels" . | nindent 8 }}
{{- if .Values.deployment.labels }}
{{- toYaml .Values.deployment.labels | nindent 8 }}
{{- end }}
spec:
{{- $hostUsers := include "gitea.hostUsers" . | trim }}
{{- $podSecurityContext := include "gitea.podSecurityContext" . | trim }}
{{- $containerSecurityContext := include "gitea.containerSecurityContext" (list . (deepCopy .Values.containerSecurityContext)) | trim }}
{{- $commandInitContainerSecurityContext := include "gitea.commandInitContainerSecurityContext" (list . (deepCopy .Values.containerSecurityContext)) | trim }}
{{- $runtimeContainerSecurityContext := include "gitea.runtimeContainerSecurityContext" . | trim }}
{{- if .Values.schedulerName }}
schedulerName: "{{ .Values.schedulerName }}"
{{- end }}
{{- if (or .Values.serviceAccount.create .Values.serviceAccount.name) }}
serviceAccountName: {{ include "gitea.serviceAccountName" . }}
{{- end }}
{{- if .Values.priorityClassName }}
priorityClassName: "{{ .Values.priorityClassName }}"
{{- end }}
{{- if $hostUsers }}
hostUsers: {{ $hostUsers }}
{{- end }}
{{- include "gitea.images.pullSecrets" . | nindent 6 }}
{{- if $podSecurityContext }}
securityContext:
{{- $podSecurityContext | nindent 8 }}
{{- end }}
initContainers:
{{- if .Values.preExtraInitContainers }}
{{- toYaml .Values.preExtraInitContainers | nindent 8 }}
{{- end }}
- name: init-directories
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/init_directory_structure.sh"
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}
{{- if .Values.secrets.gpg.enabled }}
- name: GNUPGHOME
valueFrom:
secretKeyRef:
name: {{ include "gitea.secret.gpg.name" . }}
key: {{ include "gitea.secret.gpg.gpgHomeKey" . }}
{{- end }}
volumeMounts:
- name: init
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- include "gitea.init-additional-mounts" . | nindent 12 }}
{{- if $containerSecurityContext }}
securityContext:
{{- $containerSecurityContext | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
- name: init-app-ini
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.gitea.extraEnvSourceFile }}
command:
- "/bin/bash"
- "-c"
args:
- "test -f {{ .Values.gitea.extraEnvSourceFile }} && source {{ .Values.gitea.extraEnvSourceFile }} || { echo 'ERROR: Failed to source {{ .Values.gitea.extraEnvSourceFile }}'; exit 1; } && {{ .Values.initContainersScriptsVolumeMountPath }}/config_environment.sh"
{{- else }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/config_environment.sh"
{{- end }}
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
- name: TMP_EXISTING_ENVS_FILE
value: /tmp/existing-envs
- name: ENV_TO_INI_MOUNT_POINT
value: /env-to-ini-mounts
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}
{{- if .Values.gitea.additionalConfigFromEnvs }}
{{- tpl (toYaml .Values.gitea.additionalConfigFromEnvs) $ | nindent 12 }}
{{- end }}
volumeMounts:
- name: config
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: inline-config-sources
mountPath: /env-to-ini-mounts/inlines/
{{- range $idx, $value := .Values.gitea.additionalConfigSources }}
- name: additional-config-sources-{{ $idx }}
mountPath: "/env-to-ini-mounts/additionals/{{ $idx }}/"
{{- end }}
{{- include "gitea.init-additional-mounts" . | nindent 12 }}
{{- if $containerSecurityContext }}
securityContext:
{{- $containerSecurityContext | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
{{- if .Values.secrets.gpg.enabled }}
- name: configure-gpg
image: "{{ include "gitea.image" . }}"
{{- if .Values.gitea.extraEnvSourceFile }}
command:
- "/bin/bash"
- "-c"
args:
- "test -f {{ .Values.gitea.extraEnvSourceFile }} && source {{ .Values.gitea.extraEnvSourceFile }} || { echo 'ERROR: Failed to source {{ .Values.gitea.extraEnvSourceFile }}'; exit 1; } && {{ .Values.initContainersScriptsVolumeMountPath }}/configure_gpg_environment.sh"
{{- else }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/configure_gpg_environment.sh"
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if $commandInitContainerSecurityContext }}
securityContext:
{{- $commandInitContainerSecurityContext | nindent 12 }}
{{- end }}
env:
- name: GNUPGHOME
valueFrom:
secretKeyRef:
name: {{ include "gitea.secret.gpg.name" . }}
key: {{ include "gitea.secret.gpg.gpgHomeKey" . }}
- name: TMP_RAW_GPG_KEY
value: /raw/private.asc
volumeMounts:
- name: init
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: gpg-private-key
mountPath: /raw
readOnly: true
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
{{- end }}
- name: configure-gitea
image: "{{ include "gitea.image" . }}"
{{- if .Values.gitea.extraEnvSourceFile }}
command:
- "/bin/bash"
- "-c"
args:
- "test -f {{ .Values.gitea.extraEnvSourceFile }} && source {{ .Values.gitea.extraEnvSourceFile }} || { echo 'ERROR: Failed to source {{ .Values.gitea.extraEnvSourceFile }}'; exit 1; } && {{ .Values.initContainersScriptsVolumeMountPath }}/configure_gitea.sh"
{{- else }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/configure_gitea.sh"
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if $commandInitContainerSecurityContext }}
securityContext:
{{- $commandInitContainerSecurityContext | nindent 12 }}
{{- end }}
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- if .Values.image.rootless }}
- name: HOME
value: /data/gitea/git
{{- end }}
{{- if .Values.gitea.ldap }}
{{- range $idx, $value := .Values.gitea.ldap }}
{{- if $value.existingSecret }}
- name: GITEA_LDAP_BIND_DN_{{ $idx }}
valueFrom:
secretKeyRef:
key: bindDn
name: {{ $value.existingSecret }}
- name: GITEA_LDAP_PASSWORD_{{ $idx }}
valueFrom:
secretKeyRef:
key: bindPassword
name: {{ $value.existingSecret }}
{{- else }}
- name: GITEA_LDAP_BIND_DN_{{ $idx }}
value: {{ $value.bindDn | quote }}
- name: GITEA_LDAP_PASSWORD_{{ $idx }}
value: {{ $value.bindPassword | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.gitea.oauth }}
{{- range $idx, $value := .Values.gitea.oauth }}
{{- if $value.existingSecret }}
- name: GITEA_OAUTH_KEY_{{ $idx }}
valueFrom:
secretKeyRef:
key: key
name: {{ $value.existingSecret }}
- name: GITEA_OAUTH_SECRET_{{ $idx }}
valueFrom:
secretKeyRef:
key: secret
name: {{ $value.existingSecret }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.gitea.admin.existingSecret }}
- name: GITEA_ADMIN_USERNAME
valueFrom:
secretKeyRef:
key: username
name: {{ .Values.gitea.admin.existingSecret }}
- name: GITEA_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: {{ .Values.gitea.admin.existingSecret }}
{{- else }}
- name: GITEA_ADMIN_USERNAME
value: {{ .Values.gitea.admin.username | quote }}
- name: GITEA_ADMIN_PASSWORD
value: {{ .Values.gitea.admin.password | quote }}
{{- end }}
- name: GITEA_ADMIN_PASSWORD_MODE
value: {{ include "gitea.admin.passwordMode" $ }}
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}
volumeMounts:
- name: init
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- include "gitea.init-additional-mounts" . | nindent 12 }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
{{- if .Values.postExtraInitContainers }}
{{- toYaml .Values.postExtraInitContainers | nindent 8 }}
{{- end }}
terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }}
containers:
- name: {{ .Chart.Name }}
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
# SSH Port values have to be set here as well for openssh configuration
- name: SSH_LISTEN_PORT
value: {{ .Values.gitea.config.server.SSH_LISTEN_PORT | quote }}
- name: SSH_PORT
value: {{ .Values.gitea.config.server.SSH_PORT | quote }}
{{- if not .Values.image.rootless }}
- name: SSH_LOG_LEVEL
value: {{ .Values.gitea.ssh.logLevel | quote }}
{{- end }}
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- if and (hasKey .Values.resources "limits") (hasKey .Values.resources.limits "cpu") }}
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
divisor: "1"
resource: limits.cpu
{{- end }}
- name: TMPDIR
value: /tmp/gitea
{{- if .Values.image.rootless }}
- name: HOME
value: /data/gitea/git
{{- end }}
{{- if .Values.secrets.gpg.enabled }}
- name: GNUPGHOME
valueFrom:
secretKeyRef:
name: {{ include "gitea.secret.gpg.name" . }}
key: {{ include "gitea.secret.gpg.gpgHomeKey" . }}
{{- end }}
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}
ports:
- name: ssh
containerPort: {{ .Values.gitea.config.server.SSH_LISTEN_PORT }}
{{- if .Values.service.ssh.hostPort }}
hostPort: {{ .Values.service.ssh.hostPort }}
{{- end }}
- name: http
containerPort: {{ .Values.gitea.config.server.HTTP_PORT }}
{{- if .Values.gitea.config.server.ENABLE_PPROF }}
- name: profiler
containerPort: 6060
{{- end }}
{{- if .Values.gitea.livenessProbe.enabled }}
livenessProbe:
{{- include "gitea.deployment.probe" .Values.gitea.livenessProbe | nindent 12 }}
{{- end }}
{{- if .Values.gitea.readinessProbe.enabled }}
readinessProbe:
{{- include "gitea.deployment.probe" .Values.gitea.readinessProbe | nindent 12 }}
{{- end }}
{{- if .Values.gitea.startupProbe.enabled }}
startupProbe:
{{- include "gitea.deployment.probe" .Values.gitea.startupProbe | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if $runtimeContainerSecurityContext }}
securityContext:
{{- $runtimeContainerSecurityContext | nindent 12 }}
{{- end }}
volumeMounts:
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- include "gitea.container-additional-mounts" . | nindent 12 }}
{{- if .Values.extraContainers }}
{{- toYaml .Values.extraContainers | nindent 8 }}
{{- end }}
{{- with .Values.global.hostAliases }}
hostAliases:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.topologySpreadConstraints }}
topologySpreadConstraints:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.dnsConfig }}
dnsConfig:
{{- toYaml .Values.dnsConfig | nindent 8 }}
{{- end }}
volumes:
- name: init
secret:
secretName: {{ include "gitea.secret.init.name" . }}
defaultMode: 110
- name: config
secret:
secretName: {{ include "gitea.secret.config.name" . }}
defaultMode: 110
{{- if gt (len .Values.extraVolumes) 0 }}
{{- toYaml .Values.extraVolumes | nindent 8 }}
{{- end }}
- name: inline-config-sources
secret:
secretName: {{ include "gitea.secret.inlineConfig.name" . }}
{{- range $idx, $value := .Values.gitea.additionalConfigSources }}
- name: additional-config-sources-{{ $idx }}
{{- toYaml $value | nindent 10 }}
{{- end }}
- name: temp
emptyDir: {}
{{- if .Values.secrets.gpg.enabled }}
- name: gpg-private-key
secret:
secretName: {{ include "gitea.secret.gpg.name" . }}
items:
- key: {{ include "gitea.secret.gpg.privateKeyKey" . }}
path: private.asc
defaultMode: 0100
{{- end }}
{{- if .Values.persistence.enabled }}
{{- if .Values.persistence.mount }}
- name: data
persistentVolumeClaim:
claimName: {{ .Values.persistence.claimName }}
{{- end }}
{{- else if not .Values.persistence.enabled }}
- name: data
emptyDir: {}
{{- end }}