#
#  Author: Hari Sekhon
#  Date: Thu Nov 26 13:35:31 2020 +0000
#
#  vim:ts=2:sts=2:sw=2:et
#
#  https://github.com/HariSekhon/Kubernetes-configs
#
#  License: see accompanying Hari Sekhon LICENSE file
#
#  If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback to help steer this or other code I publish
#
#  https://www.linkedin.com/in/HariSekhon
#

# ============================================================================ #
#                    T e a m C i t y   C I   -   S e r v e r
# ============================================================================ #

# See Also: https://github.com/HariSekhon/DevOps-Bash-tools/blob/master/setup/teamcity-docker-compose.yml

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: teamcity-server
  namespace: teamcity
  labels:
    app: teamcity-server
spec:
  replicas: 1
  serviceName: teamcity-server
  selector:
    matchLabels:
      app: teamcity-server
  template:
    metadata:
      labels:
        app: teamcity-server
    spec:
      priorityClassName: high-priority  # requires priorityclass.yaml
      affinity:
        # avoid preemption which can cause build failures
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: cloud.google.com/gke-preemptible
                    operator: DoesNotExist
                  - key: eks.amazonaws.com/capacityType
                    operator: NotIn
                    values:
                      - SPOT
                  - key: kubernetes.azure.com/scalesetpriority
                    operator: NotIn
                    values:
                      - spot
      # TODO: add sidecar logging cleanup container to remove very old datestamped logs or modify TeamCity's log rotation
      terminationGracePeriodSeconds: 120
      securityContext:
        #runAsUser: 0
        fsGroup: 1000
      # new version changed user to tcuser (uid 1000), crashing out, this was the fix
      #initContainers:
      #  - name: init
      #    image: busybox:latest
      #    command: ['/bin/chown', '-R', '1000:1000', '/data/teamcity_server/datadir', '/data/teamcity/logs']
      #    volumeMounts:
      #      - name: teamcity-server-datadir
      #        mountPath: /data/teamcity_server/datadir
      #      - name: teamcity-server-logs
      #        mountPath: /data/teamcity/logs
      serviceAccountName: teamcity-server
      containers:
        - name: teamcity-server
          image: jetbrains/teamcity-server:2020.2.1
          ports:
            - containerPort: 8111
          # teamcity doesn't have a proper status check endpoint
          #
          #   https://youtrack.jetbrains.com/issue/TW-62305
          #
          # don't use readiness probe, prevents accessing default /mnt page during bootup and just delays 503
          # instead of showing initializing page which redirects to login.html
  #        readinessProbe:
  #          httpGet:
  #            # works during setup or initialization but later fails during steady state as it then returns 302 to /overview.html
  #            #path: /mnt
  #            path: /login.html
  #            port: 8111
  #          initialDelaySeconds: 30  # takes 58 secs to become ready
  #          successThreshold: 1
  #          failureThreshold: 5
  #          periodSeconds: 5
  #          timeoutSeconds: 5
          # XXX: disable during fresh install setup which redirects to /mnt
          livenessProbe:
            httpGet:
              path: /login.html
              # not tested yet, may only apply to newer versions - https://youtrack.jetbrains.com/issue/TW-27675#focus=Comments-27-5577005.0-0
              #path: /app/rest/health?locator=global:true
              port: 8111
            #initialDelaySeconds: 120  # normally initializes in around this time
            initialDelaySeconds: 900   # may take longer due to complete initialization recovery after pod migration
            successThreshold: 1
            failureThreshold: 10
            periodSeconds: 5
            timeoutSeconds: 5
          resources:
            limits:
              cpu: 2
              memory: 4Gi  # TeamCity server's 2 processes JVM heaps are -Xmx2g and -Xmx1g, plus overheads and wiggle room
            requests:
              cpu: 200m    # 69m resting
              memory: 2Gi  # 1700Mi resting with pipelines
          volumeMounts:
            # contains config/, lib/, plugins/, system/
            - mountPath: /data/teamcity_server/datadir
              name: teamcity-server-datadir
            # if we reschedule the pod on another node we still want continuity of logs and their history
            - mountPath: /opt/teamcity/logs
              name: teamcity-server-logs
            # Optional: uncomment RemoteIpValve block in server.xml containing x-forwarded-for and x-forwarded-proto then upload to a configmap called server-xml in teamcity namespace to get rid of the following warning:
            #
            # Requests with incorrect proxy configuration were detected
            # Insecure Tomcat connector attributes
            # Request by <user> from x.x.x.x
            #
            #- mountPath: /opt/teamcity/conf/server.xml
            #  subPath: server.xml
            #  name: server-xml
#      volumes:
#        - name: server-xml
#          configMap:
#            name: server-xml
  volumeClaimTemplates:
    - metadata:
        name: teamcity-server-datadir
      spec:
        storageClassName: gcp-standard-resizeable
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            # after 1 year this was only 3GB
            storage: 20Gi
    - metadata:
        name: teamcity-server-logs
      spec:
        storageClassName: gcp-standard-resizeable
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            # after nearly a year the server logs were only 1.2GB,but accumulated datestamped logs, hence TODO to add sidecar to stop them building up further
            storage: 10Gi
