apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ template "fullname" . }}
  labels:
    app: {{ template "fullname" . }}
    chart: "{{ template "mysqlha.chart" . }}"
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
spec:
  selector:
    matchLabels:
      {{- include "common.labels.matchLabels" . | nindent 6 }}
      app.kubernetes.io/component: gitee-mysql
      app: {{ template "fullname" . }}
      release: {{ .Release.Name }}
  serviceName: {{ template "fullname" . }}
  replicas: {{ .Values.mysqlha.master.replicaCount }}
  template:
    metadata:
      labels:
        {{- include "common.labels.matchLabels" . | nindent 8 }}
        app.kubernetes.io/component: gitee-mysql
        app: {{ template "fullname" . }}
        release: {{ .Release.Name }}
      {{- if .Values.mysqlha.podAnnotations }}
      annotations:
{{ toYaml .Values.mysqlha.podAnnotations | indent 8 }}
      {{- end }}
    spec:
      {{- if .Values.securityContext.enabled }}
      securityContext:
        fsGroup: {{ .Values.securityContext.fsGroup }}
        runAsUser: {{ .Values.securityContext.runAsUser }}
        {{- if .Values.securityContext.sysctls }}
        sysctls: {{- toYaml .Values.securityContext.sysctls | nindent 8 }}
        {{- end }}
      {{- end }}
      {{- include "mysql.imagePullSecrets" . | indent 6 }}
      {{- if .Values.podAntiAffinityPreset | default false }}
      affinity:
        podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "component" "gitee-mysql" "context" $) | nindent 10 }}
        nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" (list  (printf "gitee-mysql") )) | nindent 10 }}
      {{- end }}
      {{- if .Values.tolerations }}
      tolerations:
      {{- toYaml .Values.tolerations | nindent 10 }}
      {{- end }}
      {{- if .Values.schedulerName }}
      schedulerName: "{{ .Values.schedulerName }}"
      {{- end }}
      initContainers:
      - name: clone-mysql
        securityContext:
          runAsUser: 0
        image: {{ .Values.xtraBackupImage }}
        imagePullPolicy: {{ .Values.imagePullPolicy | quote }}
        command:
          - bash
          - "-c"
          - |
            set -ex
            # Skip the clone on master (ordinal index 0).
            [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
            ordinal=${BASH_REMATCH[1]}
            [[ $ordinal -eq 0 ]] && exit 0

            # If data already exists, delete and proceed to clone.
            [[ -d /var/lib/mysql/mysql ]] && rm -fr /var/lib/mysql/*

            # Clone data from previous peer.
            ncat --recv-only {{ template "fullname" . }}-$(($ordinal-1)).{{ template "fullname" . }} 3307 | xbstream -x -C /var/lib/mysql
            # Prepare the backup.
            xtrabackup --prepare --user=${MYSQL_REPLICATION_USER} --password=${MYSQL_REPLICATION_PASSWORD} --target-dir=/var/lib/mysql
        env:
        - name: MYSQL_REPLICATION_USER
          value: {{ .Values.mysqlha.mysqlReplicationUser }}
        - name: MYSQL_REPLICATION_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "fullname" . }}
              key: mysql-replication-password
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
        {{- toYaml .Values.mysqlha.master.resources | nindent 10 }}
      - name: init-mysql
        securityContext:
          runAsUser: 0
        image: {{ .Values.mysqlImage }}
        imagePullPolicy: {{ .Values.imagePullPolicy | quote }}
        command: ["/bin/bash"]
        args:
          - "-c"
          - |
            set -ex
            # Generate mysql server-id from pod ordinal index.
            [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
            ordinal=${BASH_REMATCH[1]}
            # Copy server-id.conf adding offset to avoid reserved server-id=0 value.
            cat /mnt/config-map/server-id.cnf | sed s/@@SERVER_ID@@/$((100 + $ordinal))/g > /mnt/conf.d/server-id.cnf
            # Copy appropriate conf.d files from config-map to config mount.
            if [[ $ordinal -eq 0 ]]; then
              cp -f /mnt/config-map/master.cnf /mnt/conf.d/
            else
              cp -f /mnt/config-map/slave.cnf /mnt/conf.d/
            fi
            # Copy replication user script
            if [[ $ordinal -eq 0 ]]; then
              cp -f /mnt/config-map/create-replication-user.sh /mnt/scripts/create-replication-user.sh
              chmod 755 /mnt/scripts/create-replication-user.sh
            fi
        volumeMounts:
          - name: conf
            mountPath: /mnt/conf.d
          - name: config-map
            mountPath: /mnt/config-map
          - name: scripts
            mountPath: /mnt/scripts
        resources:
        {{- toYaml .Values.mysqlha.master.resources | nindent 10 }}
      containers:
      - name: mysql
        image: {{ .Values.mysqlImage }}
        imagePullPolicy: {{ .Values.imagePullPolicy | quote }}
        env:
        - name: MYSQL_DATABASE
          value: {{ default "" .Values.mysqlha.mysqlDatabase | quote }}
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "fullname" . }}
              key: mysql-root-password
        - name: MYSQL_REPLICATION_USER
          value: {{ .Values.mysqlha.mysqlReplicationUser }}
        - name: MYSQL_REPLICATION_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "fullname" . }}
              key: mysql-replication-password
        {{ if .Values.mysqlha.mysqlUser }}
        - name: MYSQL_USER
          value: {{ .Values.mysqlha.mysqlUser | quote }}
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "fullname" . }}
              key: mysql-password
        {{ end }}
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
        {{- toYaml .Values.mysqlha.master.resources | nindent 10 }}
        livenessProbe:
          exec:
            command:
            - /bin/sh
            - "-c"
            - mysqladmin ping -h 127.0.0.1 -u root -p${MYSQL_ROOT_PASSWORD}
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          exec:
            # Check we can execute queries over TCP (skip-networking is off).
            command:
            - /bin/sh
            - "-c"
            - MYSQL_PWD="${MYSQL_ROOT_PASSWORD}"
            - mysql -h 127.0.0.1 -uroot -e "SELECT 1"
          initialDelaySeconds: 10
          timeoutSeconds: 1
      {{- if .Values.metrics.enabled }}
      - name: metrics
        image: "{{ .Values.metrics.image }}:{{ .Values.metrics.imageTag }}"
        imagePullPolicy: {{ .Values.imagePullPolicy | quote }}
        {{- if .Values.mysqlha.mysqlAllowEmptyPassword }}
        command: ['sh', '-c', 'DATA_SOURCE_NAME="root@(localhost:3306)/" /bin/mysqld_exporter' ]
        {{- else }}
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ template "fullname" . }}
              key: mysql-root-password
        command: [ 'sh', '-c', 'DATA_SOURCE_NAME="root:$MYSQL_ROOT_PASSWORD@(localhost:3306)/" /bin/mysqld_exporter' ]
        {{- end }}
        ports:
        - name: metrics
          containerPort: 9104
        livenessProbe:
          httpGet:
            path: /
            port: metrics
          initialDelaySeconds: {{ .Values.metrics.livenessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.metrics.livenessProbe.timeoutSeconds }}
        readinessProbe:
          httpGet:
            path: /
            port: metrics
          initialDelaySeconds: {{ .Values.metrics.readinessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.metrics.readinessProbe.timeoutSeconds }}
        resources:
{{ toYaml .Values.metrics.resources | indent 10 }}
      {{- end }}
      volumes:
      - name: conf
        emptyDir: {}
      - name: config-map
        configMap:
          name: {{ template "fullname" . }}
      - name: scripts
        emptyDir: {}
{{- if .Values.mysqlha.master.persistence.enabled }}
  volumeClaimTemplates:
  - metadata:
      name: data
      annotations:
      {{- range $key, $value := .Values.mysqlha.master.persistence.annotations }}
        {{ $key }}: {{ $value }}
      {{- end }}
    spec:
      accessModes:
      {{- range .Values.mysqlha.master.persistence.accessModes }}
      - {{ . | quote }}
      {{- end }}
      resources:
        requests:
          storage: {{ .Values.mysqlha.master.persistence.size | quote }}
      {{- if .Values.mysqlha.master.persistence.storageClass }}
      {{- if (eq "-" .Values.mysqlha.master.persistence.storageClass) }}
      storageClassName: ""
      {{- else }}
      storageClassName: "{{ .Values.mysqlha.master.persistence.storageClass }}"
      {{- end }}
      {{- end }}
{{- else }}
      - name: data
        emptyDir: {}
{{- end }}
