---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ${NAME}-runner-work-dir
  labels:
    content: ${NAME}-runner-work-dir
provisioner: rancher.io/local-path
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ${NAME}
# In kind environments, the provider writes:
#   /var/lib/docker/volumes/KIND_NODE_CONTAINER_VOL_ID/_data/local-path-provisioner/PV_NAME
# It can be hundreds of gigabytes depending on what you cache in the test workflow. Beware to not encounter `no space left on device` errors!
# If you did encounter no space errorrs try:
#   docker system prune
#   docker buildx prune #=> frees up /var/lib/docker/volumes/buildx_buildkit_container-builder0_state
#   sudo rm -rf /var/lib/docker/volumes/KIND_NODE_CONTAINER_VOL_ID/_data/local-path-provisioner #=> frees up local-path-provisioner's data
provisioner: rancher.io/local-path
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ${NAME}-var-lib-docker
  labels:
    content: ${NAME}-var-lib-docker
provisioner: rancher.io/local-path
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ${NAME}-cache
  labels:
    content: ${NAME}-cache
provisioner: rancher.io/local-path
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ${NAME}-runner-tool-cache
  labels:
    content: ${NAME}-runner-tool-cache
provisioner: rancher.io/local-path
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ${NAME}-rootless-dind-work-dir
  labels:
    content: ${NAME}-rootless-dind-work-dir
provisioner: rancher.io/local-path
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerSet
metadata:
  name: ${NAME}
spec:
  # MANDATORY because it is based on StatefulSet: Results in a below error when omitted:
  #   missing required field "selector" in dev.summerwind.actions.v1alpha1.RunnerSet.spec
  selector:
    matchLabels:
      app: ${NAME}

  # MANDATORY because it is based on StatefulSet: Results in a below error when omitted:
  # missing required field "serviceName" in dev.summerwind.actions.v1alpha1.RunnerSet.spec]
  serviceName: ${NAME}

  #replicas: 1

  # From my limited testing, `ephemeral: true` is more reliable.
  # Seomtimes, updating already deployed runners from `ephemeral: false` to `ephemeral: true` seems to
  # result in queued jobs hanging forever.
  ephemeral: ${TEST_EPHEMERAL}

  enterprise: ${TEST_ENTERPRISE}
  group: ${TEST_GROUP}
  organization: ${TEST_ORG}
  repository: ${TEST_REPO}

  #
  # Custom runner image
  #
  image: ${RUNNER_NAME}:${RUNNER_TAG}

  #
  # dockerd within runner container
  #
  ## Replace `mumoshu/actions-runner-dind:dev` with your dind image
  #dockerdWithinRunnerContainer: true
  dockerdWithinRunnerContainer: ${RUNNER_DOCKERD_WITHIN_RUNNER_CONTAINER}

  #
  # Set the MTU used by dockerd-managed network interfaces (including docker-build-ubuntu)
  #
  #dockerMTU: 1450
  #Runner group
  # labels:
  # - "mylabel 1"
  # - "mylabel 2"
  labels:
  - "${RUNNER_LABEL}"
  #
  # Non-standard working directory
  #
  # workDir: "/"
  template:
    metadata:
      labels:
        app: ${NAME}
    spec:
      serviceAccountName: ${RUNNER_SERVICE_ACCOUNT_NAME}
      terminationGracePeriodSeconds: ${RUNNER_TERMINATION_GRACE_PERIOD_SECONDS}
      containers:
      # # Uncomment only when non-dind-runner / you're using docker sidecar
      # - name: docker
      #   # Image is required for the dind sidecar definition within RunnerSet spec
      #   image: "docker:dind"
      #   env:
      #   - name: RUNNER_GRACEFUL_STOP_TIMEOUT
      #     value: "${RUNNER_GRACEFUL_STOP_TIMEOUT}"
      - name: runner
        imagePullPolicy: IfNotPresent
        env:
        - name: RUNNER_GRACEFUL_STOP_TIMEOUT
          value: "${RUNNER_GRACEFUL_STOP_TIMEOUT}"
        - name: RUNNER_FEATURE_FLAG_EPHEMERAL
          value: "${RUNNER_FEATURE_FLAG_EPHEMERAL}"
        - name: GOMODCACHE
          value: "/home/runner/.cache/go-mod"
        - name: ROLLING_UPDATE_PHASE
          value: "${ROLLING_UPDATE_PHASE}"
        # PV-backed runner work dir
        volumeMounts:
        # Comment out the ephemeral work volume if you're going to test the kubernetes container mode
        # The volume and mount with the same names will be created by workVolumeClaimTemplate and the kubernetes container mode support.
        # - name: work
        #   mountPath: /runner/_work
        # Cache docker image layers, in case dockerdWithinRunnerContainer=true
        - name: var-lib-docker
          mountPath: /var/lib/docker
        # Cache go modules and builds
        # - name: gocache
        #   # Run `goenv | grep GOCACHE` to verify the path is correct for your env
        #   mountPath: /home/runner/.cache/go-build
        # - name: gomodcache
        #   # Run `goenv | grep GOMODCACHE` to verify the path is correct for your env
        #   # mountPath: /home/runner/go/pkg/mod
        - name: cache
          # go: could not create module cache: stat /home/runner/.cache/go-mod: permission denied
          mountPath: "/home/runner/.cache"
        - name: runner-tool-cache
          # This corresponds to our runner image's default setting of RUNNER_TOOL_CACHE=/opt/hostedtoolcache.
          #
          # In case you customize the envvar in both runner and docker containers of the runner pod spec,
          # You'd need to change this mountPath accordingly.
          #
          # The tool cache directory is defined in actions/toolkit's tool-cache module:
          # https://github.com/actions/toolkit/blob/2f164000dcd42fb08287824a3bc3030dbed33687/packages/tool-cache/src/tool-cache.ts#L621-L638
          #
          # Many setup-* actions like setup-go utilizes the tool-cache module to download and cache installed binaries:
          # https://github.com/actions/setup-go/blob/56a61c9834b4a4950dbbf4740af0b8a98c73b768/src/installer.ts#L144
          mountPath: "/opt/hostedtoolcache"
      # Valid only when dockerdWithinRunnerContainer=false
      # - name: docker
      #   # PV-backed runner work dir
      #   volumeMounts:
      #   - name: work
      #     mountPath: /runner/_work
      #   # Cache docker image layers, in case dockerdWithinRunnerContainer=false
      #   - name: var-lib-docker
      #     mountPath: /var/lib/docker
      #   # image: mumoshu/actions-runner-dind:dev

      #   # For buildx cache
      #   - name: cache
      #     mountPath: "/home/runner/.cache"

        # For fixing no space left error on rootless dind runner
        - name: rootless-dind-work-dir
          # Omit the /share/docker part of the /home/runner/.local/share/docker as
          # that part is created by dockerd.
          mountPath: /home/runner/.local
          readOnly: false

      # Comment out the ephemeral work volume if you're going to test the kubernetes container mode
      # volumes:
      # - name: work
      #   ephemeral:
      #     volumeClaimTemplate:
      #       spec:
      #         accessModes:
      #         - ReadWriteOnce
      #         storageClassName: "${NAME}-runner-work-dir"
      #         resources:
      #           requests:
      #             storage: 10Gi

      # Fix the following no space left errors with rootless-dind runners that can happen while running buildx build:
      #   ------
      #   > [4/5] RUN go mod download:
      #   ------
      #   ERROR: failed to solve: failed to prepare yxsw8lv9hqnuafzlfta244l0z: mkdir /home/runner/.local/share/docker/vfs/dir/yxsw8lv9hqnuafzlfta244l0z/usr/local/go/src/cmd/compile/internal/types2/testdata: no space left on device
      #   Error: Process completed with exit code 1.
      #
      volumes:
      - name: rootless-dind-work-dir
        ephemeral:
          volumeClaimTemplate:
            spec:
              accessModes: [ "ReadWriteOnce" ]
              storageClassName: "${NAME}-rootless-dind-work-dir"
              resources:
                requests:
                  storage: 3Gi
  volumeClaimTemplates:
  - metadata:
      name: vol1
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Mi
      storageClassName: ${NAME}
      ## Dunno which provider supports auto-provisioning with selector.
      ## At least the rancher local path provider stopped with:
      ##  waiting for a volume to be created, either by external provisioner "rancher.io/local-path" or manually created by system administrator
      # selector:
      #    matchLabels:
      #      runnerset-volume-id: ${NAME}-vol1
  - metadata:
      name: vol2
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Mi
      storageClassName: ${NAME}
      # selector:
      #    matchLabels:
      #      runnerset-volume-id: ${NAME}-vol2
  - metadata:
      name: var-lib-docker
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Mi
      storageClassName: ${NAME}-var-lib-docker
  - metadata:
      name: cache
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Mi
      storageClassName: ${NAME}-cache
  - metadata:
      name: runner-tool-cache
      # It turns out labels doesn't distinguish PVs across PVCs and the
      # end result is PVs are reused by wrong PVCs.
      # The correct way seems to be to differentiate storage class per pvc template.
      # labels:
      #   id: runner-tool-cache
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Mi
      storageClassName: ${NAME}-runner-tool-cache
---
apiVersion: actions.summerwind.dev/v1alpha1
kind: HorizontalRunnerAutoscaler
metadata:
  name: ${NAME}
spec:
  scaleTargetRef:
    kind: RunnerSet
    name: ${NAME}
  scaleUpTriggers:
  - githubEvent:
      workflowJob: {}
    amount: 1
    duration: "10m"
  minReplicas: ${RUNNER_MIN_REPLICAS}
  maxReplicas: 10
  scaleDownDelaySecondsAfterScaleOut: ${RUNNER_SCALE_DOWN_DELAY_SECONDS_AFTER_SCALE_OUT}
  # Comment out the whole metrics if you'd like to solely test webhook-based scaling
  metrics:
  - type: PercentageRunnersBusy
    scaleUpThreshold: '0.75'
    scaleDownThreshold: '0.25'
    scaleUpFactor: '2'
    scaleDownFactor: '0.5'
