Generic way for configuring Gitea app.ini (#240)

With the result of PR #239 it is much easier to provide additional values to the _app.ini_ configuration from different sources.
These changes adds an _additionalConfigSources_ field where the users can define such sources. This enables the users to choose
on their own whether to store values in _values.yaml_ or load them from Kuberetes Secrets or ConfigMaps.

- Fixes #243
- Fixes #174
- Fixes #260

Reviewed-on: https://gitea.com/gitea/helm-chart/pulls/240
Reviewed-by: luhahn <luhahn@noreply.gitea.io>
Reviewed-by: wxiaoguang <wxiaoguang@noreply.gitea.io>
Co-authored-by: justusbunsi <justusbunsi@noreply.gitea.io>
Co-committed-by: justusbunsi <justusbunsi@noreply.gitea.io>
This commit is contained in:
justusbunsi
2021-12-22 18:44:04 +08:00
committed by luhahn
parent 66683e14df
commit 7b0a1c7ae6
6 changed files with 314 additions and 138 deletions

View File

@ -155,3 +155,157 @@ app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration" -}}
{{- include "gitea.inline_configuration.init" . -}}
{{- include "gitea.inline_configuration.defaults" . -}}
{{- $generals := list -}}
{{- $inlines := dict -}}
{{- range $key, $value := .Values.gitea.config }}
{{- if kindIs "map" $value }}
{{- if gt (len $value) 0 }}
{{- $section := default list (get $inlines $key) -}}
{{- range $n_key, $n_value := $value }}
{{- $section = append $section (printf "%s=%v" $n_key $n_value) -}}
{{- end }}
{{- $_ := set $inlines $key (join "\n" $section) -}}
{{- end -}}
{{- else }}
{{- if or (eq $key "APP_NAME") (eq $key "RUN_USER") (eq $key "RUN_MODE") -}}
{{- $generals = append $generals (printf "%s=%s" $key $value) -}}
{{- else -}}
{{- (printf "Key %s cannot be on top level of configuration" $key) | fail -}}
{{- end -}}
{{- end }}
{{- end }}
{{- $_ := set $inlines "_generals_" (join "\n" $generals) -}}
{{- toYaml $inlines -}}
{{- end -}}
{{- define "gitea.inline_configuration.init" -}}
{{- if not (hasKey .Values.gitea.config "cache") -}}
{{- $_ := set .Values.gitea.config "cache" dict -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config "server") -}}
{{- $_ := set .Values.gitea.config "server" dict -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config "metrics") -}}
{{- $_ := set .Values.gitea.config "metrics" dict -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config "database") -}}
{{- $_ := set .Values.gitea.config "database" dict -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config "security") -}}
{{- $_ := set .Values.gitea.config "security" dict -}}
{{- end -}}
{{- if not .Values.gitea.config.repository -}}
{{- $_ := set .Values.gitea.config "repository" dict -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config "oauth2") -}}
{{- $_ := set .Values.gitea.config "oauth2" dict -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration.defaults" -}}
{{- include "gitea.inline_configuration.defaults.server" . -}}
{{- include "gitea.inline_configuration.defaults.database" . -}}
{{- if not .Values.gitea.config.repository.ROOT -}}
{{- $_ := set .Values.gitea.config.repository "ROOT" "/data/git/gitea-repositories" -}}
{{- end -}}
{{- if not .Values.gitea.config.security.INSTALL_LOCK -}}
{{- $_ := set .Values.gitea.config.security "INSTALL_LOCK" "true" -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.metrics "ENABLED") -}}
{{- $_ := set .Values.gitea.config.metrics "ENABLED" .Values.gitea.metrics.enabled -}}
{{- end -}}
{{- if .Values.gitea.cache.builtIn.enabled -}}
{{- $_ := set .Values.gitea.config.cache "ENABLED" "true" -}}
{{- $_ := set .Values.gitea.config.cache "ADAPTER" "memcache" -}}
{{- if not (.Values.gitea.config.cache.HOST) -}}
{{- $_ := set .Values.gitea.config.cache "HOST" (include "memcached.dns" .) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration.defaults.server" -}}
{{- if not (hasKey .Values.gitea.config.server "HTTP_PORT") -}}
{{- $_ := set .Values.gitea.config.server "HTTP_PORT" .Values.service.http.port -}}
{{- end -}}
{{- if not .Values.gitea.config.server.PROTOCOL -}}
{{- $_ := set .Values.gitea.config.server "PROTOCOL" "http" -}}
{{- end -}}
{{- if not (.Values.gitea.config.server.DOMAIN) -}}
{{- if gt (len .Values.ingress.hosts) 0 -}}
{{- $_ := set .Values.gitea.config.server "DOMAIN" (index .Values.ingress.hosts 0).host -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "DOMAIN" (include "gitea.default_domain" .) -}}
{{- end -}}
{{- end -}}
{{- if not .Values.gitea.config.server.ROOT_URL -}}
{{- if .Values.ingress.enabled -}}
{{- if gt (len .Values.ingress.tls) 0 -}}
{{- $_ := set .Values.gitea.config.server "ROOT_URL" (printf "%s://%s" .Values.gitea.config.server.PROTOCOL (index (index .Values.ingress.tls 0).hosts 0)) -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "ROOT_URL" (printf "%s://%s" .Values.gitea.config.server.PROTOCOL (index .Values.ingress.hosts 0).host) -}}
{{- end -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "ROOT_URL" (printf "%s://%s" .Values.gitea.config.server.PROTOCOL .Values.gitea.config.server.DOMAIN) -}}
{{- end -}}
{{- end -}}
{{- if not .Values.gitea.config.server.SSH_DOMAIN -}}
{{- $_ := set .Values.gitea.config.server "SSH_DOMAIN" .Values.gitea.config.server.DOMAIN -}}
{{- end -}}
{{- if not .Values.gitea.config.server.SSH_PORT -}}
{{- $_ := set .Values.gitea.config.server "SSH_PORT" .Values.service.ssh.port -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "SSH_LISTEN_PORT") -}}
{{- if not .Values.image.rootless -}}
{{- $_ := set .Values.gitea.config.server "SSH_LISTEN_PORT" .Values.gitea.config.server.SSH_PORT -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "SSH_LISTEN_PORT" "2222" -}}
{{- end -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "START_SSH_SERVER") -}}
{{- if .Values.image.rootless -}}
{{- $_ := set .Values.gitea.config.server "START_SSH_SERVER" "true" -}}
{{- end -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "APP_DATA_PATH") -}}
{{- $_ := set .Values.gitea.config.server "APP_DATA_PATH" "/data" -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "ENABLE_PPROF") -}}
{{- $_ := set .Values.gitea.config.server "ENABLE_PPROF" false -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration.defaults.database" -}}
{{- if .Values.gitea.database.builtIn.postgresql.enabled -}}
{{- $_ := set .Values.gitea.config.database "DB_TYPE" "postgres" -}}
{{- if not (.Values.gitea.config.database.HOST) -}}
{{- $_ := set .Values.gitea.config.database "HOST" (include "postgresql.dns" .) -}}
{{- end -}}
{{- $_ := set .Values.gitea.config.database "NAME" .Values.postgresql.global.postgresql.postgresqlDatabase -}}
{{- $_ := set .Values.gitea.config.database "USER" .Values.postgresql.global.postgresql.postgresqlUsername -}}
{{- $_ := set .Values.gitea.config.database "PASSWD" .Values.postgresql.global.postgresql.postgresqlPassword -}}
{{- else if .Values.gitea.database.builtIn.mysql.enabled -}}
{{- $_ := set .Values.gitea.config.database "DB_TYPE" "mysql" -}}
{{- if not (.Values.gitea.config.database.HOST) -}}
{{- $_ := set .Values.gitea.config.database "HOST" (include "mysql.dns" .) -}}
{{- end -}}
{{- $_ := set .Values.gitea.config.database "NAME" .Values.mysql.db.name -}}
{{- $_ := set .Values.gitea.config.database "USER" .Values.mysql.db.user -}}
{{- $_ := set .Values.gitea.config.database "PASSWD" .Values.mysql.db.password -}}
{{- else if .Values.gitea.database.builtIn.mariadb.enabled -}}
{{- $_ := set .Values.gitea.config.database "DB_TYPE" "mysql" -}}
{{- if not (.Values.gitea.config.database.HOST) -}}
{{- $_ := set .Values.gitea.config.database "HOST" (include "mariadb.dns" .) -}}
{{- end -}}
{{- $_ := set .Values.gitea.config.database "NAME" .Values.mariadb.auth.database -}}
{{- $_ := set .Values.gitea.config.database "USER" .Values.mariadb.auth.username -}}
{{- $_ := set .Values.gitea.config.database "PASSWD" .Values.mariadb.auth.password -}}
{{- end -}}
{{- end -}}

View File

@ -1,5 +1,15 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "gitea.fullname" . }}-inline-config
labels:
{{- include "gitea.labels" . | nindent 4 }}
type: Opaque
stringData:
{{- include "gitea.inline_configuration" . | nindent 2 }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "gitea.fullname" . }}
labels:
@ -10,160 +20,105 @@ stringData:
#!/usr/bin/env bash
set -euo pipefail
{{- if not (hasKey .Values.gitea.config "cache") -}}
{{- $_ := set .Values.gitea.config "cache" dict -}}
{{- end -}}
function env2ini::log() {
printf "${1}\n"
}
{{- if not (hasKey .Values.gitea.config "server") -}}
{{- $_ := set .Values.gitea.config "server" dict -}}
{{- end -}}
function env2ini::read_config_to_env() {
local section="${1}"
local line="${2}"
{{- if not (hasKey .Values.gitea.config "metrics") -}}
{{- $_ := set .Values.gitea.config "metrics" dict -}}
{{- end -}}
if [[ -z "${line}" ]]; then
# skip empty line
return
fi
# 'xargs echo -n' trims all leading/trailing whitespaces and a trailing new line
local setting="$(awk -F '=' '{print $1}' <<< "${line}" | xargs echo -n)"
{{- if not (hasKey .Values.gitea.config "database") -}}
{{- $_ := set .Values.gitea.config "database" dict -}}
{{- end -}}
if [[ -z "${setting}" ]]; then
env2ini::log ' ! invalid setting'
exit 1
fi
{{- if not (hasKey .Values.gitea.config "security") -}}
{{- $_ := set .Values.gitea.config "security" dict -}}
{{- end -}}
local value=''
local regex="^${setting}(\s*)=(\s*)(.*)"
if [[ $line =~ $regex ]]; then
value="${BASH_REMATCH[3]}"
else
env2ini::log ' ! invalid setting'
exit 1
fi
{{- if not .Values.gitea.config.repository -}}
{{- $_ := set .Values.gitea.config "repository" dict -}}
{{- end -}}
env2ini::log " + '${setting}'"
{{- if not (hasKey .Values.gitea.config "oauth2") -}}
{{- $_ := set .Values.gitea.config "oauth2" dict -}}
{{- end -}}
if [[ -z "${section}" ]]; then
export "ENV_TO_INI____${setting^^}=${value}" # '^^' makes the variable content uppercase
return
fi
{{- /* repository default settings */ -}}
{{- if not .Values.gitea.config.repository.ROOT -}}
{{- $_ := set .Values.gitea.config.repository "ROOT" "/data/git/gitea-repositories" -}}
{{- end -}}
local masked_section="${section//./_0X2E_}" # '//' instructs to replace all matches
masked_section="${masked_section//-/_0X2D_}"
{{- /* security default settings */ -}}
{{- if not .Values.gitea.config.security.INSTALL_LOCK -}}
{{- $_ := set .Values.gitea.config.security "INSTALL_LOCK" "true" -}}
{{- end -}}
export "ENV_TO_INI__${masked_section^^}__${setting^^}=${value}" # '^^' makes the variable content uppercase
}
{{- /* server default settings */ -}}
{{- if not (hasKey .Values.gitea.config.server "HTTP_PORT") -}}
{{- $_ := set .Values.gitea.config.server "HTTP_PORT" .Values.service.http.port -}}
{{- end -}}
{{- if not .Values.gitea.config.server.PROTOCOL -}}
{{- $_ := set .Values.gitea.config.server "PROTOCOL" "http" -}}
{{- end -}}
{{- if not (.Values.gitea.config.server.DOMAIN) -}}
{{- if gt (len .Values.ingress.hosts) 0 -}}
{{- $_ := set .Values.gitea.config.server "DOMAIN" (index .Values.ingress.hosts 0).host -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "DOMAIN" (include "gitea.default_domain" .) -}}
{{- end -}}
{{- end -}}
{{- if not .Values.gitea.config.server.ROOT_URL -}}
{{- if .Values.ingress.enabled -}}
{{- if gt (len .Values.ingress.tls) 0 -}}
{{- $_ := set .Values.gitea.config.server "ROOT_URL" (printf "%s://%s" .Values.gitea.config.server.PROTOCOL (index (index .Values.ingress.tls 0).hosts 0)) -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "ROOT_URL" (printf "%s://%s" .Values.gitea.config.server.PROTOCOL (index .Values.ingress.hosts 0).host) -}}
{{- end -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "ROOT_URL" (printf "%s://%s" .Values.gitea.config.server.PROTOCOL .Values.gitea.config.server.DOMAIN) -}}
{{- end -}}
{{- end -}}
{{- if not .Values.gitea.config.server.SSH_DOMAIN -}}
{{- $_ := set .Values.gitea.config.server "SSH_DOMAIN" .Values.gitea.config.server.DOMAIN -}}
{{- end -}}
{{- if not .Values.gitea.config.server.SSH_PORT -}}
{{- $_ := set .Values.gitea.config.server "SSH_PORT" .Values.service.ssh.port -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "SSH_LISTEN_PORT") -}}
{{- if not .Values.image.rootless -}}
{{- $_ := set .Values.gitea.config.server "SSH_LISTEN_PORT" .Values.gitea.config.server.SSH_PORT -}}
{{- else -}}
{{- $_ := set .Values.gitea.config.server "SSH_LISTEN_PORT" "2222" -}}
{{- end -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "START_SSH_SERVER") -}}
{{- if .Values.image.rootless -}}
{{- $_ := set .Values.gitea.config.server "START_SSH_SERVER" "true" -}}
{{- end -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "APP_DATA_PATH") -}}
{{- $_ := set .Values.gitea.config.server "APP_DATA_PATH" "/data" -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config.server "ENABLE_PPROF") -}}
{{- $_ := set .Values.gitea.config.server "ENABLE_PPROF" false -}}
{{- end -}}
function env2ini::process_config_file() {
local config_file="${1}"
local section="$(basename "${config_file}")"
{{- /* metrics default settings */ -}}
{{- if not (hasKey .Values.gitea.config.metrics "ENABLED") -}}
{{- $_ := set .Values.gitea.config.metrics "ENABLED" .Values.gitea.metrics.enabled -}}
{{- end -}}
if [[ $section == '_generals_' ]]; then
env2ini::log " [ini root]"
section=''
else
env2ini::log " ${section}"
fi
{{- /* database default settings */ -}}
{{- if .Values.gitea.database.builtIn.postgresql.enabled -}}
{{- $_ := set .Values.gitea.config.database "DB_TYPE" "postgres" -}}
{{- if not (.Values.gitea.config.database.HOST) -}}
{{- $_ := set .Values.gitea.config.database "HOST" (include "postgresql.dns" .) -}}
{{- end -}}
{{- $_ := set .Values.gitea.config.database "NAME" .Values.postgresql.global.postgresql.postgresqlDatabase -}}
{{- $_ := set .Values.gitea.config.database "USER" .Values.postgresql.global.postgresql.postgresqlUsername -}}
{{- $_ := set .Values.gitea.config.database "PASSWD" .Values.postgresql.global.postgresql.postgresqlPassword -}}
{{ else if .Values.gitea.database.builtIn.mysql.enabled -}}
{{- $_ := set .Values.gitea.config.database "DB_TYPE" "mysql" -}}
{{- if not (.Values.gitea.config.database.HOST) -}}
{{- $_ := set .Values.gitea.config.database "HOST" (include "mysql.dns" .) -}}
{{- end -}}
{{- $_ := set .Values.gitea.config.database "NAME" .Values.mysql.db.name -}}
{{- $_ := set .Values.gitea.config.database "USER" .Values.mysql.db.user -}}
{{- $_ := set .Values.gitea.config.database "PASSWD" .Values.mysql.db.password -}}
{{ else if .Values.gitea.database.builtIn.mariadb.enabled -}}
{{- $_ := set .Values.gitea.config.database "DB_TYPE" "mysql" -}}
{{- if not (.Values.gitea.config.database.HOST) -}}
{{- $_ := set .Values.gitea.config.database "HOST" (include "mariadb.dns" .) -}}
{{- end -}}
{{- $_ := set .Values.gitea.config.database "NAME" .Values.mariadb.auth.database -}}
{{- $_ := set .Values.gitea.config.database "USER" .Values.mariadb.auth.username -}}
{{- $_ := set .Values.gitea.config.database "PASSWD" .Values.mariadb.auth.password -}}
{{- end -}}
while read -r line; do
env2ini::read_config_to_env "${section}" "${line}"
done < <(awk 1 "${config_file}") # Helm .toYaml trims the trailing new line which breaks line processing; awk 1 ... adds it back while reading
}
{{- /* cache default settings */ -}}
{{- if .Values.gitea.cache.builtIn.enabled -}}
{{- $_ := set .Values.gitea.config.cache "ENABLED" "true" -}}
{{- $_ := set .Values.gitea.config.cache "ADAPTER" "memcache" -}}
{{- if not (.Values.gitea.config.cache.HOST) -}}
{{- $_ := set .Values.gitea.config.cache "HOST" (include "memcached.dns" .) -}}
{{- end -}}
{{- end -}}
function env2ini::load_config_sources() {
local path="${1}"
{{- if not (hasKey .Values.gitea.config.security "INTERNAL_TOKEN") }}
export ENV_TO_INI__SECURITY__INTERNAL_TOKEN=$(gitea generate secret INTERNAL_TOKEN)
{{- end }}
{{- if not (hasKey .Values.gitea.config.security "SECRET_KEY") }}
export ENV_TO_INI__SECURITY__SECRET_KEY=$(gitea generate secret SECRET_KEY)
{{- end }}
{{- if not (hasKey .Values.gitea.config.oauth2 "JWT_SECRET") }}
export ENV_TO_INI__OAUTH2__JWT_SECRET=$(gitea generate secret JWT_SECRET)
{{- end }}
env2ini::log "Processing $(basename "${path}")..."
{{- /* autogenerate app.ini environment values */ -}}
{{- range $key, $value := .Values.gitea.config }}
{{- if kindIs "map" $value }}
{{- if gt (len $value) 0 }}
{{- range $n_key, $n_value := $value }}
export ENV_TO_INI__{{ $key | upper | replace "." "_0X2E_" | replace "-" "_0X2D_" }}__{{ $n_key | upper }}={{ $n_value }}
{{- end }}
{{- end }}
{{- else }}
export ENV_TO_INI__{{ $key | upper | replace "." "_0X2E_" | replace "-" "_0X2D_" }}__{{ $key | upper }}={{ $value }}
{{- end }}
{{- end }}
while read -d '' configFile; do
env2ini::process_config_file "${configFile}"
done < <(find "${path}" -type l -not -name '..data' -print0)
env2ini::log "\n"
}
function env2ini::generate_initial_secrets() {
# These environment variables will either be
# - overwritten with user defined values,
# - initially used to set up Gitea
# Anyway, they won't harm existing app.ini files
export ENV_TO_INI__SECURITY__INTERNAL_TOKEN=$(gitea generate secret INTERNAL_TOKEN)
export ENV_TO_INI__SECURITY__SECRET_KEY=$(gitea generate secret SECRET_KEY)
export ENV_TO_INI__OAUTH2__JWT_SECRET=$(gitea generate secret JWT_SECRET)
env2ini::log "...Initial secrets generated\n"
}
# MUST BE CALLED BEFORE OTHER CONFIGURATION
env2ini::generate_initial_secrets
env2ini::load_config_sources '/env-to-ini-mounts/inlines/'
env2ini::load_config_sources '/env-to-ini-mounts/additionals/'
env2ini::log "=== All configuration sources loaded ===\n"
# safety to prevent rewrite of secret keys if an app.ini already exists
if [ -f ${GITEA_APP_INI} ]; then
env2ini::log 'An app.ini file already exists. To prevent overwriting secret keys, these settings are dropped and remain unchanged:'
env2ini::log ' - security.INTERNAL_TOKEN'
env2ini::log ' - security.SECRET_KEY'
env2ini::log ' - oauth2.JWT_SECRET'
unset ENV_TO_INI__SECURITY__INTERNAL_TOKEN
unset ENV_TO_INI__SECURITY__SECRET_KEY
unset ENV_TO_INI__OAUTH2__JWT_SECRET

View File

@ -97,6 +97,12 @@ spec:
{{- 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 }}
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 12 }}
{{- end }}
@ -284,6 +290,13 @@ spec:
{{- if .Values.extraVolumes }}
{{- toYaml .Values.extraVolumes | nindent 8 }}
{{- end }}
- name: inline-config-sources
secret:
secretName: {{ include "gitea.fullname" . }}-inline-config
{{- range $idx, $value := .Values.gitea.additionalConfigSources }}
- name: additional-config-sources-{{ $idx }}
{{- toYaml $value | nindent 10 }}
{{- end }}
- name: temp
emptyDir: {}
{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }}