fix(secrets): render config and init secrets as data to prune removed keys
Both Secrets rendered their payload via `stringData`. That field is write-only: the API server decodes it into `data` and does not persist `stringData` itself. Helm's three-way merge therefore generates a deletion patch that targets `stringData`, while the live object only ever carries `data` - so a key that disappears from the rendered manifest is never pruned and survives every upgrade. Unlike the inline-config Secret fixed in #1110, the keys here are driven by the files in `scripts/init-containers/**` rather than by user values, so the bug is latent rather than acute. It still bites whenever a script is removed or renamed in the chart: the stale key stays in the Secret and keeps being mounted into the init containers. The two inline scripts of the init Secret were YAML block scalars and had to be moved into `define` blocks to be pipeable through `b64enc`. The bodies are dedented by four columns accordingly, and `trimAll "\n"` reproduces the chomping semantics of the previous `|-` scalars. Rendering was diffed against the previous revision for defaults, rootless, initPreScript, GPG, admin, LDAP, OAuth and all valkey variants - the decoded payloads are byte-identical, so no init script changes behaviour. Unit tests now read the payloads from `data.*` with `decodeBase64: true` and assert that `stringData` no longer exists, to catch a regression early. See: https://gitea.com/gitea/helm-gitea/issues/1109 See: https://gitea.com/gitea/helm-gitea/pulls/1110 Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -14,10 +14,9 @@ metadata:
|
||||
name: {{ include "gitea.secret.config.name" . }}
|
||||
namespace: {{ .Values.namespace | default .Release.Namespace }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
{{ (.Files.Glob "scripts/init-containers/config/*.sh").AsConfig | indent 2 }}
|
||||
assertions: |
|
||||
{{- $assertions | nindent 4 }}
|
||||
data:
|
||||
{{ (.Files.Glob "scripts/init-containers/config/*.sh").AsSecrets | indent 2 }}
|
||||
assertions: {{ $assertions | b64enc | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gitea.config.assertions" -}}
|
||||
|
||||
+57
-52
@@ -11,59 +11,64 @@ metadata:
|
||||
name: {{ include "gitea.secret.init.name" . }}
|
||||
namespace: {{ .Values.namespace | default .Release.Namespace }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
{{ (.Files.Glob "scripts/init-containers/init/*.sh").AsConfig | indent 2 }}
|
||||
init_directory_structure.sh: |-
|
||||
#!/usr/bin/env bash
|
||||
data:
|
||||
{{ (.Files.Glob "scripts/init-containers/init/*.sh").AsSecrets | indent 2 }}
|
||||
configure_gitea.sh: {{ include "gitea.init.configureGitea" . | trimAll "\n" | b64enc | quote }}
|
||||
init_directory_structure.sh: {{ include "gitea.init.initDirectoryStructure" . | trimAll "\n" | b64enc | quote }}
|
||||
{{- end }}
|
||||
|
||||
set -euo pipefail
|
||||
{{- define "gitea.init.initDirectoryStructure" -}}
|
||||
#!/usr/bin/env bash
|
||||
|
||||
{{- if .Values.initPreScript }}
|
||||
# BEGIN: initPreScript
|
||||
{{- with .Values.initPreScript -}}
|
||||
{{ . | nindent 4}}
|
||||
{{- end -}}
|
||||
# END: initPreScript
|
||||
{{- end }}
|
||||
set -euo pipefail
|
||||
|
||||
{{- if not .Values.deployment.gitea.image.rootless }}
|
||||
chown -v 1000:1000 /data
|
||||
{{- end }}
|
||||
mkdir -pv /data/git/.ssh
|
||||
chmod -Rv 700 /data/git/.ssh
|
||||
[ ! -d /data/gitea/conf ] && mkdir -pv /data/gitea/conf
|
||||
{{- if .Values.initPreScript }}
|
||||
# BEGIN: initPreScript
|
||||
{{- with .Values.initPreScript -}}
|
||||
{{ . | nindent 0 }}
|
||||
{{- end -}}
|
||||
# END: initPreScript
|
||||
{{- end }}
|
||||
|
||||
# prepare temp directory structure
|
||||
mkdir -pv "${GITEA_TEMP}"
|
||||
{{- if not .Values.deployment.gitea.image.rootless }}
|
||||
chown -v 1000:1000 "${GITEA_TEMP}"
|
||||
{{- end }}
|
||||
chmod -v ug+rwx "${GITEA_TEMP}"
|
||||
{{- if not .Values.deployment.gitea.image.rootless }}
|
||||
chown -v 1000:1000 /data
|
||||
{{- end }}
|
||||
mkdir -pv /data/git/.ssh
|
||||
chmod -Rv 700 /data/git/.ssh
|
||||
[ ! -d /data/gitea/conf ] && mkdir -pv /data/gitea/conf
|
||||
|
||||
{{ if .Values.secrets.gpg.enabled -}}
|
||||
if [ ! -d "${GNUPGHOME}" ]; then
|
||||
# prepare temp directory structure
|
||||
mkdir -pv "${GITEA_TEMP}"
|
||||
{{- if not .Values.deployment.gitea.image.rootless }}
|
||||
chown -v 1000:1000 "${GITEA_TEMP}"
|
||||
{{- end }}
|
||||
chmod -v ug+rwx "${GITEA_TEMP}"
|
||||
|
||||
{{ if .Values.secrets.gpg.enabled -}}
|
||||
if [ ! -d "${GNUPGHOME}" ]; then
|
||||
mkdir -pv "${GNUPGHOME}"
|
||||
chmod -v 700 "${GNUPGHOME}"
|
||||
chown -v 1000:1000 "${GNUPGHOME}"
|
||||
fi
|
||||
{{- end }}
|
||||
fi
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
configure_gitea.sh: |-
|
||||
#!/usr/bin/env bash
|
||||
{{- define "gitea.init.configureGitea" -}}
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
set -euo pipefail
|
||||
|
||||
echo '==== BEGIN GITEA CONFIGURATION ===='
|
||||
echo '==== BEGIN GITEA CONFIGURATION ===='
|
||||
|
||||
{ # try
|
||||
{ # try
|
||||
gitea migrate
|
||||
} || { # catch
|
||||
} || { # catch
|
||||
echo "Gitea migrate might fail due to database connection...This init-container will try again in a few seconds"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
{{- if include "valkey.servicename" . }}
|
||||
function test_valkey_connection() {
|
||||
{{- if include "valkey.servicename" . }}
|
||||
function test_valkey_connection() {
|
||||
local RETRY=0
|
||||
local MAX=30
|
||||
|
||||
@@ -78,14 +83,14 @@ stringData:
|
||||
echo "Valkey not reachable after '${MAX}' attempts!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
test_valkey_connection
|
||||
{{- end }}
|
||||
test_valkey_connection
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- if .Values.secrets.admin.enabled }}
|
||||
function configure_admin_user() {
|
||||
{{- if .Values.secrets.admin.enabled }}
|
||||
function configure_admin_user() {
|
||||
local full_admin_list=$(gitea admin user list --admin)
|
||||
local actual_user_table=''
|
||||
|
||||
@@ -137,12 +142,12 @@ stringData:
|
||||
echo "Admin account '${GITEA_ADMIN_USERNAME}' already exist, but update mode is set to '${GITEA_ADMIN_PASSWORD_MODE}'. Skipping."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
configure_admin_user
|
||||
{{- end }}
|
||||
configure_admin_user
|
||||
{{- end }}
|
||||
|
||||
function configure_ldap() {
|
||||
function configure_ldap() {
|
||||
{{- if .Values.gitea.ldap }}
|
||||
{{- range $idx, $value := .Values.gitea.ldap }}
|
||||
local LDAP_NAME={{ (printf "%s" $value.name) | squote }}
|
||||
@@ -182,11 +187,11 @@ stringData:
|
||||
{{- else }}
|
||||
echo 'no ldap configuration... skipping.'
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
configure_ldap
|
||||
configure_ldap
|
||||
|
||||
function configure_oauth() {
|
||||
function configure_oauth() {
|
||||
{{- if .Values.gitea.oauth }}
|
||||
{{- range $idx, $value := .Values.gitea.oauth }}
|
||||
local OAUTH_NAME={{ (printf "%s" $value.name) | squote }}
|
||||
@@ -226,9 +231,9 @@ stringData:
|
||||
{{- else }}
|
||||
echo 'no oauth configuration... skipping.'
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
configure_oauth
|
||||
configure_oauth
|
||||
|
||||
echo '==== END GITEA CONFIGURATION ===='
|
||||
echo '==== END GITEA CONFIGURATION ===='
|
||||
{{- end }}
|
||||
|
||||
@@ -11,5 +11,15 @@ tests:
|
||||
asserts:
|
||||
- documentIndex: 0
|
||||
matchRegex:
|
||||
path: stringData["config_environment.sh"]
|
||||
path: data["config_environment.sh"]
|
||||
decodeBase64: true
|
||||
pattern: 'gitea config edit-ini --apply-env --config .+GITEA_APP_INI.+ --out .+GITEA_APP_INI'
|
||||
- it: renders data, not stringData, so removed keys are pruned on upgrade
|
||||
template: templates/secret_config.yaml
|
||||
asserts:
|
||||
- documentIndex: 0
|
||||
notExists:
|
||||
path: stringData
|
||||
- documentIndex: 0
|
||||
exists:
|
||||
path: data["config_environment.sh"]
|
||||
|
||||
@@ -39,7 +39,8 @@ tests:
|
||||
asserts:
|
||||
- documentIndex: 0
|
||||
matchRegex:
|
||||
path: stringData["configure_gitea.sh"]
|
||||
path: data["configure_gitea.sh"]
|
||||
decodeBase64: true
|
||||
pattern: nc -vz -w2 gitea-unittests-valkey.testing.svc.cluster.local 6379
|
||||
- it: "[gitea] waits for valkey to be up and running with custom cluster domain"
|
||||
set:
|
||||
@@ -48,5 +49,6 @@ tests:
|
||||
asserts:
|
||||
- documentIndex: 0
|
||||
matchRegex:
|
||||
path: stringData["configure_gitea.sh"]
|
||||
path: data["configure_gitea.sh"]
|
||||
decodeBase64: true
|
||||
pattern: nc -vz -w2 gitea-unittests-valkey.testing.svc.my-special-cluster.local 6379
|
||||
|
||||
@@ -14,7 +14,8 @@ tests:
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData["configure_gpg_environment.sh"]
|
||||
path: data["configure_gpg_environment.sh"]
|
||||
decodeBase64: true
|
||||
value: |
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
@@ -23,7 +24,8 @@ tests:
|
||||
- it: skips gpg script block for disabled signing
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData["init_directory_structure.sh"]
|
||||
path: data["init_directory_structure.sh"]
|
||||
decodeBase64: true
|
||||
value: |-
|
||||
#!/usr/bin/env bash
|
||||
|
||||
@@ -44,7 +46,8 @@ tests:
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData["init_directory_structure.sh"]
|
||||
path: data["init_directory_structure.sh"]
|
||||
decodeBase64: true
|
||||
value: |-
|
||||
#!/usr/bin/env bash
|
||||
|
||||
@@ -68,7 +71,8 @@ tests:
|
||||
deployment.gitea.image.fullOverride: docker.gitea.com/gitea:1.20.5
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData["init_directory_structure.sh"]
|
||||
path: data["init_directory_structure.sh"]
|
||||
decodeBase64: true
|
||||
value: |-
|
||||
#!/usr/bin/env bash
|
||||
|
||||
@@ -80,3 +84,9 @@ tests:
|
||||
# prepare temp directory structure
|
||||
mkdir -pv "${GITEA_TEMP}"
|
||||
chmod -v ug+rwx "${GITEA_TEMP}"
|
||||
- it: renders data, not stringData, so removed keys are pruned on upgrade
|
||||
asserts:
|
||||
- notExists:
|
||||
path: stringData
|
||||
- exists:
|
||||
path: data["init_directory_structure.sh"]
|
||||
|
||||
@@ -15,7 +15,8 @@ tests:
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData["configure_gpg_environment.sh"]
|
||||
path: data["configure_gpg_environment.sh"]
|
||||
decodeBase64: true
|
||||
value: |
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
@@ -26,7 +27,8 @@ tests:
|
||||
deployment.gitea.image.rootless: false
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData["init_directory_structure.sh"]
|
||||
path: data["init_directory_structure.sh"]
|
||||
decodeBase64: true
|
||||
value: |-
|
||||
#!/usr/bin/env bash
|
||||
|
||||
@@ -50,7 +52,8 @@ tests:
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData["init_directory_structure.sh"]
|
||||
path: data["init_directory_structure.sh"]
|
||||
decodeBase64: true
|
||||
value: |-
|
||||
#!/usr/bin/env bash
|
||||
|
||||
@@ -70,3 +73,11 @@ tests:
|
||||
chmod -v 700 "${GNUPGHOME}"
|
||||
chown -v 1000:1000 "${GNUPGHOME}"
|
||||
fi
|
||||
- it: renders data, not stringData, so removed keys are pruned on upgrade
|
||||
set:
|
||||
deployment.gitea.image.rootless: false
|
||||
asserts:
|
||||
- notExists:
|
||||
path: stringData
|
||||
- exists:
|
||||
path: data["init_directory_structure.sh"]
|
||||
|
||||
Reference in New Issue
Block a user