apiVersion: v1 kind: Secret metadata: labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 name: gitea namespace: gitea stringData: assertions: "" config_environment.sh: | #!/usr/bin/env bash set -euo pipefail function env2ini::log() { printf "${1}\n" } 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="$(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="$(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="$(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 -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 export GITEA__SECURITY__INTERNAL_TOKEN=$(gitea generate secret INTERNAL_TOKEN) export GITEA__SECURITY__SECRET_KEY=$(gitea generate secret SECRET_KEY) export GITEA__OAUTH2__JWT_SECRET=$(gitea generate secret JWT_SECRET) export GITEA__SERVER__LFS_JWT_SECRET=$(gitea generate secret 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 environment-to-ini -o $GITEA_APP_INI type: Opaque --- apiVersion: v1 kind: Secret metadata: labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 name: gitea-init namespace: gitea stringData: configure_gitea.sh: |- #!/usr/bin/env bash set -euo pipefail echo '==== BEGIN GITEA CONFIGURATION ====' { # try gitea migrate } || { # catch echo "Gitea migrate might fail due to database connection...This init-container will try again in a few seconds" exit 1 } function configure_admin_user() { local full_admin_list=$(gitea admin user list --admin) local actual_user_table='' # We might have distorted output due to warning logs, so we have to detect the actual user table by its headline and trim output above that line local regex="(.*)(ID\s+Username\s+Email\s+IsActive.*)" if [[ "${full_admin_list}" =~ $regex ]]; then actual_user_table=$(echo "${BASH_REMATCH[2]}" | tail -n+2) # tail'ing to drop the table headline else # This code block should never be reached, as long as the output table header remains the same. # If this code block is reached, the regex doesn't match anymore and we probably have to adjust this script. echo "ERROR: 'configure_admin_user' was not able to determine the current list of admin users." echo " Please review the output of 'gitea admin user list --admin' shown below." echo " If you think it is an issue with the Helm Chart provisioning, file an issue at https://gitea.com/gitea/helm-gitea/issues." echo "DEBUG: Output of 'gitea admin user list --admin'" echo "--" echo "${full_admin_list}" echo "--" exit 1 fi local ACCOUNT_ID=$(echo "${actual_user_table}" | grep -E "\s+${GITEA_ADMIN_USERNAME}\s+" | awk -F " " "{printf \$1}") if [[ -z "${ACCOUNT_ID}" ]]; then local -a create_args create_args=(--admin --username "${GITEA_ADMIN_USERNAME}" --password "${GITEA_ADMIN_PASSWORD}" --email "gitea@local.domain") if [[ "${GITEA_ADMIN_PASSWORD_MODE}" = initialOnlyRequireReset ]]; then create_args+=(--must-change-password=true) else create_args+=(--must-change-password=false) fi echo "No admin user '${GITEA_ADMIN_USERNAME}' found. Creating now..." gitea admin user create "${create_args[@]}" echo '...created.' else if [[ "${GITEA_ADMIN_PASSWORD_MODE}" = keepUpdated ]]; then echo "Admin account '${GITEA_ADMIN_USERNAME}' already exist. Running update to sync password..." # See https://gitea.com/gitea/helm-gitea/issues/673 # --must-change-password argument was added to change-password, defaulting to true, counter to the previous behavior # which acted as if it were provided with =false. If the argument is present in this version of gitea, then we # should add it to prevent requiring frequent admin password resets. local -a change_args change_args=(--username "${GITEA_ADMIN_USERNAME}" --password "${GITEA_ADMIN_PASSWORD}") if gitea admin user change-password --help | grep -qF -- '--must-change-password'; then change_args+=(--must-change-password=false) fi gitea admin user change-password "${change_args[@]}" echo '...password sync done.' else echo "Admin account '${GITEA_ADMIN_USERNAME}' already exist, but update mode is set to '${GITEA_ADMIN_PASSWORD_MODE}'. Skipping." fi fi } configure_admin_user function configure_ldap() { echo 'no ldap configuration... skipping.' } configure_ldap function configure_oauth() { echo 'no oauth configuration... skipping.' } configure_oauth echo '==== END GITEA CONFIGURATION ====' configure_gpg_environment.sh: | #!/usr/bin/env bash set -eu gpg --batch --import "$TMP_RAW_GPG_KEY" init_directory_structure.sh: |- #!/usr/bin/env bash set -euo pipefail mkdir -pv /data/git/.ssh chmod -Rv 700 /data/git/.ssh [ ! -d /data/gitea/conf ] && mkdir -pv /data/gitea/conf # prepare temp directory structure mkdir -pv "${GITEA_TEMP}" chmod -v ug+rwx "${GITEA_TEMP}" type: Opaque --- apiVersion: v1 kind: Secret metadata: labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 name: gitea-inline-config namespace: gitea stringData: _generals_: "" cache: |- ADAPTER=memory HOST= indexer: ISSUE_INDEXER_TYPE=db metrics: ENABLED=false queue: |- CONN_STR= TYPE=level repository: ROOT=/data/git/gitea-repositories security: INSTALL_LOCK=true server: |- APP_DATA_PATH=/data DOMAIN=git.borninpain.de ENABLE_PPROF=false HTTP_PORT=3000 PROTOCOL=http ROOT_URL=https://git.borninpain.de SSH_DOMAIN=ssh.git.borninpain.de SSH_LISTEN_PORT=2222 SSH_PORT=22 START_SSH_SERVER=true session: |- PROVIDER=memory PROVIDER_CONFIG= type: Opaque --- apiVersion: v1 kind: Service metadata: labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 name: gitea-http namespace: gitea spec: clusterIP: None ports: - name: http port: 3000 targetPort: null selector: app.kubernetes.io/instance: gitea app.kubernetes.io/name: gitea type: ClusterIP --- apiVersion: v1 kind: Service metadata: annotations: io.cilium/lb-ipam-ips: 192.168.0.185 labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 name: gitea-ssh namespace: gitea spec: ports: - name: ssh port: 22 protocol: TCP targetPort: 2222 selector: app.kubernetes.io/instance: gitea app.kubernetes.io/name: gitea type: LoadBalancer --- apiVersion: v1 kind: PersistentVolumeClaim metadata: annotations: helm.sh/resource-policy: keep labels: {} name: gitea-shared-storage namespace: gitea spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: openebs-3-replicas volumeMode: Filesystem --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 name: gitea namespace: gitea spec: replicas: 1 selector: matchLabels: app.kubernetes.io/instance: gitea app.kubernetes.io/name: gitea strategy: rollingUpdate: maxSurge: 100% maxUnavailable: 0 type: RollingUpdate template: metadata: annotations: checksum/config: 38f2f2bb0d9f5e9dd240c334857a64d931ca33e10b20d310240980753d8ff265 labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 spec: containers: - env: - name: SSH_LISTEN_PORT value: "2222" - name: SSH_PORT value: "22" - name: GITEA_APP_INI value: /data/gitea/conf/app.ini - name: GITEA_CUSTOM value: /data/gitea - name: GITEA_WORK_DIR value: /data - name: GITEA_TEMP value: /tmp/gitea - name: TMPDIR value: /tmp/gitea - name: HOME value: /data/gitea/git image: docker.gitea.com/gitea:1.24.5-rootless imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 10 initialDelaySeconds: 200 periodSeconds: 10 successThreshold: 1 tcpSocket: port: http timeoutSeconds: 1 name: gitea ports: - containerPort: 2222 name: ssh - containerPort: 3000 name: http readinessProbe: failureThreshold: 3 initialDelaySeconds: 5 periodSeconds: 10 successThreshold: 1 tcpSocket: port: http timeoutSeconds: 1 resources: {} securityContext: {} volumeMounts: - mountPath: /tmp name: temp - mountPath: /data name: data initContainers: - command: - /usr/sbinx/init_directory_structure.sh env: - name: GITEA_APP_INI value: /data/gitea/conf/app.ini - name: GITEA_CUSTOM value: /data/gitea - name: GITEA_WORK_DIR value: /data - name: GITEA_TEMP value: /tmp/gitea image: docker.gitea.com/gitea:1.24.5-rootless imagePullPolicy: IfNotPresent name: init-directories resources: limits: {} requests: cpu: 100m memory: 128Mi securityContext: {} volumeMounts: - mountPath: /usr/sbinx name: init - mountPath: /tmp name: temp - mountPath: /data name: data - command: - /usr/sbinx/config_environment.sh env: - name: GITEA_APP_INI value: /data/gitea/conf/app.ini - name: GITEA_CUSTOM value: /data/gitea - name: GITEA_WORK_DIR value: /data - name: GITEA_TEMP value: /tmp/gitea - name: TMP_EXISTING_ENVS_FILE value: /tmp/existing-envs - name: ENV_TO_INI_MOUNT_POINT value: /env-to-ini-mounts image: docker.gitea.com/gitea:1.24.5-rootless imagePullPolicy: IfNotPresent name: init-app-ini resources: limits: {} requests: cpu: 100m memory: 128Mi securityContext: {} volumeMounts: - mountPath: /usr/sbinx name: config - mountPath: /tmp name: temp - mountPath: /data name: data - mountPath: /env-to-ini-mounts/inlines/ name: inline-config-sources - command: - /usr/sbinx/configure_gitea.sh env: - name: GITEA_APP_INI value: /data/gitea/conf/app.ini - name: GITEA_CUSTOM value: /data/gitea - name: GITEA_WORK_DIR value: /data - name: GITEA_TEMP value: /tmp/gitea - name: HOME value: /data/gitea/git - name: GITEA_ADMIN_USERNAME value: gitea_admin - name: GITEA_ADMIN_PASSWORD value: r8sA8CPHD9!bt6d - name: GITEA_ADMIN_PASSWORD_MODE value: keepUpdated image: docker.gitea.com/gitea:1.24.5-rootless imagePullPolicy: IfNotPresent name: configure-gitea resources: limits: {} requests: cpu: 100m memory: 128Mi securityContext: runAsUser: 1000 volumeMounts: - mountPath: /usr/sbinx name: init - mountPath: /tmp name: temp - mountPath: /data name: data securityContext: fsGroup: 1000 terminationGracePeriodSeconds: 60 volumes: - name: init secret: defaultMode: 110 secretName: gitea-init - name: config secret: defaultMode: 110 secretName: gitea - name: inline-config-sources secret: secretName: gitea-inline-config - emptyDir: {} name: temp - name: data persistentVolumeClaim: claimName: gitea-shared-storage --- apiVersion: v1 kind: Pod metadata: annotations: helm.sh/hook: test-success labels: app: gitea app.kubernetes.io/instance: gitea app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: gitea app.kubernetes.io/version: 1.24.5 helm.sh/chart: gitea-12.2.0 version: 1.24.5 name: gitea-test-connection namespace: gitea spec: containers: - args: - gitea-http:3000 command: - wget image: busybox:latest name: wget restartPolicy: Never