apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "gitlab-runner.fullname" . }}
  namespace: {{ default .Release.Namespace .Values.runners.namespace | quote }}
  labels:
    app: {{ include "gitlab-runner.fullname" . }}
    chart: {{ include "gitlab-runner.chart" . }}
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
data:
  entrypoint: |
    #!/bin/bash
    set -e

    mkdir -p /home/gitlab-runner/.gitlab-runner/

    cp /configmaps/config.toml /home/gitlab-runner/.gitlab-runner/

    {{- if and (eq (default 1.0 .Values.replicas) 1.0) .Values.sessionServer .Values.sessionServer.enabled }}
    quit() {
      kill -TERM "$child"
    }

    trap quit QUIT TERM

    sh /configmaps/set-session-server-address &
    child=$!
    wait "$child"
    {{- end }}

    # Set up environment variables for cache
    if [[ -f /secrets/accesskey && -f /secrets/secretkey ]]; then
      export CACHE_S3_ACCESS_KEY=$(cat /secrets/accesskey)
      export CACHE_S3_SECRET_KEY=$(cat /secrets/secretkey)
    fi

    if [[ -f /secrets/gcs-applicaton-credentials-file ]]; then
      export GOOGLE_APPLICATION_CREDENTIALS="/secrets/gcs-applicaton-credentials-file"
    elif [[ -f /secrets/gcs-application-credentials-file ]]; then
      export GOOGLE_APPLICATION_CREDENTIALS="/secrets/gcs-application-credentials-file"
    else
      if [[ -f /secrets/gcs-access-id && -f /secrets/gcs-private-key ]]; then
        export CACHE_GCS_ACCESS_ID=$(cat /secrets/gcs-access-id)
        # echo -e used to make private key multiline (in google json auth key private key is oneline with \n)
        export CACHE_GCS_PRIVATE_KEY=$(echo -e $(cat /secrets/gcs-private-key))
      fi
    fi

    if [[ -f /secrets/azure-account-name && -f /secrets/azure-account-key ]]; then
      export CACHE_AZURE_ACCOUNT_NAME=$(cat /secrets/azure-account-name)
      export CACHE_AZURE_ACCOUNT_KEY=$(cat /secrets/azure-account-key)
    fi

    if [[ -f /secrets/runner-registration-token ]]; then
      export REGISTRATION_TOKEN=$(cat /secrets/runner-registration-token)
    fi

    if [[ -f /secrets/runner-token ]]; then
      export CI_SERVER_TOKEN=$(cat /secrets/runner-token)
    fi

    {{- if and (not (empty .Values.runnerToken)) (ne "1" ((default "1" .Values.replicas) | toString)) }}
    {{- fail "Using a runner token with more than 1 replica is not supported." }}
    {{- end }}

    # Validate this also at runtime in case the user has set a custom secret
    if [[ ! -z "$CI_SERVER_TOKEN" && "{{ default 1 .Values.replicas }}" -ne "1" ]]; then
      echo "Using a runner token with more than 1 replica is not supported."
      exit 1
    fi

    # Register the runner
    if ! sh /configmaps/register-the-runner; then
      exit 1
    fi

    # Run pre-entrypoint-script
    if ! bash /configmaps/pre-entrypoint-script; then
      exit 1
    fi

    # Start the runner
    exec /entrypoint run --user=gitlab-runner \
      --working-directory=/home/gitlab-runner

  config.toml: |
    concurrent = {{ .Values.concurrent }}
    check_interval = {{ .Values.checkInterval }}
    log_level = {{ default "info" .Values.logLevel | quote }}
    {{- if .Values.logFormat }}
    log_format = {{ .Values.logFormat | quote }}
    {{- end }}
    {{- if .Values.metrics.enabled }}
    listen_address = ':9252'
    {{- end }}
    {{- if .Values.sentryDsn }}
    sentry_dsn = "{{ .Values.sentryDsn }}"
    {{- end }}
    {{- if and (eq (default 1.0 .Values.replicas) 1.0) .Values.sessionServer .Values.sessionServer.enabled }}
    [session_server]
      session_timeout = {{ include "gitlab-runner.server-session-timeout" . }}
      listen_address = "0.0.0.0:{{ include "gitlab-runner.server-session-internal-port" . }}"
      advertise_address = "SESSION_SERVER_IP:{{ include "gitlab-runner.server-session-external-port" . }}"
    {{- end }}

  {{ if .Values.runners.config }}
  config.template.toml: {{ tpl (toYaml .Values.runners.config) $ | indent 2 }}
  {{ end }}

  register-the-runner: |
    #!/bin/bash
    MAX_REGISTER_ATTEMPTS=30

    for i in $(seq 1 "${MAX_REGISTER_ATTEMPTS}"); do
      echo "Registration attempt ${i} of ${MAX_REGISTER_ATTEMPTS}"
      /entrypoint register \
        {{- range .Values.runners.imagePullSecrets }}
        --kubernetes-image-pull-secrets {{ . | quote }} \
        {{- end }}
        {{- range $key, $val := .Values.runners.nodeSelector }}
        --kubernetes-node-selector {{ $key | quote }}:{{ $val | quote }} \
        {{- end }}
        {{- range .Values.runners.nodeTolerations }}
        {{-   $keyValue := .key }}
        {{-   if eq (.operator | default "Equal") "Equal"  }}
        {{-     $keyValue = print $keyValue "=" (.value | default "" ) }}
        {{-   end }}
        --kubernetes-node-tolerations {{ $keyValue }}:{{ .effect | quote }} \
        {{- end }}
        {{- range $key, $value := .Values.runners.podLabels }}
        --kubernetes-pod-labels {{ $key | quote }}:{{ $value | quote }} \
        {{- end }}
        {{- range $key, $val := .Values.runners.podAnnotations }}
        --kubernetes-pod-annotations {{ $key | quote }}:{{ $val | quote }} \
        {{- end }}
        {{- if and (hasKey .Values.runners "name") .Values.runners.name }}
        --name={{ .Values.runners.name | quote -}} \
        {{- end }}
        {{- if and (hasKey .Values.runners "maximumTimeout") .Values.runners.maximumTimeout }}
        --maximum-timeout={{ .Values.runners.maximumTimeout | quote -}} \
        {{- end }}
        {{- range $key, $value := .Values.runners.env }}
        --env {{ $key | quote -}} = {{- $value | quote }} \
        {{- end }}
        {{- if and (hasKey .Values.runners "runUntagged") .Values.runners.runUntagged }}
        --run-untagged=true \
        {{- end }}
        {{- if and (hasKey .Values.runners "protected") .Values.runners.protected }}
        --access-level="ref_protected" \
        {{- end }}
        {{- if .Values.runners.pod_security_context }}
        {{-   if .Values.runners.pod_security_context.supplemental_groups }}
        {{-     range $gid := .Values.runners.pod_security_context.supplemental_groups }}
        --kubernetes-pod-security-context-supplemental-groups {{ $gid | quote }} \
        {{-     end }}
        {{-   end }}
        {{- end }}
        {{- if .Values.runners.config }}
        --template-config /configmaps/config.template.toml \
        {{- end }}
        --non-interactive

      retval=$?

      if [ ${retval} = 0 ]; then
        break
      elif [ ${i} = ${MAX_REGISTER_ATTEMPTS} ]; then
        exit 1
      fi

      sleep 5
    done

    exit 0

  check-live: |
    #!/bin/bash
    if /usr/bin/pgrep -f .*register-the-runner; then
      exit 0
    elif /usr/bin/pgrep gitlab.*runner; then
      exit 0
    else
      exit 1
    fi

  {{- if and (eq (default 1.0 .Values.replicas) 1.0) .Values.sessionServer .Values.sessionServer.enabled }}
  set-session-server-address: |
    #!/bin/bash

    {{- if (not .Values.sessionServer.publicIP) }}
    APISERVER=https://kubernetes.default.svc \
      && SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount \
      && NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) \
      && TOKEN=$(cat ${SERVICEACCOUNT}/token) \
      && CACERT=${SERVICEACCOUNT}/ca.crt \
      && header="Authorization: Bearer ${TOKEN}"

    SERVICEURL=${APISERVER}/api/v1/namespaces/${NAMESPACE}/services/{{ include "gitlab-runner.fullname" . }}-session-server

    has_address=false
    while [ "${has_address}" = false ]; do
      SERVICEIP=$(curl —-silent \
        --cacert ${CACERT} \
        --header "${header}" \
        -X GET ${SERVICEURL} 2>/dev/null \
        | grep '"ip":' | cut -d ":" -f2 | xargs)

      # for aws, the hostname is available but not the external IP
      SERVICEHOSTNAME=$(curl —-silent \
        --cacert ${CACERT} \
        --header "${header}" \
        -X GET ${SERVICEURL} 2>/dev/null \
        | grep '"hostname":' | cut -d ":" -f2 | xargs)

      ADDRESS="${SERVICEHOSTNAME:-$SERVICEIP}"
      
      if [ -z "${ADDRESS}" ]
      then
        echo "Service LoadBalancer External Address not yet available"
        has_address=false
        sleep 5
      else
        has_address=true
        sed -i -e "s/SESSION_SERVER_IP/${ADDRESS}/g" /home/gitlab-runner/.gitlab-runner/config.toml
      fi
    done
    {{- else }}
    sed -i -e "s/SESSION_SERVER_IP/{{ .Values.sessionServer.publicIP }}/g" /home/gitlab-runner/.gitlab-runner/config.toml
    {{- end}}
  {{ end }}

  pre-entrypoint-script: |
{{ .Values.preEntrypointScript | default "" | indent 4 }}

{{ if not (empty .Values.configMaps) }}{{ toYaml .Values.configMaps | indent 2 }}{{ end }}
