From 377306b41897d4f1e168f740e6b2bfd358f3c717 Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Fri, 4 Sep 2026 13:28:54 +0200 Subject: [PATCH] feat(deployment)!: move security contexts into the `deployment` dict `podSecurityContext` and `containerSecurityContext` are both Deployment-scoped: the former is rendered into `spec.template.spec.securityContext`, the latter into the securityContext of the Gitea container and the chart-managed init containers. Keeping them at the top level hid that pod/container distinction behind a naming convention and separated them from the other pod- and container-scoped settings that already live under `deployment` and `deployment.gitea`. `podSecurityContext` therefore becomes `deployment.securityContext` and `containerSecurityContext` becomes `deployment.gitea.securityContext`, which makes the scope obvious from the values path alone and continues the consolidation started with `deployment.gitea.env`, `deployment.gitea.resources` and `deployment.gitea.image`. The template helpers keep their argument-based signatures, because `gitea.containerSecurityContext` is also used by the Helm test pod and is not bound to a single values path. Both removed keys are covered by the deprecation check so that a silently dropped security context cannot lead to containers unexpectedly running as root or without the configured capability set. BREAKING CHANGE: `podSecurityContext` and `containerSecurityContext` no longer exist. Use `deployment.securityContext` and `deployment.gitea.securityContext` instead. Installations that still set the old keys will fail to render unless `checkDeprecation` is set to `false`. Co-authored-by: Copilot --- README.md | 16 +++---- templates/_helpers.tpl | 14 +++--- templates/gitea/deployment.yaml | 10 ++--- templates/gitea/deprecation.yaml | 10 +++++ unittests/helm/deployment/deprecations.yaml | 18 ++++++++ unittests/helm/deployment/openshift.yaml | 12 +++--- values.yaml | 48 ++++++++++----------- 7 files changed, 79 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 13fb80d..fe583d8 100644 --- a/README.md +++ b/README.md @@ -1014,11 +1014,13 @@ To comply with the Gitea helm chart definition of the digest parameter, a "custo | `deployment.gitea.image.rootless` | Wether or not to pull the rootless version of Gitea, only works on Gitea 1.14.x or higher | `true` | | `deployment.gitea.image.fullOverride` | Completely overrides the image registry, path/image, tag and digest. **Adjust `deployment.gitea.image.rootless` accordingly and review [Rootless defaults](#rootless-defaults).** | `""` | | `deployment.gitea.resources` | Compute Resources required by Gitea container. Cannot be updated. | `nil` | +| `deployment.gitea.securityContext` | Security context of the Gitea container and the chart-managed init containers. | `{}` | | `deployment.nodeSelector` | NodeSelector for the deployment | `{}` | | `deployment.priorityClassName` | priorityClassName for the deployment | `""` | | `deployment.replicas` | Number of replicas for the Gitea deployment. | `1` | | `deployment.resources` | Resources is the total amount of CPU and Memory resources required by all containers in the pod. | `{}` | | `deployment.schedulerName` | Use an alternate scheduler, e.g. "stork" | `""` | +| `deployment.securityContext` | Pod security context. On non-OpenShift clusters the chart defaults `fsGroup` to `1000` when this map is empty. | `{}` | | `deployment.strategy.type` | Deployment strategy used to replace old pods, either `RollingUpdate` or `Recreate`. | `RollingUpdate` | | `deployment.strategy.rollingUpdate.maxSurge` | Number or percentage of pods that may be created above the desired replica count. Only used with `RollingUpdate`. | `100%` | | `deployment.strategy.rollingUpdate.maxUnavailable` | Number or percentage of pods that may be unavailable during the update. Only used with `RollingUpdate`. | `0` | @@ -1083,14 +1085,12 @@ To comply with the Gitea helm chart definition of the digest parameter, a "custo ### Security -| Name | Description | Value | -| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----- | -| `openshift.enabled` | Enable OpenShift compatibility defaults for chart-managed pods. Defaults to auto-detect based on the SecurityContextConstraints API. | `nil` | -| `openshift.hostUsers` | Override the PodSpec hostUsers field for chart-managed pods. When unset, the field is omitted so the platform default is used. | `nil` | -| `podSecurityContext` | Pod security context. On non-OpenShift clusters the chart defaults `fsGroup` to `1000` when this map is empty. | `{}` | -| `containerSecurityContext` | Security context | `{}` | -| `securityContext` | Run init and Gitea containers as a specific securityContext | `{}` | -| `podDisruptionBudget` | Pod disruption budget | `{}` | +| Name | Description | Value | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----- | +| `openshift.enabled` | Enable OpenShift compatibility defaults for chart-managed pods. Defaults to auto-detect based on the SecurityContextConstraints API. | `nil` | +| `openshift.hostUsers` | Override the PodSpec hostUsers field for chart-managed pods. When unset, the field is omitted so the platform default is used. | `nil` | +| `securityContext` | Run init and Gitea containers as a specific securityContext | `{}` | +| `podDisruptionBudget` | Pod disruption budget | `{}` | ### Route diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 7cec3ce..7a7b627 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -104,13 +104,13 @@ Return the pod's hostUsers setting when OpenShift compatibility is enabled. {{/* Render pod securityContext. On non-OpenShift clusters an empty map defaults fsGroup to 1000. */}} -{{- define "gitea.podSecurityContext" -}} -{{- $podSecurityContext := deepCopy .Values.podSecurityContext -}} -{{- if and (ne (include "gitea.openshift.enabled" . | trim) "true") (not (hasKey $podSecurityContext "fsGroup")) -}} -{{- $_ := set $podSecurityContext "fsGroup" 1000 -}} +{{- define "gitea.deployment.securityContext" -}} +{{- $securityContext := deepCopy .Values.deployment.securityContext -}} +{{- if and (ne (include "gitea.openshift.enabled" . | trim) "true") (not (hasKey $securityContext "fsGroup")) -}} +{{- $_ := set $securityContext "fsGroup" 1000 -}} {{- end -}} -{{- if gt (len $podSecurityContext) 0 -}} -{{ toYaml $podSecurityContext }} +{{- if gt (len $securityContext) 0 -}} +{{ toYaml $securityContext }} {{- end -}} {{- end -}} @@ -150,7 +150,7 @@ These default to runAsUser 1000 outside OpenShift to preserve existing behavior. Render the runtime container securityContext while honoring the deprecated securityContext value. */}} {{- define "gitea.runtimeContainerSecurityContext" -}} -{{- $containerSecurityContext := deepCopy .Values.containerSecurityContext -}} +{{- $containerSecurityContext := deepCopy .Values.deployment.gitea.securityContext -}} {{- if and (eq (len $containerSecurityContext) 0) .Values.securityContext -}} {{- $containerSecurityContext = deepCopy .Values.securityContext -}} {{- end -}} diff --git a/templates/gitea/deployment.yaml b/templates/gitea/deployment.yaml index cb5560a..6753937 100644 --- a/templates/gitea/deployment.yaml +++ b/templates/gitea/deployment.yaml @@ -62,9 +62,9 @@ spec: {{- 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 }} + {{- $securityContext := include "gitea.deployment.securityContext" . | trim }} + {{- $containerSecurityContext := include "gitea.containerSecurityContext" (list . (deepCopy .Values.deployment.gitea.securityContext)) | trim }} + {{- $commandInitContainerSecurityContext := include "gitea.commandInitContainerSecurityContext" (list . (deepCopy .Values.deployment.gitea.securityContext)) | trim }} {{- $runtimeContainerSecurityContext := include "gitea.runtimeContainerSecurityContext" . | trim }} {{- if .Values.deployment.schedulerName }} schedulerName: "{{ .Values.deployment.schedulerName }}" @@ -79,9 +79,9 @@ spec: hostUsers: {{ $hostUsers }} {{- end }} {{- include "gitea.images.pullSecrets" . | nindent 6 }} - {{- if $podSecurityContext }} + {{- if $securityContext }} securityContext: - {{- $podSecurityContext | nindent 8 }} + {{- $securityContext | nindent 8 }} {{- end }} initContainers: {{- if .Values.preExtraInitContainers }} diff --git a/templates/gitea/deprecation.yaml b/templates/gitea/deprecation.yaml index d725556..aeece41 100644 --- a/templates/gitea/deprecation.yaml +++ b/templates/gitea/deprecation.yaml @@ -45,6 +45,11 @@ {{- fail "`affinity` does no longer exist. Please refer to the changelog and configure `deployment.affinity` instead." -}} {{- end -}} + {{/* CONTAINER SECURITY CONTEXT */}} + {{- if .Values.containerSecurityContext -}} + {{- fail "`containerSecurityContext` does no longer exist. Please refer to the changelog and configure `deployment.gitea.securityContext` instead." -}} + {{- end -}} + {{/* DEPLOYMENT ENV */}} {{- if .Values.deployment.env -}} {{- fail "`deployment.env` does no longer exist. Please refer to the changelog and configure `deployment.gitea.env` instead." -}} @@ -65,6 +70,11 @@ {{- fail "`priorityClassName` does no longer exist. Please refer to the changelog and configure `deployment.priorityClassName` instead." -}} {{- end -}} + {{/* POD SECURITY CONTEXT */}} + {{- if .Values.podSecurityContext -}} + {{- fail "`podSecurityContext` does no longer exist. Please refer to the changelog and configure `deployment.securityContext` instead." -}} + {{- end -}} + {{/* RESOURCES */}} {{- if .Values.resources -}} {{- fail "`resources` does no longer exist. Please refer to the changelog and configure `deployment.gitea.resources` instead." -}} diff --git a/unittests/helm/deployment/deprecations.yaml b/unittests/helm/deployment/deprecations.yaml index d993f05..528cdad 100644 --- a/unittests/helm/deployment/deprecations.yaml +++ b/unittests/helm/deployment/deprecations.yaml @@ -23,6 +23,13 @@ tests: asserts: - failedTemplate: errorMessage: "`affinity` does no longer exist. Please refer to the changelog and configure `deployment.affinity` instead." + - it: fails when the removed `containerSecurityContext` value is set + set: + containerSecurityContext: + runAsUser: 1000 + asserts: + - failedTemplate: + errorMessage: "`containerSecurityContext` does no longer exist. Please refer to the changelog and configure `deployment.gitea.securityContext` instead." - it: fails when the removed `deployment.env` value is set set: deployment.env: @@ -52,6 +59,13 @@ tests: asserts: - failedTemplate: errorMessage: "`priorityClassName` does no longer exist. Please refer to the changelog and configure `deployment.priorityClassName` instead." + - it: fails when the removed `podSecurityContext` value is set + set: + podSecurityContext: + fsGroup: 1000 + asserts: + - failedTemplate: + errorMessage: "`podSecurityContext` does no longer exist. Please refer to the changelog and configure `deployment.securityContext` instead." - it: fails when the removed `resources` value is set set: resources: @@ -101,6 +115,8 @@ tests: checkDeprecation: false affinity: nodeAffinity: {} + containerSecurityContext: + runAsUser: 1000 deployment.env: - name: VARIABLE value: my-value @@ -109,6 +125,8 @@ tests: - 192.0.2.1 nodeSelector: foo: bar + podSecurityContext: + fsGroup: 1000 priorityClassName: high-priority replicaCount: 2 resources: diff --git a/unittests/helm/deployment/openshift.yaml b/unittests/helm/deployment/openshift.yaml index 8c5f84d..c39b9f9 100644 --- a/unittests/helm/deployment/openshift.yaml +++ b/unittests/helm/deployment/openshift.yaml @@ -80,11 +80,13 @@ tests: openshift: enabled: true hostUsers: true - podSecurityContext: - fsGroup: 1000620000 - containerSecurityContext: - runAsUser: 1000620000 - runAsGroup: 1000620000 + deployment: + securityContext: + fsGroup: 1000620000 + gitea: + securityContext: + runAsUser: 1000620000 + runAsGroup: 1000620000 asserts: - equal: path: spec.template.spec.hostUsers diff --git a/values.yaml b/values.yaml index fa15835..e0f75b8 100644 --- a/values.yaml +++ b/values.yaml @@ -101,6 +101,25 @@ deployment: # cpu: 100m # memory: 128Mi + ## @param deployment.gitea.securityContext Security context of the Gitea container and the chart-managed init containers. + securityContext: {} + # allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + # # Add the SYS_CHROOT capability for root and rootless images if you intend to + # # run pods on nodes that use the container runtime cri-o. Otherwise, you will + # # get an error message from the SSH server that it is not possible to read from + # # the repository. + # # https://gitea.com/gitea/helm-gitea/issues/161 + # add: + # - SYS_CHROOT + # privileged: false + # readOnlyRootFilesystem: true + # runAsGroup: 1000 + # runAsNonRoot: true + # runAsUser: 1000 + ## @param deployment.nodeSelector NodeSelector for the deployment nodeSelector: {} @@ -126,6 +145,9 @@ deployment: ## @param deployment.schedulerName Use an alternate scheduler, e.g. "stork" schedulerName: "" + ## @param deployment.securityContext Pod security context. On non-OpenShift clusters the chart defaults `fsGroup` to `1000` when this map is empty. + securityContext: {} + ## @param deployment.strategy.type Deployment strategy used to replace old pods, either `RollingUpdate` or `Recreate`. ## @param deployment.strategy.rollingUpdate.maxSurge Number or percentage of pods that may be created above the desired replica count. Only used with `RollingUpdate`. ## @param deployment.strategy.rollingUpdate.maxUnavailable Number or percentage of pods that may be unavailable during the update. Only used with `RollingUpdate`. @@ -281,31 +303,9 @@ openshift: enabled: null hostUsers: null -## @param podSecurityContext Pod security context. On non-OpenShift clusters the chart defaults `fsGroup` to `1000` when this map is empty. -podSecurityContext: {} - -## @param containerSecurityContext Security context -containerSecurityContext: {} -# allowPrivilegeEscalation: false -# capabilities: -# drop: -# - ALL -# # Add the SYS_CHROOT capability for root and rootless images if you intend to -# # run pods on nodes that use the container runtime cri-o. Otherwise, you will -# # get an error message from the SSH server that it is not possible to read from -# # the repository. -# # https://gitea.com/gitea/helm-gitea/issues/161 -# add: -# - SYS_CHROOT -# privileged: false -# readOnlyRootFilesystem: true -# runAsGroup: 1000 -# runAsNonRoot: true -# runAsUser: 1000 - ## @deprecated The securityContext variable has been split two: -## - containerSecurityContext -## - podSecurityContext. +## - deployment.gitea.securityContext +## - deployment.securityContext. ## @param securityContext Run init and Gitea containers as a specific securityContext securityContext: {}