apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: utilities
  namespace: argo
  labels:
    type: util
spec:
  templates:
  - name: apply-job-and-wait
    inputs:
      parameters:
      - name: kubeconfig-secret
      - name: timeout
        default: 10m
      - name: ns
        default: default
      artifacts:
      - name: manifest
        path: /tmp/job.yaml
    volumes:
    - name: kubeconfig
      secret:
        secretName: '{{inputs.parameters.kubeconfig-secret}}'
    script:
      image: aylei/kubectl:v1.19.0
      command: [bash]
      volumeMounts:
      - mountPath: /.kube
        name: kubeconfig
      env:
      - name: KUBECONFIG
        value: "/.kube/kubeconfig"
      source: |
        set -x
        set -euo pipefail
        NS="{{inputs.parameters.ns}}"
        kubectl -n ${NS} apply -f /tmp/job.yaml
        kubectl -n ${NS} wait --for=condition=complete --timeout={{inputs.parameters.timeout}} -f /tmp/job.yaml &
        completion_pid=$!
        kubectl -n ${NS} wait --for=condition=failed --timeout={{inputs.parameters.timeout}} -f /tmp/job.yaml && exit 1 &
        failure_pid=$!
        wait -n $completion_pid $failure_pid
        exit_code=$?
        kubectl -n ${NS} logs --limit-bytes=1048576 job/$(yq -r .metadata.name /tmp/job.yaml) | tee -a /tmp/job.log
        if (( $exit_code != 0 )); then
          echo "Job failed with exit code ${exit_code}, exiting..."
          exit $exit_code
        fi
        # retain the job if failed
        kubectl -n ${NS} delete -f /tmp/job.yaml
    outputs:
      artifacts:
        - name: job-log
          path: /tmp/job.log

  - name: restore-and-wait
    inputs:
      parameters:
      - name: timeout
        default: 12h
      - name: ns
      - name: kubeconfig-secret
      - name: storage-credential-secret
      artifacts:
      - name: source
        path: /tmp/source.yaml
    volumes:
    - name: kubeconfig
      secret:
        secretName: '{{inputs.parameters.kubeconfig-secret}}'
    - name: storage-credential
      secret:
        secretName: '{{inputs.parameters.storage-credential-secret}}'
    script:
      image: aylei/kubectl:v1.19.0
      command: [bash]
      volumeMounts:
      - mountPath: /.kube
        name: kubeconfig
      - mountPath: /storage-credential
        name: storage-credential
      env:
      - name: KUBECONFIG
        value: "/.kube/kubeconfig"
      source: |
        set -x
        set -euo pipefail
        NS="{{inputs.parameters.ns}}"
        cat << EOF > /tmp/restore.yaml
        apiVersion: pingcap.com/v1alpha1
        kind: Restore
        metadata:
          name: bench-{{workflow.uid}}
          namespace: ${NS}
        spec:
          backupType: full
          br:
            cluster: db
            clusterNamespace: ${NS}
            sendCredToTikv: true
            concurrency: 128
        $(cat /tmp/source.yaml | sed "s/^/$(printf '%*s' 2)/")
          to:
            host: db-tidb-extra-service.${NS}
            port: 4000
            secretName: db-tidb-extra-secret
            user: root
        EOF

        mkdir /cred
        # Relay the credential of restore source to the target cluster temporarily
        # unfold symlinks to credentials so that --from-file can recongnize the secret keys
        cp /storage-credential/* /cred
        kubectl -n ${NS} create secret generic storage-credential --from-file=/cred
        trap 'kubectl -n ${NS} delete secret storage-credential' EXIT

        kubectl -n ${NS} apply -f /tmp/restore.yaml
        kubectl -n ${NS} wait --for=condition=Complete --timeout={{inputs.parameters.timeout}} -f /tmp/restore.yaml &
        completion_pid=$!
        kubectl -n ${NS} wait --for=condition=Failed --timeout={{inputs.parameters.timeout}} -f /tmp/restore.yaml && exit 1 &
        failure_pid=$!
        kubectl -n ${NS} wait --for=condition=RetryFailed --timeout={{inputs.parameters.timeout}} -f /tmp/restore.yaml && exit 1 &
        retry_failed_pid=$!
        wait -n $completion_pid $failure_pid $retry_failed_pid
        exit_code=$?
        if (( $exit_code != 0 )); then
          echo "Restore failed"
          exit $exit_code
        fi
