The script masked the exit codes of every command substitution it ran. `local` and `export` are commands themselves, so their own return value overwrites the one of the substitution and `set -e` never sees a failure. This was not only cosmetic: when `gitea generate secret` failed, the init container happily continued and exported an empty `INTERNAL_TOKEN`, `SECRET_KEY`, `JWT_SECRET` and `LFS_JWT_SECRET`. Declaration and assignment are now separated, which lets `set -e` abort instead of writing an app.ini with empty secrets. (SC2155) `env2ini::log` passed its argument as the format string of `printf`. Settings names and section names are read from user supplied configuration and are logged verbatim, so a value containing a `%` directive made `printf` consume non-existing arguments. The message is passed as data now. `%b` instead of `%s` keeps the `\n` escapes of the existing call sites working. (SC2059) The remaining changes quote the file name variables and add `-r` to the `read` of the `find -print0` loop, where an unquoted path or a backslash in a mount point would have been mangled. (SC2086, SC2162) Co-authored-by: Copilot <copilot@github.com>
162 lines
4.8 KiB
Bash
Executable File
162 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
function env2ini::log() {
|
|
# '%b' expands the \n escapes of the callers without treating the message itself as a format string
|
|
printf '%b\n' "${1}"
|
|
}
|
|
|
|
function env2ini::read_config_to_env() {
|
|
local section="${1}"
|
|
local line="${2}"
|
|
|
|
if [[ -z "${line}" ]]; then
|
|
# skip empty line
|
|
return
|
|
fi
|
|
|
|
# 'xargs echo -n' trims all leading/trailing whitespaces and a trailing new line
|
|
local setting
|
|
setting="$(awk -F '=' '{print $1}' <<< "${line}" | xargs echo -n)"
|
|
|
|
if [[ -z "${setting}" ]]; then
|
|
env2ini::log ' ! invalid setting'
|
|
exit 1
|
|
fi
|
|
|
|
local value=''
|
|
local regex="^${setting}(\s*)=(\s*)(.*)"
|
|
if [[ $line =~ $regex ]]; then
|
|
value="${BASH_REMATCH[3]}"
|
|
else
|
|
env2ini::log ' ! invalid setting'
|
|
exit 1
|
|
fi
|
|
|
|
env2ini::log " + '${setting}'"
|
|
|
|
if [[ -z "${section}" ]]; then
|
|
export "GITEA____${setting^^}=${value}" # '^^' makes the variable content uppercase
|
|
return
|
|
fi
|
|
|
|
local masked_section="${section//./_0X2E_}" # '//' instructs to replace all matches
|
|
masked_section="${masked_section//-/_0X2D_}"
|
|
|
|
export "GITEA__${masked_section^^}__${setting^^}=${value}" # '^^' makes the variable content uppercase
|
|
}
|
|
|
|
function env2ini::reload_preset_envs() {
|
|
env2ini::log "Reloading preset envs..."
|
|
|
|
while read -r line; do
|
|
if [[ -z "${line}" ]]; then
|
|
# skip empty line
|
|
return
|
|
fi
|
|
|
|
# 'xargs echo -n' trims all leading/trailing whitespaces and a trailing new line
|
|
local setting
|
|
setting="$(awk -F '=' '{print $1}' <<< "${line}" | xargs echo -n)"
|
|
|
|
if [[ -z "${setting}" ]]; then
|
|
env2ini::log ' ! invalid setting'
|
|
exit 1
|
|
fi
|
|
|
|
local value=''
|
|
local regex="^${setting}(\s*)=(\s*)(.*)"
|
|
if [[ $line =~ $regex ]]; then
|
|
value="${BASH_REMATCH[3]}"
|
|
else
|
|
env2ini::log ' ! invalid setting'
|
|
exit 1
|
|
fi
|
|
|
|
env2ini::log " + '${setting}'"
|
|
|
|
export "${setting^^}=${value}" # '^^' makes the variable content uppercase
|
|
done < "$TMP_EXISTING_ENVS_FILE"
|
|
|
|
rm "$TMP_EXISTING_ENVS_FILE"
|
|
}
|
|
|
|
function env2ini::process_config_file() {
|
|
local config_file="${1}"
|
|
local section
|
|
section="$(basename "${config_file}")"
|
|
|
|
if [[ $section == '_generals_' ]]; then
|
|
env2ini::log " [ini root]"
|
|
section=''
|
|
else
|
|
env2ini::log " ${section}"
|
|
fi
|
|
|
|
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
|
|
}
|
|
|
|
function env2ini::load_config_sources() {
|
|
local path="${1}"
|
|
|
|
if [[ -d "${path}" ]]; then
|
|
env2ini::log "Processing $(basename "${path}")..."
|
|
|
|
while read -r -d '' configFile; do
|
|
env2ini::process_config_file "${configFile}"
|
|
done < <(find "${path}" -type l -not -name '..data' -print0)
|
|
|
|
env2ini::log "\n"
|
|
fi
|
|
}
|
|
|
|
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
|
|
|
|
GITEA__SECURITY__INTERNAL_TOKEN="$(gitea generate secret INTERNAL_TOKEN)"
|
|
GITEA__SECURITY__SECRET_KEY="$(gitea generate secret SECRET_KEY)"
|
|
GITEA__OAUTH2__JWT_SECRET="$(gitea generate secret JWT_SECRET)"
|
|
GITEA__SERVER__LFS_JWT_SECRET="$(gitea generate secret LFS_JWT_SECRET)"
|
|
export GITEA__SECURITY__INTERNAL_TOKEN \
|
|
GITEA__SECURITY__SECRET_KEY \
|
|
GITEA__OAUTH2__JWT_SECRET \
|
|
GITEA__SERVER__LFS_JWT_SECRET
|
|
|
|
env2ini::log "...Initial secrets generated\n"
|
|
}
|
|
|
|
# save existing envs prior to script execution. Necessary to keep order of preexisting and custom envs
|
|
env | (grep -e '^GITEA__' || [[ $? == 1 ]]) > "$TMP_EXISTING_ENVS_FILE"
|
|
|
|
# MUST BE CALLED BEFORE OTHER CONFIGURATION
|
|
env2ini::generate_initial_secrets
|
|
|
|
env2ini::load_config_sources "$ENV_TO_INI_MOUNT_POINT/inlines/"
|
|
env2ini::load_config_sources "$ENV_TO_INI_MOUNT_POINT/additionals/"
|
|
|
|
# load existing envs to override auto generated envs
|
|
env2ini::reload_preset_envs
|
|
|
|
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'
|
|
env2ini::log ' - server.LFS_JWT_SECRET'
|
|
|
|
unset GITEA__SECURITY__INTERNAL_TOKEN
|
|
unset GITEA__SECURITY__SECRET_KEY
|
|
unset GITEA__OAUTH2__JWT_SECRET
|
|
unset GITEA__SERVER__LFS_JWT_SECRET
|
|
fi
|
|
|
|
gitea config edit-ini --apply-env --config "$GITEA_APP_INI" --out "$GITEA_APP_INI"
|