From 1f2dc7b7ee42bb61236bc5cb05280e07194e8753 Mon Sep 17 00:00:00 2001 From: Erfan Ghavam Date: Sat, 11 Oct 2025 12:50:30 +0330 Subject: [PATCH 01/14] sidekiq: add antiAffinity overwrite option --- .../charts/sidekiq/templates/deployment.yaml | 20 ++++++++++--------- charts/gitlab/charts/sidekiq/values.yaml | 2 ++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/charts/gitlab/charts/sidekiq/templates/deployment.yaml b/charts/gitlab/charts/sidekiq/templates/deployment.yaml index 3418b74121..404e8e16a4 100644 --- a/charts/gitlab/charts/sidekiq/templates/deployment.yaml +++ b/charts/gitlab/charts/sidekiq/templates/deployment.yaml @@ -20,6 +20,8 @@ {{- $metricsPort := .Values.metrics.port -}} {{- $metricsPath := .Values.metrics.path -}} {{- $healthChecksPort := .Values.health_checks.port -}} +{{- $affinityMode := coalesce $.Values.antiAffinity $.Values.global.antiAffinity .antiAffinity -}} +{{- $topologyKey := coalesce $.Values.affinity.podAntiAffinity.topologyKey $.Values.global.affinity.podAntiAffinity.topologyKey -}} {{- $configMapChecksum := include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} {{- range .Values.pods -}} {{- $queueName := printf "%s-%s" $fullname .name | trunc 63 }} @@ -88,25 +90,25 @@ spec: {{- $priorityClassName := dict "Values" (dict "global" (dict "priorityClassName" $.Values.global.priorityClassName) "priorityClassName" (default $.Values.priorityClassName .priorityClassName)) -}} {{- include "gitlab.priorityClassName" $priorityClassName | nindent 6 }} {{- include "gitlab.podSecurityContext" $.Values.securityContext | nindent 6 }} - {{- if eq (default $.Values.global.antiAffinity .antiAffinity) "hard" }} + {{- if eq $affinityMode "hard" }} affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - - topologyKey: {{ default $.Values.global.affinity.podAntiAffinity.topologyKey $.Values.affinity.podAntiAffinity.topologyKey | quote }} + - topologyKey: {{ $topologyKey | quote }} labelSelector: matchLabels: {{- include "gitlab.selectorLabels" $ | nindent 18 }} queue-pod-name: {{ .name }} - {{- else if eq (default $.Values.global.antiAffinity .antiAffinity) "soft" }} + {{- else if eq $affinityMode "soft" }} affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - podAffinityTerm: - topologyKey: {{ default $.Values.global.affinity.podAntiAffinity.topologyKey $.Values.affinity.podAntiAffinity.topologyKey | quote }} - labelSelector: - matchLabels: - {{- include "gitlab.selectorLabels" $ | nindent 18 }} + - weight: 1 + podAffinityTerm: + topologyKey: {{ $topologyKey | quote }} + labelSelector: + matchLabels: + {{- include "gitlab.selectorLabels" $ | nindent 20 }} {{- end }} {{- if or $.Values.serviceAccount.enabled $.Values.global.serviceAccount.enabled }} serviceAccountName: {{ include "gitlab.serviceAccount.name" $ }} diff --git a/charts/gitlab/charts/sidekiq/values.yaml b/charts/gitlab/charts/sidekiq/values.yaml index c9eba3c6fd..45e371fda7 100644 --- a/charts/gitlab/charts/sidekiq/values.yaml +++ b/charts/gitlab/charts/sidekiq/values.yaml @@ -380,6 +380,8 @@ serviceAccount: # https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" +antiAffinity: "" # options: "hard", "soft" + affinity: podAntiAffinity: topologyKey: -- GitLab From bf9acdb823795c0fec46c537a45a51193836bdc2 Mon Sep 17 00:00:00 2001 From: Erfan Ghavam Date: Sat, 11 Oct 2025 13:00:19 +0330 Subject: [PATCH 02/14] webservice: add antiAffinity overwrite option --- .../gitlab/charts/webservice/templates/deployment.yaml | 10 ++++++---- charts/gitlab/charts/webservice/values.yaml | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/charts/gitlab/charts/webservice/templates/deployment.yaml b/charts/gitlab/charts/webservice/templates/deployment.yaml index 1ca48e5275..cae16c10a4 100644 --- a/charts/gitlab/charts/webservice/templates/deployment.yaml +++ b/charts/gitlab/charts/webservice/templates/deployment.yaml @@ -1,6 +1,8 @@ {{- if $.Values.enabled }} {{- $imageCfg := dict "global" $.Values.global.image "local" $.Values.image -}} {{- $initImageCfg := include "gitlab.configure.config" $.Values | fromYaml -}} +{{- $affinityMode := coalesce $.Values.antiAffinity $.Values.global.antiAffinity .antiAffinity -}} +{{- $topologyKey := coalesce $.Values.affinity.podAntiAffinity.topologyKey $.Values.global.affinity.podAntiAffinity.topologyKey -}} {{- include "database.datamodel.prepare" $ -}} {{- include "webservice.datamodel.prepare" $ -}} {{/* BEGIN range deployments */}} @@ -84,22 +86,22 @@ spec: {{- $priorityClassName := dict "Values" (dict "global" (dict "priorityClassName" $.Values.global.priorityClassName) "priorityClassName" (default $.Values.priorityClassName .priorityClassName)) -}} {{- include "gitlab.priorityClassName" $priorityClassName | nindent 6 }} {{- include "gitlab.podSecurityContext" $.Values.securityContext | nindent 6 }} - {{- if eq (default $.Values.global.antiAffinity $.Values.antiAffinity) "hard" }} + {{- if eq $affinityMode "hard" }} affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - - topologyKey: {{ default $.Values.global.affinity.podAntiAffinity.topologyKey $.Values.affinity.podAntiAffinity.topologyKey | quote }} + - topologyKey: {{ $topologyKey | quote }} labelSelector: matchLabels: {{- include "gitlab.selectorLabels" $ | nindent 18 }} {{- include "webservice.labels" . | nindent 18}} - {{- else if eq (default $.Values.global.antiAffinity $.Values.antiAffinity) "soft" }} + {{- else if eq $affinityMode "soft" }} affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podAffinityTerm: - topologyKey: {{ default $.Values.global.affinity.podAntiAffinity.topologyKey $.Values.affinity.podAntiAffinity.topologyKey | quote }} + topologyKey: {{ $topologyKey | quote }} labelSelector: matchLabels: {{- include "gitlab.selectorLabels" $ | nindent 18 }} diff --git a/charts/gitlab/charts/webservice/values.yaml b/charts/gitlab/charts/webservice/values.yaml index 34c55e0e97..207be69541 100644 --- a/charts/gitlab/charts/webservice/values.yaml +++ b/charts/gitlab/charts/webservice/values.yaml @@ -131,7 +131,7 @@ extraIngress: proxyConnectTimeout: 15 proxyReadTimeout: 600 proxyBodySize: "512m" - # hostname: + # hostname: tls: {} # secretName: # smartcardSecretName: @@ -516,6 +516,8 @@ deployments: {} # ingress: # path: / +antiAffinity: "" # options: "hard", "soft" + affinity: podAntiAffinity: topologyKey: -- GitLab From 691f280d20cb48ba6c548b9c301f2bdc76d59064 Mon Sep 17 00:00:00 2001 From: Jason Plum Date: Mon, 13 Oct 2025 10:47:44 -0400 Subject: [PATCH 03/14] Ingress NGINX: update controller to v1.11.8 Update the Ingress NGINX controller to v1.11.8 Set `v1.11.8`, matched to list digest shown at https://gitlab.com/gitlab-org/cloud-native/mirror/images/-/jobs/11653174985#L791 Related to https://gitlab.com/gitlab-org/cloud-native/charts/gitlab-ingress-nginx/-/issues/25 Changelog: changed --- values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index fa230a2fc1..46f8a89895 100644 --- a/values.yaml +++ b/values.yaml @@ -1019,8 +1019,8 @@ nginx-ingress: &nginx-ingress image: registry: registry.gitlab.com image: gitlab-org/cloud-native/mirror/images/ingress-nginx/controller - tag: "v1.11.7" - digest: "sha256:016a25cf89bf7f930869ccd7cb3dd4acbe106cd4da1419804951ef9c8636f053" + tag: "v1.11.8" + digest: "sha256:695d79381ee6af00c7f5c9fd434f50851d7d32838ad5b2c507e416cf2084fc79" addHeaders: Referrer-Policy: strict-origin-when-cross-origin config: &nginx-ingress-controller-config -- GitLab From 1306c4bd811ffb1d77ec4d2ac6b3a52e121bc8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Cunha?= Date: Fri, 26 Sep 2025 16:12:10 +0200 Subject: [PATCH 04/14] Doc preference for safe navigation of nested values --- doc/development/style_guide.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/development/style_guide.md b/doc/development/style_guide.md index 151194d365..d9626023d4 100644 --- a/doc/development/style_guide.md +++ b/doc/development/style_guide.md @@ -240,6 +240,24 @@ Let's look at two snippet examples, which easily exemplify the reasoning: Related issue: [#729 Refactoring: Helm templates](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/729) +### Nested Value Access + +When accessing nested values in Helm templates, always use safe navigation patterns to prevent template rendering failures. + +**Preferred approach**: Use parentheses syntax for safe nested value access: + +```yaml +{{- $host := (((.Values.database).connection).host) -}} +{{- $port := (((.Values.database).connection).port) -}} +``` + +**Avoid**: Direct nested access without safety checks: + +```yaml +{{/* ❌ Unsafe - will fail if intermediate objects are null */}} +{{- if .Values.database.connection.host -}} +``` + ### When to utilize `toYaml` in templates It is frowned upon to default to utilizing a `toYaml` in the template files as -- GitLab From 713b0abca15974fa7e7037733b58d063ced06dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Cunha?= Date: Tue, 7 Oct 2025 22:07:33 +0200 Subject: [PATCH 05/14] Provide guidence on using dig, index, and direct access --- doc/development/style_guide.md | 44 +++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/doc/development/style_guide.md b/doc/development/style_guide.md index d9626023d4..c837e75e85 100644 --- a/doc/development/style_guide.md +++ b/doc/development/style_guide.md @@ -242,16 +242,54 @@ Related issue: [#729 Refactoring: Helm templates](https://gitlab.com/gitlab-org/ ### Nested Value Access -When accessing nested values in Helm templates, always use safe navigation patterns to prevent template rendering failures. +When accessing nested values in Helm templates, choose the appropriate safe navigation pattern based on your use case to prevent template rendering failures. Below we describe each case with examples. -**Preferred approach**: Use parentheses syntax for safe nested value access: +#### When to use each approach + +- **`dig`**: When you need fallback defaults and the path is known at template time. Best for most use cases. +- **`index`**: When accessing dynamic keys, working with complex nested structures, or when performance is critical. +- **Parentheses**: For simple cases where you just need safe navigation without defaults. +- **Direct access**: Only when you can guarantee the full path exists (rare in practice). + +#### Performance considerations + +Functions like `dig` and `index` can be more efficient than deeply nested parentheses, especially when accessing the same nested structure multiple times. Consider storing the result in a variable for reuse. + +#### Use `dig` for safe access with fallback defaults + +The [`dig` function](https://masterminds.github.io/sprig/dicts.html#dig) provides safe nested access with default values and is often the most robust approach: + +```yaml +{{- $host := dig "database" "connection" "host" "localhost" .Values -}} +{{- $port := dig "database" "connection" "port" 5432 .Values -}} +{{- $enabled := dig "registry" "enabled" false .Values.global -}} +``` + +#### Use `index` for dynamic keys or performance-critical paths + +The [`index` function](https://helm.sh/docs/chart_template_guide/function_list/#index) is ideal when accessing dynamic keys or when performance matters: + +```yaml +{{- $config := index .Values.global.redis .redisConfigName | default dict -}} +{{- $image := index .Values "shared-secrets" "selfsign" "image" -}} +{{- $settings := index .Values.gitlab "gitlab-shell" -}} +``` + +#### Use parentheses for simple safe navigation + +Parentheses syntax works well for straightforward cases where you need basic safe navigation: ```yaml {{- $host := (((.Values.database).connection).host) -}} {{- $port := (((.Values.database).connection).port) -}} ``` -**Avoid**: Direct nested access without safety checks: +But note that if you already know for other means that, ofr instance, `.Values.database` is present, you can simplify +the safe navitation with `(.Values.database.connection).port`. + +#### Avoid direct nested access without safety checks + +Direct access should only be used when you can guarantee the full path exists: ```yaml {{/* ❌ Unsafe - will fail if intermediate objects are null */}} -- GitLab From 1b74e244cf4c20141196e3965285082737d6b2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Cunha?= Date: Mon, 13 Oct 2025 21:55:49 +0200 Subject: [PATCH 06/14] Clarify use of index and remove Performance bit It's very unlikely that we'll get impacted by Performance. So the section about it is not so useful. --- doc/development/style_guide.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/doc/development/style_guide.md b/doc/development/style_guide.md index c837e75e85..2497c7b506 100644 --- a/doc/development/style_guide.md +++ b/doc/development/style_guide.md @@ -247,14 +247,10 @@ When accessing nested values in Helm templates, choose the appropriate safe navi #### When to use each approach - **`dig`**: When you need fallback defaults and the path is known at template time. Best for most use cases. -- **`index`**: When accessing dynamic keys, working with complex nested structures, or when performance is critical. +- **`index`**: When accessing dynamic keys, working with complex nested structures, or naming conventions imcompatible with Go, like kebab-case or snake_case. - **Parentheses**: For simple cases where you just need safe navigation without defaults. - **Direct access**: Only when you can guarantee the full path exists (rare in practice). -#### Performance considerations - -Functions like `dig` and `index` can be more efficient than deeply nested parentheses, especially when accessing the same nested structure multiple times. Consider storing the result in a variable for reuse. - #### Use `dig` for safe access with fallback defaults The [`dig` function](https://masterminds.github.io/sprig/dicts.html#dig) provides safe nested access with default values and is often the most robust approach: @@ -265,14 +261,12 @@ The [`dig` function](https://masterminds.github.io/sprig/dicts.html#dig) provide {{- $enabled := dig "registry" "enabled" false .Values.global -}} ``` -#### Use `index` for dynamic keys or performance-critical paths +#### Use `index` for dynamic keys, or naming conventions incompatible with Go -The [`index` function](https://helm.sh/docs/chart_template_guide/function_list/#index) is ideal when accessing dynamic keys or when performance matters: +Use [`index`](https://helm.sh/docs/chart_template_guide/function_list/#index) for dynamic keys or Go-incompatible naming like `kebab-case`: ```yaml -{{- $config := index .Values.global.redis .redisConfigName | default dict -}} {{- $image := index .Values "shared-secrets" "selfsign" "image" -}} -{{- $settings := index .Values.gitlab "gitlab-shell" -}} ``` #### Use parentheses for simple safe navigation @@ -284,7 +278,7 @@ Parentheses syntax works well for straightforward cases where you need basic saf {{- $port := (((.Values.database).connection).port) -}} ``` -But note that if you already know for other means that, ofr instance, `.Values.database` is present, you can simplify +But note that if you already know for other means that, for instance, `.Values.database` is present, you can simplify the safe navitation with `(.Values.database.connection).port`. #### Avoid direct nested access without safety checks -- GitLab From dd61b4dd53f9082dbcb51913f646ca46cc426932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Cunha?= Date: Thu, 25 Sep 2025 20:52:36 +0200 Subject: [PATCH 07/14] Extend the env deduplication on deployments and pods Webservice deployments and Sidekiq Pods were not considered when we implemented our `gitlab.godebug.env` template and `checkDuplicateKeyFromEnv` template. We've now extended both to accept an extra optional argument which takes the deployment/pod scope to detect if it finds the duplicated key on their extraEnv and extraEnvFrom. Issue: https://gitlab.com/gitlab-org/charts/gitlab/-/issues/6159 MR: https://gitlab.com/gitlab-org/charts/gitlab/-/merge_requests/4537 Changelog: fixed --- .../webservice/templates/deployment.yaml | 2 +- .../webservice_deployments_spec.rb | 56 +++++++++++++++++++ templates/_helpers.tpl | 16 +++++- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/charts/gitlab/charts/webservice/templates/deployment.yaml b/charts/gitlab/charts/webservice/templates/deployment.yaml index cae16c10a4..520320155b 100644 --- a/charts/gitlab/charts/webservice/templates/deployment.yaml +++ b/charts/gitlab/charts/webservice/templates/deployment.yaml @@ -366,7 +366,7 @@ spec: {{- end }} env: {{- include "gitlab.timeZone.env" $ | nindent 12 }} - {{- include "gitlab.godebug.env" $ | nindent 12 }} + {{- include "gitlab.godebug.env" (dict "rootScope" $ "deploymentScope" .) | nindent 12 }} - name: TMPDIR value: "/tmp/gitlab" - name: GITLAB_WORKHORSE_AUTH_BACKEND diff --git a/spec/configuration/webservice_deployments_spec.rb b/spec/configuration/webservice_deployments_spec.rb index a5177974bc..3ea65d071d 100644 --- a/spec/configuration/webservice_deployments_spec.rb +++ b/spec/configuration/webservice_deployments_spec.rb @@ -241,6 +241,62 @@ describe 'Webservice Deployments configuration' do expect(items.dig('ConfigMap/test-webservice')).to be_truthy expect(items.dig(item_key('ConfigMap', 'tests'))).to be_truthy end + + context 'extraEnv configuration for deployments' do + let(:extra_env_values) do + YAML.safe_load(%( + global: + extraEnv: + GLOBAL_VAR: "global_value" + gitlab: + webservice: + extraEnv: + WEBSERVICE_VAR: "webservice_value" + deployments: + default: + ingress: + path: / + extraEnv: + DEPLOYMENT_VAR: "default_deployment_value" + WEBSERVICE_VAR: "overridden_webservice_value" + api: + ingress: + path: /api + extraEnv: + API_SPECIFIC_VAR: "api_value" + GODEBUG: "foo=bar" + )).deep_merge(default_values) + end + + let(:chart_extra_env) { HelmTemplate.new(extra_env_values) } + + it 'properly inherits and merges extraEnv variables across deployment levels' do + expect(chart_extra_env.exit_code).to eq(0) + + # Test default deployment - should have global, webservice (overridden), and deployment-specific vars + default_env = chart_extra_env.env(item_key('Deployment', 'default'), 'webservice') + expect(default_env).to include(env_value('GLOBAL_VAR', 'global_value')) + expect(default_env).to include(env_value('WEBSERVICE_VAR', 'overridden_webservice_value')) + expect(default_env).to include(env_value('DEPLOYMENT_VAR', 'default_deployment_value')) + + # Test api deployment - should have global, webservice, and api-specific vars + api_env = chart_extra_env.env(item_key('Deployment', 'api'), 'webservice') + expect(api_env).to include(env_value('GLOBAL_VAR', 'global_value')) + expect(api_env).to include(env_value('WEBSERVICE_VAR', 'webservice_value')) + expect(api_env).to include(env_value('API_SPECIFIC_VAR', 'api_value')) + expect(api_env).not_to include(env_value('DEPLOYMENT_VAR', 'default_deployment_value')) + expect(api_env).not_to include(env_value('API_SPECIFIC_VAR', 'default_deployment_value')) + + # Test GODEBUG without deployment overrides + default_workhorse_env = chart_extra_env.env(item_key('Deployment', 'default'), 'gitlab-workhorse') + expect(default_workhorse_env).to include(env_value('GODEBUG', 'tlsmlkem=0,tlskyber=0')) + + # Test GODEBUG gets overriden on api deployment + default_workhorse_env = chart_extra_env.env(item_key('Deployment', 'api'), 'gitlab-workhorse') + expect(default_workhorse_env).to_not include(env_value('GODEBUG', 'tlsmlkem=0,tlskyber=0')) + expect(default_workhorse_env).to include(env_value('GODEBUG', 'foo=bar')) + end + end end context 'deployments datamodel' do diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 5c6203259b..8053a1ddf8 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -670,15 +670,19 @@ Return a boolean value that indicates whether a given key exists in the provided variables from either local or global scope. Usage: {{- include checkDuplicateKeyFromEnv (dict "rootScope" $ "keyToFind" "MY_KEY") -}} +Usage with webservice deployments or sidekiq pods context: {{- include checkDuplicateKeyFromEnv (dict "rootScope" $ "keyToFind" "MY_KEY" "deploymentScope" .) -}} */}} {{- define "checkDuplicateKeyFromEnv" -}} {{- $keyToFind := .keyToFind -}} {{- $rootScope := .rootScope -}} + {{- $deploymentScope := .deploymentScope -}} {{- $localHasKey := and $rootScope.Values.extraEnv (hasKey $rootScope.Values.extraEnv $keyToFind) -}} {{- $globalHasKey := and $rootScope.Values.global.extraEnv (hasKey $rootScope.Values.global.extraEnv $keyToFind) -}} {{- $localHasKeyFrom := and $rootScope.Values.extraEnvFrom (hasKey $rootScope.Values.extraEnvFrom $keyToFind) -}} {{- $globalHasKeyFrom := and $rootScope.Values.global.extraEnvFrom (hasKey $rootScope.Values.global.extraEnvFrom $keyToFind) -}} - {{- if or $localHasKey $globalHasKey $localHasKeyFrom $globalHasKeyFrom -}} + {{- $deploymentHasKey := and $deploymentScope $deploymentScope.extraEnv (hasKey $deploymentScope.extraEnv $keyToFind) -}} + {{- $deploymentHasKeyFrom := and $deploymentScope $deploymentScope.extraEnvFrom (hasKey $deploymentScope.extraEnvFrom $keyToFind) -}} + {{- if or $localHasKey $globalHasKey $localHasKeyFrom $globalHasKeyFrom $deploymentHasKey $deploymentHasKeyFrom -}} true {{- else -}} false @@ -687,9 +691,17 @@ false {{/* Render GODEBUG environment variable if not already defined in extraEnv + +Usage: {{- include "gitlab.godebug.env" $ -}} +Usage with webservice deployments or sidekiq pods context: {{- include "gitlab.godebug.env" (dict "rootScope" $ "deploymentScope" .) -}} */}} {{- define "gitlab.godebug.env" -}} -{{- $godebugIsDuplicate := include "checkDuplicateKeyFromEnv" (dict "rootScope" . "keyToFind" "GODEBUG") }} +{{- $rootScope := . -}} +{{- $deploymentScope := .deploymentScope -}} +{{- if .rootScope -}} +{{- $rootScope = .rootScope -}} +{{- end -}} +{{- $godebugIsDuplicate := include "checkDuplicateKeyFromEnv" (dict "rootScope" $rootScope "keyToFind" "GODEBUG" "deploymentScope" $deploymentScope) }} {{- if eq $godebugIsDuplicate "false" }} - name: GODEBUG value: 'tlsmlkem=0,tlskyber=0' -- GitLab From 2120b90ba3cbb038a7f8d1dcbe9d0e671bedc91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Alexandre=20Cunha?= Date: Fri, 10 Oct 2025 17:34:43 -0300 Subject: [PATCH 08/14] Simplify rootScope presence check --- templates/_helpers.tpl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 8053a1ddf8..219a8c19d1 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -696,12 +696,7 @@ Usage: {{- include "gitlab.godebug.env" $ -}} Usage with webservice deployments or sidekiq pods context: {{- include "gitlab.godebug.env" (dict "rootScope" $ "deploymentScope" .) -}} */}} {{- define "gitlab.godebug.env" -}} -{{- $rootScope := . -}} -{{- $deploymentScope := .deploymentScope -}} -{{- if .rootScope -}} -{{- $rootScope = .rootScope -}} -{{- end -}} -{{- $godebugIsDuplicate := include "checkDuplicateKeyFromEnv" (dict "rootScope" $rootScope "keyToFind" "GODEBUG" "deploymentScope" $deploymentScope) }} +{{- $godebugIsDuplicate := include "checkDuplicateKeyFromEnv" (dict "rootScope" (hasKey . "rootScope" | ternary .rootScope . ) "keyToFind" "GODEBUG" "deploymentScope" .deploymentScope) }} {{- if eq $godebugIsDuplicate "false" }} - name: GODEBUG value: 'tlsmlkem=0,tlskyber=0' -- GitLab From 14ea5cd3f4b61be180636a5e66e1d56512bb5518 Mon Sep 17 00:00:00 2001 From: Evan Read Date: Tue, 14 Oct 2025 10:40:38 +1000 Subject: [PATCH 09/14] Update Vale rules from GitLab project Ensure project Vale rules are synchronized with GitLab project. --- doc/.vale/gitlab_base/SubstitutionWarning.yml | 6 ++++++ doc/.vale/gitlab_base/WordSlashWord.yml | 16 ++++++++++++++++ doc/.vale/gitlab_base/spelling-exceptions.txt | 2 ++ doc/.vale/gitlab_docs/HistoryItems.yml | 2 +- doc/.vale/gitlab_docs/InternalLinkFormat.yml | 2 +- doc/.vale/gitlab_docs/TablePipes.yml | 12 ++++++++++++ 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 doc/.vale/gitlab_base/WordSlashWord.yml create mode 100644 doc/.vale/gitlab_docs/TablePipes.yml diff --git a/doc/.vale/gitlab_base/SubstitutionWarning.yml b/doc/.vale/gitlab_base/SubstitutionWarning.yml index 9eec13f102..61875d3a29 100644 --- a/doc/.vale/gitlab_base/SubstitutionWarning.yml +++ b/doc/.vale/gitlab_base/SubstitutionWarning.yml @@ -22,10 +22,13 @@ swap: case sensitive: "case-sensitive" case insensitive: "case-insensitive" cherry pick: "cherry-pick" + cmd: Command code base: "codebase" config: "configuration" confirmation box: "confirmation dialog" confirmation dialog box: "confirmation dialog" + ctrl: Control + del: Delete deselect: "clear" deselected: "cleared" dialog box: "dialog" @@ -63,14 +66,17 @@ swap: once the: "after the" once you: "after you" open telemetry: "OpenTelemetry" + open ldap: "OpenLDAP" pack file: packfile pack files: packfiles pop-up window: "dialog" pop-up: "dialog" popup: "dialog" + primary node: "primary site" re-index: "reindex" repo: "repository" root group: "top-level group" + secondary node: "secondary site" signed in user: "authenticated user" signed-in user: "authenticated user" since: "because' or 'after" diff --git a/doc/.vale/gitlab_base/WordSlashWord.yml b/doc/.vale/gitlab_base/WordSlashWord.yml new file mode 100644 index 0000000000..7238878c85 --- /dev/null +++ b/doc/.vale/gitlab_base/WordSlashWord.yml @@ -0,0 +1,16 @@ +--- +name: gitlab_base.WordSlashWord +description: | + Do not use word/word combos with slashes. +extends: existence +message: "Rewrite word/word combos like '%s' to not use slashes." +vocab: false +nonword: true +level: suggestion +link: https://docs.gitlab.com/development/documentation/styleguide/word_list/#slashes +scope: text +ignorecase: true +tokens: + - "and/or" + - "follow/unfollow" + - "go/no-go" diff --git a/doc/.vale/gitlab_base/spelling-exceptions.txt b/doc/.vale/gitlab_base/spelling-exceptions.txt index 6f3790e492..82b02b0ccf 100644 --- a/doc/.vale/gitlab_base/spelling-exceptions.txt +++ b/doc/.vale/gitlab_base/spelling-exceptions.txt @@ -481,6 +481,7 @@ Iglu IIFEs Immer inclusivity +inferencing inflector inflectors Ingress @@ -687,6 +688,7 @@ offboards OIDs OKRs Okta +Ollama OLM OmniAuth onboarding diff --git a/doc/.vale/gitlab_docs/HistoryItems.yml b/doc/.vale/gitlab_docs/HistoryItems.yml index ebf6023e81..c3f7d2cace 100644 --- a/doc/.vale/gitlab_docs/HistoryItems.yml +++ b/doc/.vale/gitlab_docs/HistoryItems.yml @@ -11,5 +11,5 @@ nonword: true scope: raw tokens: - '\{\{< history >\}\}\n\n[^-]' - - '(^#+[^\n]*|\{\{< /details >\}\})\n\n> -' + - '(^#+[^\n]*|\{\{< /details >\}\})\n\n>' - '^##.*?\n\n- \[?(Introduced|Changed|Renamed|Updated|Improved|Generally)' diff --git a/doc/.vale/gitlab_docs/InternalLinkFormat.yml b/doc/.vale/gitlab_docs/InternalLinkFormat.yml index 57043e0695..8a4c32aea2 100644 --- a/doc/.vale/gitlab_docs/InternalLinkFormat.yml +++ b/doc/.vale/gitlab_docs/InternalLinkFormat.yml @@ -9,4 +9,4 @@ vocab: false level: error scope: raw raw: - - '\[[^\]]+\]\((\.?\/(?!uploads|documentation)|[^:)]*\/\/)[^)]*\)' + - '\[[^\]]+\]\((\.?\/(?!uploads|documentation|page-from-root|home)|[^:)]*\/\/)[^)]*\)' diff --git a/doc/.vale/gitlab_docs/TablePipes.yml b/doc/.vale/gitlab_docs/TablePipes.yml new file mode 100644 index 0000000000..057b4e206a --- /dev/null +++ b/doc/.vale/gitlab_docs/TablePipes.yml @@ -0,0 +1,12 @@ +--- +name: gitlab_docs.TablePipes +description: | + Ensures pipe characters in tables use proper formatting. +extends: existence +message: "Table cells must have at least one space between pipe '|' characters and cell contents. In regex examples, escape pipe characters with a backslash: '\\|'." +link: https://docs.gitlab.com/development/documentation/styleguide/#tables +vocab: false +level: error +scope: raw +raw: + - '(?<=\n) *\|.*?[^\\]\|[^- \n:\\,=]' -- GitLab From 8111ac0e08c5597308bf20144d776b0c26666381 Mon Sep 17 00:00:00 2001 From: Erfan Ghavam Date: Sat, 25 Oct 2025 23:22:22 +0330 Subject: [PATCH 10/14] remove unwanted `.antiAffinity` --- charts/gitlab/charts/sidekiq/templates/deployment.yaml | 2 +- charts/gitlab/charts/webservice/templates/deployment.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/gitlab/charts/sidekiq/templates/deployment.yaml b/charts/gitlab/charts/sidekiq/templates/deployment.yaml index 404e8e16a4..346ea66e97 100644 --- a/charts/gitlab/charts/sidekiq/templates/deployment.yaml +++ b/charts/gitlab/charts/sidekiq/templates/deployment.yaml @@ -20,7 +20,7 @@ {{- $metricsPort := .Values.metrics.port -}} {{- $metricsPath := .Values.metrics.path -}} {{- $healthChecksPort := .Values.health_checks.port -}} -{{- $affinityMode := coalesce $.Values.antiAffinity $.Values.global.antiAffinity .antiAffinity -}} +{{- $affinityMode := coalesce $.Values.antiAffinity $.Values.global.antiAffinity -}} {{- $topologyKey := coalesce $.Values.affinity.podAntiAffinity.topologyKey $.Values.global.affinity.podAntiAffinity.topologyKey -}} {{- $configMapChecksum := include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} {{- range .Values.pods -}} diff --git a/charts/gitlab/charts/webservice/templates/deployment.yaml b/charts/gitlab/charts/webservice/templates/deployment.yaml index 520320155b..bb1b54f14e 100644 --- a/charts/gitlab/charts/webservice/templates/deployment.yaml +++ b/charts/gitlab/charts/webservice/templates/deployment.yaml @@ -1,7 +1,7 @@ {{- if $.Values.enabled }} {{- $imageCfg := dict "global" $.Values.global.image "local" $.Values.image -}} {{- $initImageCfg := include "gitlab.configure.config" $.Values | fromYaml -}} -{{- $affinityMode := coalesce $.Values.antiAffinity $.Values.global.antiAffinity .antiAffinity -}} +{{- $affinityMode := coalesce $.Values.antiAffinity $.Values.global.antiAffinity -}} {{- $topologyKey := coalesce $.Values.affinity.podAntiAffinity.topologyKey $.Values.global.affinity.podAntiAffinity.topologyKey -}} {{- include "database.datamodel.prepare" $ -}} {{- include "webservice.datamodel.prepare" $ -}} -- GitLab From e310cfa67efe784ad6f29d230ce7e2841fcdc1aa Mon Sep 17 00:00:00 2001 From: Erfan Ghavam Date: Sun, 26 Oct 2025 12:01:03 +0330 Subject: [PATCH 11/14] affinity_spec.rb: update tests for affinity changes --- spec/configuration/affinity_spec.rb | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/spec/configuration/affinity_spec.rb b/spec/configuration/affinity_spec.rb index c0c00205a3..85cebbc459 100644 --- a/spec/configuration/affinity_spec.rb +++ b/spec/configuration/affinity_spec.rb @@ -157,6 +157,38 @@ describe 'local affinity configuration' do )) end + let(:values_with_sidekiq_anti_affinity_override) do + HelmTemplate.with_defaults(%( + global: + antiAffinity: "soft" + affinity: + podAntiAffinity: + topologyKey: "global.test/hostname" + gitlab: + sidekiq: + antiAffinity: "hard" + affinity: + podAntiAffinity: + topologyKey: "sidekiq.test/hostname" + )) + end + + let(:values_with_webservice_anti_affinity_override) do + HelmTemplate.with_defaults(%( + global: + antiAffinity: "soft" + affinity: + podAntiAffinity: + topologyKey: "global.test/hostname" + gitlab: + webservice: + antiAffinity: "hard" + affinity: + podAntiAffinity: + topologyKey: "webservice.test/hostname" + )) + end + context 'when setting a local antiAffinity override' do it 'applies to a single Deployment' do t = HelmTemplate.new(values_with_override) @@ -198,4 +230,37 @@ describe 'local affinity configuration' do end end end + + context 'when overriding sidekiq antiAffinity locally' do + it 'enforces required antiAffinity with the queue label' do + t = HelmTemplate.new(values_with_sidekiq_anti_affinity_override) + expect(t.exit_code).to eq(0), "Unexpected error code #{t.exit_code} -- #{t.stderr}" + + key = 'Deployment/test-sidekiq-all-in-1-v2' + affinity = t.dig(key, 'spec', 'template', 'spec', 'affinity', 'podAntiAffinity') + + expect(affinity).to be_present + expect(affinity['requiredDuringSchedulingIgnoredDuringExecution']).to be_present + rule = affinity['requiredDuringSchedulingIgnoredDuringExecution'].first + expect(rule['topologyKey']).to eq('sidekiq.test/hostname') + expect(rule.dig('labelSelector', 'matchLabels', 'queue-pod-name')).to eq('all-in-1') + expect(affinity['preferredDuringSchedulingIgnoredDuringExecution']).not_to be_present + end + end + + context 'when overriding webservice antiAffinity locally' do + it 'enforces required antiAffinity with the custom topology key' do + t = HelmTemplate.new(values_with_webservice_anti_affinity_override) + expect(t.exit_code).to eq(0), "Unexpected error code #{t.exit_code} -- #{t.stderr}" + + key = 'Deployment/test-webservice-default' + affinity = t.dig(key, 'spec', 'template', 'spec', 'affinity', 'podAntiAffinity') + + expect(affinity).to be_present + expect(affinity['requiredDuringSchedulingIgnoredDuringExecution']).to be_present + rule = affinity['requiredDuringSchedulingIgnoredDuringExecution'].first + expect(rule['topologyKey']).to eq('webservice.test/hostname') + expect(affinity['preferredDuringSchedulingIgnoredDuringExecution']).not_to be_present + end + end end -- GitLab From c489b11a303a5576fd86da2cdcf9bac8498c37e0 Mon Sep 17 00:00:00 2001 From: Erfan Ghavam Date: Sun, 26 Oct 2025 12:41:43 +0330 Subject: [PATCH 12/14] update docs for sidekiq/webservice nodeAffinity --- doc/charts/gitlab/sidekiq/_index.md | 1 + doc/charts/gitlab/webservice/_index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/charts/gitlab/sidekiq/_index.md b/doc/charts/gitlab/sidekiq/_index.md index f945d64b7b..8500a976bc 100644 --- a/doc/charts/gitlab/sidekiq/_index.md +++ b/doc/charts/gitlab/sidekiq/_index.md @@ -146,6 +146,7 @@ to the `helm install` command using the `--set` flags: | `serviceAccount.enabled` | `false` | Indicates whether or not to use a ServiceAccount | | `serviceAccount.name` | | Name of the ServiceAccount. If not set, the full chart name is used | | `priorityClassName` | `""` | Allow configuring pods `priorityClassName`, this is used to control pod priority in case of eviction | +| `antiAffinity` | `""` | Allow you to overwrite antiAffinity values from chart global values, could default is read from global, could be set to `soft` or `hard` | ## Chart configuration examples diff --git a/doc/charts/gitlab/webservice/_index.md b/doc/charts/gitlab/webservice/_index.md index ecf7d2bf2c..16f4b2941c 100644 --- a/doc/charts/gitlab/webservice/_index.md +++ b/doc/charts/gitlab/webservice/_index.md @@ -206,6 +206,7 @@ to the `helm install` command using the `--set` flags. | `workhorse.circuitBreaker.consecutiveFailures` | `5`. | The number of consecutive failed requests to open the circuit breaker when closed | | `webServer` | `puma` | Selects web server (Webservice/Puma) that would be used for request handling | | `priorityClassName` | `""` | Allow configuring pods `priorityClassName`, this is used to control pod priority in case of eviction | +| `antiAffinity` | `""` | Allow you to overwrite antiAffinity values from chart global values, could default is read from global, could be set to `soft` or `hard` | ## Chart configuration examples -- GitLab From 0e6bb220ce9721ec73cdd80302ecd9947ea14a63 Mon Sep 17 00:00:00 2001 From: Erfan Ghavam Date: Mon, 27 Oct 2025 10:28:51 +0000 Subject: [PATCH 13/14] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Dylan Griffith --- doc/charts/gitlab/webservice/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/charts/gitlab/webservice/_index.md b/doc/charts/gitlab/webservice/_index.md index 16f4b2941c..ef72981d0a 100644 --- a/doc/charts/gitlab/webservice/_index.md +++ b/doc/charts/gitlab/webservice/_index.md @@ -206,7 +206,7 @@ to the `helm install` command using the `--set` flags. | `workhorse.circuitBreaker.consecutiveFailures` | `5`. | The number of consecutive failed requests to open the circuit breaker when closed | | `webServer` | `puma` | Selects web server (Webservice/Puma) that would be used for request handling | | `priorityClassName` | `""` | Allow configuring pods `priorityClassName`, this is used to control pod priority in case of eviction | -| `antiAffinity` | `""` | Allow you to overwrite antiAffinity values from chart global values, could default is read from global, could be set to `soft` or `hard` | +| `antiAffinity` | `""` | Allow you to overwrite antiAffinity values from chart global values, default is read from global, could be set to `soft` or `hard` | ## Chart configuration examples -- GitLab From 03c39a25a2f87cf8f2f6a734ce1897e8d6cdc3e1 Mon Sep 17 00:00:00 2001 From: Erfan Ghavam Date: Mon, 27 Oct 2025 10:28:59 +0000 Subject: [PATCH 14/14] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: Dylan Griffith --- doc/charts/gitlab/sidekiq/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/charts/gitlab/sidekiq/_index.md b/doc/charts/gitlab/sidekiq/_index.md index 8500a976bc..0cea655dca 100644 --- a/doc/charts/gitlab/sidekiq/_index.md +++ b/doc/charts/gitlab/sidekiq/_index.md @@ -146,7 +146,7 @@ to the `helm install` command using the `--set` flags: | `serviceAccount.enabled` | `false` | Indicates whether or not to use a ServiceAccount | | `serviceAccount.name` | | Name of the ServiceAccount. If not set, the full chart name is used | | `priorityClassName` | `""` | Allow configuring pods `priorityClassName`, this is used to control pod priority in case of eviction | -| `antiAffinity` | `""` | Allow you to overwrite antiAffinity values from chart global values, could default is read from global, could be set to `soft` or `hard` | +| `antiAffinity` | `""` | Allow you to overwrite antiAffinity values from chart global values, default is read from global, could be set to `soft` or `hard` | ## Chart configuration examples -- GitLab