Compare commits

..

7 Commits

Author SHA1 Message Date
Nikola Jokic ffcaa06b6a Rename Id and Url fields to ID and URL per convention
Validate Helm Chart / Lint Chart (push) Has been cancelled
(gha) Validate Helm Charts / Lint Chart (push) Has been cancelled
(gha) Validate Helm Charts / Test Chart (push) Has been cancelled
2026-01-15 19:16:07 +01:00
Nikola Jokic 0bb603edc8 adding tests checking auth 2026-01-12 15:59:27 +01:00
Nikola Jokic 9e871b42d4 Improve tests 2026-01-12 14:44:43 +01:00
Nikola Jokic 26f573fa80 starting with tests 2026-01-10 01:28:17 +01:00
Nikola Jokic 1ce073b56e moving to chart tests 2026-01-09 17:32:54 +01:00
Nikola Jokic beef400c07 slowly develop nicer helper functions 2026-01-09 13:41:41 +01:00
Nikola Jokic 20e696b6c8 rewriting the gha-runner-scale-set-chart 2026-01-09 11:22:54 +01:00
271 changed files with 9610 additions and 57842 deletions
+1 -1
View File
@@ -79,7 +79,7 @@ jobs:
- name: Create kind cluster
if: steps.list-changed.outputs.changed == 'true'
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab
# We need cert-manager already installed in the cluster because we assume the CRDs exist
- name: Install cert-manager
+3 -1
View File
@@ -47,7 +47,9 @@ jobs:
- name: Install tools
run: |
curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.2.0/kubebuilder_2.2.0_linux_amd64.tar.gz
tar zxvf kubebuilder_2.2.0_linux_amd64.tar.gz
sudo mv kubebuilder_2.2.0_linux_amd64 /usr/local/kubebuilder
curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash
sudo mv kustomize /usr/local/bin
curl -L -O https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_linux_amd64.tar.gz
+1 -1
View File
@@ -70,7 +70,7 @@ jobs:
ct lint --config charts/.ci/ct-config.yaml
- name: Create kind cluster
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab
if: steps.list-changed.outputs.changed == 'true'
# We need cert-manager already installed in the cluster because we assume the CRDs exist
+1 -192
View File
@@ -49,28 +49,6 @@ jobs:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
default-setup-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run default setup test
run: hack/e2e-test.sh default-setup-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
single-namespace-setup:
runs-on: ubuntu-latest
timeout-minutes: 20
@@ -87,34 +65,13 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run single namespace setup test
run: hack/e2e-test.sh single-namespace-setup
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
single-namespace-setup-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run single namespace setup test
run: hack/e2e-test.sh single-namespace-setup-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
dind-mode-setup:
runs-on: ubuntu-latest
timeout-minutes: 20
@@ -131,28 +88,7 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run dind mode setup test
run: hack/e2e-test.sh dind-mode-setup-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
dind-mode-setup-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run dind mode setup test
run: hack/e2e-test.sh dind-mode-setup
env:
@@ -175,28 +111,7 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run kubernetes mode setup test
run: hack/e2e-test.sh kubernetes-mode-setup-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
kubernetes-mode-setup-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run kubernetes mode setup test
run: hack/e2e-test.sh kubernetes-mode-setup
env:
@@ -219,28 +134,7 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run single namespace setup test
run: hack/e2e-test.sh single-namespace-setup-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
auth-proxy-setup-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run single namespace setup test
run: hack/e2e-test.sh single-namespace-setup
env:
@@ -263,28 +157,7 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run anonymous proxy setup test
run: hack/e2e-test.sh anonymous-proxy-setup-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
anonymous-proxy-setup-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run anonymous proxy setup test
run: hack/e2e-test.sh anonymous-proxy-setup
env:
@@ -307,28 +180,7 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run self signed CA setup test
run: hack/e2e-test.sh self-signed-ca-setup-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
self-signed-ca-setup-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run self signed CA setup test
run: hack/e2e-test.sh self-signed-ca-setup
env:
@@ -351,28 +203,7 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run update strategy test
run: hack/e2e-test.sh update-strategy-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
update-strategy-tests-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run update strategy test
run: hack/e2e-test.sh update-strategy
env:
@@ -395,31 +226,9 @@ jobs:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run init with min runners test
run: hack/e2e-test.sh init-with-min-runners-v2
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
init-with-min-runners-v2:
runs-on: ubuntu-latest
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
steps:
- uses: actions/checkout@v6
with:
ref: ${{github.head_ref}}
- name: Get configure token
id: config-token
uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343
with:
application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }}
application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }}
organization: ${{ env.TARGET_ORG }}
- name: Run init with min runners test
run: hack/e2e-test.sh init-with-min-runners
env:
GITHUB_TOKEN: "${{steps.config-token.outputs.token}}"
shell: bash
+4 -111
View File
@@ -23,21 +23,11 @@ on:
required: true
type: boolean
default: false
publish_gha_runner_scale_set_controller_experimental_chart:
description: "Publish new helm chart for gha-runner-scale-set-controller-experimental"
required: true
type: boolean
default: false
publish_gha_runner_scale_set_chart:
description: "Publish new helm chart for gha-runner-scale-set"
required: true
type: boolean
default: false
publish_gha_runner_scale_set_experimental_chart:
description: "Publish new helm chart for gha-runner-scale-set-experimental"
required: true
type: boolean
default: false
env:
HELM_VERSION: v3.8.0
@@ -82,10 +72,10 @@ jobs:
echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435
with:
# Pinning v0.9.1 for Buildx and BuildKit v0.10.6
# BuildKit v0.11 which has a bug causing intermittent
@@ -94,14 +84,14 @@ jobs:
driver-opts: image=moby/buildkit:v0.10.6
- name: Login to GitHub Container Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & push controller image
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
with:
file: Dockerfile
platforms: linux/amd64,linux/arm64
@@ -169,54 +159,6 @@ jobs:
echo "- Short SHA: ${{ steps.resolve_parameters.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY
echo "- gha-runner-scale-set-controller Chart version: ${{ env.GHA_RUNNER_SCALE_SET_CONTROLLER_CHART_VERSION_TAG }}" >> $GITHUB_STEP_SUMMARY
publish-helm-chart-gha-runner-scale-set-controller-experimental:
if: ${{ inputs.publish_gha_runner_scale_set_controller_experimental_chart == true }}
needs: build-push-image
name: Publish Helm chart for gha-runner-scale-set-controller-experimental
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
# If inputs.ref is empty, it'll resolve to the default branch
ref: ${{ inputs.ref }}
- name: Resolve parameters
id: resolve_parameters
run: |
resolvedRef="${{ inputs.ref }}"
if [ -z "$resolvedRef" ]
then
resolvedRef="${{ github.ref }}"
fi
echo "resolved_ref=$resolvedRef" >> $GITHUB_OUTPUT
echo "INFO: Resolving short SHA for $resolvedRef"
echo "short_sha=$(git rev-parse --short $resolvedRef)" >> $GITHUB_OUTPUT
echo "INFO: Normalizing repository name (lowercase)"
echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up Helm
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4
with:
version: ${{ env.HELM_VERSION }}
- name: Publish new helm chart for gha-runner-scale-set-controller-experimental
run: |
echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ghcr.io --username ${{ github.actor }} --password-stdin
GHA_RUNNER_SCALE_SET_CONTROLLER_CHART_VERSION_TAG=$(cat charts/gha-runner-scale-set-controller-experimental/Chart.yaml | grep version: | cut -d " " -d '"' -f 2)
echo "GHA_RUNNER_SCALE_SET_CONTROLLER_CHART_VERSION_TAG=${GHA_RUNNER_SCALE_SET_CONTROLLER_CHART_VERSION_TAG}" >> $GITHUB_ENV
helm package charts/gha-runner-scale-set-controller-experimental/ --version="${GHA_RUNNER_SCALE_SET_CONTROLLER_CHART_VERSION_TAG}"
helm push gha-runner-scale-set-controller-experimental-"${GHA_RUNNER_SCALE_SET_CONTROLLER_CHART_VERSION_TAG}".tgz oci://ghcr.io/${{ steps.resolve_parameters.outputs.repository_owner }}/actions-runner-controller-charts
- name: Job summary
run: |
echo "New helm chart for gha-runner-scale-set-controller-experimental published successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY
echo "- Ref: ${{ steps.resolve_parameters.outputs.resolved_ref }}" >> $GITHUB_STEP_SUMMARY
echo "- Short SHA: ${{ steps.resolve_parameters.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY
echo "- gha-runner-scale-set-controller-experimental Chart version: ${{ env.GHA_RUNNER_SCALE_SET_CONTROLLER_CHART_VERSION_TAG }}" >> $GITHUB_STEP_SUMMARY
publish-helm-chart-gha-runner-scale-set:
if: ${{ inputs.publish_gha_runner_scale_set_chart == true }}
needs: build-push-image
@@ -264,52 +206,3 @@ jobs:
echo "- Ref: ${{ steps.resolve_parameters.outputs.resolvedRef }}" >> $GITHUB_STEP_SUMMARY
echo "- Short SHA: ${{ steps.resolve_parameters.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY
echo "- gha-runner-scale-set Chart version: ${{ env.GHA_RUNNER_SCALE_SET_CHART_VERSION_TAG }}" >> $GITHUB_STEP_SUMMARY
publish-helm-chart-gha-runner-scale-set-experimental:
if: ${{ inputs.publish_gha_runner_scale_set_experimental_chart == true }}
needs: build-push-image
name: Publish Helm chart for gha-runner-scale-set-experimental
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
# If inputs.ref is empty, it'll resolve to the default branch
ref: ${{ inputs.ref }}
- name: Resolve parameters
id: resolve_parameters
run: |
resolvedRef="${{ inputs.ref }}"
if [ -z "$resolvedRef" ]
then
resolvedRef="${{ github.ref }}"
fi
echo "resolved_ref=$resolvedRef" >> $GITHUB_OUTPUT
echo "INFO: Resolving short SHA for $resolvedRef"
echo "short_sha=$(git rev-parse --short $resolvedRef)" >> $GITHUB_OUTPUT
echo "INFO: Normalizing repository name (lowercase)"
echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up Helm
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4
with:
version: ${{ env.HELM_VERSION }}
- name: Publish new helm chart for gha-runner-scale-set-experimental
run: |
echo ${{ secrets.GITHUB_TOKEN }} | helm registry login ghcr.io --username ${{ github.actor }} --password-stdin
GHA_RUNNER_SCALE_SET_CHART_VERSION_TAG=$(cat charts/gha-runner-scale-set-experimental/Chart.yaml | grep version: | cut -d " " -d '"' -f 2)
echo "GHA_RUNNER_SCALE_SET_CHART_VERSION_TAG=${GHA_RUNNER_SCALE_SET_CHART_VERSION_TAG}" >> $GITHUB_ENV
helm package charts/gha-runner-scale-set-experimental/ --version="${GHA_RUNNER_SCALE_SET_CHART_VERSION_TAG}"
helm push gha-runner-scale-set-experimental-"${GHA_RUNNER_SCALE_SET_CHART_VERSION_TAG}".tgz oci://ghcr.io/${{ steps.resolve_parameters.outputs.repository_owner }}/actions-runner-controller-charts
- name: Job summary
run: |
echo "New helm chart for gha-runner-scale-set-experimental published successfully!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY
echo "- Ref: ${{ steps.resolve_parameters.outputs.resolved_ref }}" >> $GITHUB_STEP_SUMMARY
echo "- Short SHA: ${{ steps.resolve_parameters.outputs.short_sha }}" >> $GITHUB_STEP_SUMMARY
echo "- gha-runner-scale-set-experimental Chart version: ${{ env.GHA_RUNNER_SCALE_SET_CHART_VERSION_TAG }}" >> $GITHUB_STEP_SUMMARY
+4 -28
View File
@@ -18,7 +18,7 @@ on:
workflow_dispatch:
env:
KUBE_SCORE_VERSION: 1.16.1
HELM_VERSION: v3.19.4
HELM_VERSION: v3.17.0
permissions:
contents: read
@@ -61,39 +61,19 @@ jobs:
if [[ -n "$changed" ]]; then
echo "changed=true" >> $GITHUB_OUTPUT
fi
echo "changed_charts<<EOF" >> $GITHUB_OUTPUT
echo "$changed" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Install helm-unittest
if: |
contains(steps.list-changed.outputs.changed_charts, 'charts/gha-runner-scale-set-controller-experimental') ||
contains(steps.list-changed.outputs.changed_charts, 'charts/gha-runner-scale-set-experimental')
run: |
helm plugin install https://github.com/helm-unittest/helm-unittest.git
- name: Run helm-unittest (gha-runner-scale-set-controller-experimental)
if: contains(steps.list-changed.outputs.changed_charts, 'charts/gha-runner-scale-set-controller-experimental')
run: |
helm unittest ./charts/gha-runner-scale-set-controller-experimental/
- name: Run helm-unittest (gha-runner-scale-set-experimental)
if: contains(steps.list-changed.outputs.changed_charts, 'charts/gha-runner-scale-set-experimental')
run: |
helm unittest ./charts/gha-runner-scale-set-experimental/
- name: Run chart-testing (lint)
run: |
ct lint --config charts/.ci/ct-config-gha.yaml
- name: Set up docker buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435
if: steps.list-changed.outputs.changed == 'true'
with:
version: latest
- name: Build controller image
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
if: steps.list-changed.outputs.changed == 'true'
with:
file: Dockerfile
@@ -108,7 +88,7 @@ jobs:
cache-to: type=gha,mode=max
- name: Create kind cluster
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab
if: steps.list-changed.outputs.changed == 'true'
with:
cluster_name: chart-testing
@@ -140,7 +120,3 @@ jobs:
run: go test ./charts/gha-runner-scale-set/...
- name: Test gha-runner-scale-set-controller
run: go test ./charts/gha-runner-scale-set-controller/...
- name: Test gha-runner-scale-set-experimental
run: go test ./charts/gha-runner-scale-set-experimental/...
- name: Test gha-runner-scale-set-controller-experimental
run: go test ./charts/gha-runner-scale-set-controller-experimental/...
+4 -4
View File
@@ -93,7 +93,7 @@ jobs:
uses: actions/checkout@v6
- name: Login to GitHub Container Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -110,16 +110,16 @@ jobs:
echo "repository_owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435
with:
version: latest
# Unstable builds - run at your own risk
- name: Build and Push
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
with:
context: .
file: ./Dockerfile
+7 -18
View File
@@ -51,7 +51,7 @@ jobs:
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20
with:
only-new-issues: true
version: v2.11.2
version: v2.5.0
generate:
runs-on: ubuntu-latest
@@ -66,19 +66,6 @@ jobs:
- name: Check diff
run: git diff --exit-code
mocks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: "go.mod"
cache: false
- name: "Run mockery"
run: go tool github.com/vektra/mockery/v3
- name: Check diff
run: git diff --exit-code
test:
runs-on: ubuntu-latest
steps:
@@ -89,11 +76,13 @@ jobs:
- run: make manifests
- name: Check diff
run: git diff --exit-code
- name: Setup envtest
- name: Install kubebuilder
run: |
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@$(go list -m -f '{{ .Version }}' sigs.k8s.io/controller-runtime | awk -F'[v.]' '{printf "release-%d.%d", $2, $3}')
ENVTEST_K8S_VERSION=$(go list -m -f '{{ .Version }}' k8s.io/api | awk -F'[v.]' '{printf "1.%d", $3}')
echo "KUBEBUILDER_ASSETS=$(setup-envtest use ${ENVTEST_K8S_VERSION} -p path)" >> $GITHUB_ENV
curl -D headers.txt -fsL "https://storage.googleapis.com/kubebuilder-tools/kubebuilder-tools-1.30.0-linux-amd64.tar.gz" -o kubebuilder-tools
echo "$(grep -i etag headers.txt -m 1 | cut -d'"' -f2) kubebuilder-tools" > sum
md5sum -c sum
tar -zvxf kubebuilder-tools
sudo mv kubebuilder /usr/local/
- name: Run go tests
run: |
go test -short `go list ./... | grep -v ./test_e2e_arc`
+1 -1
View File
@@ -34,5 +34,5 @@ bin
# OS
.DS_STORE
/test-assets
/.tools
-4
View File
@@ -12,7 +12,3 @@ linters:
exclusions:
presets:
- std-error-handling
rules:
- linters:
- staticcheck
text: "QF1008:"
-17
View File
@@ -1,17 +0,0 @@
all: false
dir: "{{.InterfaceDir}}"
filename: mocks_test.go
force-file-write: true
formatter: goimports
log-level: info
structname: "{{.Mock}}{{.InterfaceName}}"
pkgname: "{{.SrcPackageName}}"
recursive: false
template: testify
packages:
github.com/actions/actions-runner-controller/cmd/ghalistener/metrics:
config:
all: true
github.com/actions/actions-runner-controller/controllers/actions.github.com:
config:
all: true
+1 -1
View File
@@ -1,2 +1,2 @@
# actions-runner-controller maintainers
* @mumoshu @toast-gear @actions/actions-launch @actions/actions-compute @nikola-jokic @rentziass @steve-glass
* @mumoshu @toast-gear @actions/actions-launch @actions/actions-compute @nikola-jokic @rentziass
+7 -4
View File
@@ -102,19 +102,22 @@ A set of example pipelines (./acceptance/pipelines) are provided in this reposit
When raising a PR please run the relevant suites to prove your change hasn't broken anything.
#### Running Ginkgo Tests
You can run the integration test suite that is written in Ginkgo with:
```shell
make test-with-deps
```
This will install `setup-envtest`, download the required envtest binaries (etcd, kube-apiserver, kubectl), and then run `go test`.
This will firstly install a few binaries required to setup the integration test environment and then runs `go test` to start the Ginkgo test.
If you don't want to use `make`, install the envtest binaries using `setup-envtest`:
If you don't want to use `make`, like when you're running tests from your IDE, install required binaries to `/usr/local/kubebuilder/bin`.
That's the directory in which controller-runtime's `envtest` framework locates the binaries.
```shell
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
export KUBEBUILDER_ASSETS=$(setup-envtest use -p path)
sudo mkdir -p /usr/local/kubebuilder/bin
make kube-apiserver etcd
sudo mv test-assets/{etcd,kube-apiserver} /usr/local/kubebuilder/bin/
go test -v -run TestAPIs github.com/actions/actions-runner-controller/controllers/actions.summerwind.net
```
+8 -8
View File
@@ -1,5 +1,5 @@
# Build the manager binary
FROM --platform=$BUILDPLATFORM golang:1.26.1 AS builder
FROM --platform=$BUILDPLATFORM golang:1.25.1 AS builder
WORKDIR /workspace
@@ -34,13 +34,13 @@ ENV GOCACHE="/build/${TARGETPLATFORM}/root/.cache/go-build"
# Build
RUN --mount=target=. \
--mount=type=cache,mode=0777,target=${GOCACHE} \
export GOOS=${TARGETOS} GOARCH=${TARGETARCH} GOARM=${TARGETVARIANT#v} && \
go build -trimpath -ldflags="-s -w -X 'github.com/actions/actions-runner-controller/build.Version=${VERSION}' -X 'github.com/actions/actions-runner-controller/build.CommitSHA=${COMMIT_SHA}'" -o /out/manager main.go && \
go build -trimpath -ldflags="-s -w -X 'github.com/actions/actions-runner-controller/build.Version=${VERSION}' -X 'github.com/actions/actions-runner-controller/build.CommitSHA=${COMMIT_SHA}'" -o /out/ghalistener ./cmd/ghalistener && \
go build -trimpath -ldflags="-s -w" -o /out/github-webhook-server ./cmd/githubwebhookserver && \
go build -trimpath -ldflags="-s -w" -o /out/actions-metrics-server ./cmd/actionsmetricsserver && \
go build -trimpath -ldflags="-s -w" -o /out/sleep ./cmd/sleep
--mount=type=cache,mode=0777,target=${GOCACHE} \
export GOOS=${TARGETOS} GOARCH=${TARGETARCH} GOARM=${TARGETVARIANT#v} && \
go build -trimpath -ldflags="-s -w -X 'github.com/actions/actions-runner-controller/build.Version=${VERSION}' -X 'github.com/actions/actions-runner-controller/build.CommitSHA=${COMMIT_SHA}'" -o /out/manager main.go && \
go build -trimpath -ldflags="-s -w -X 'github.com/actions/actions-runner-controller/build.Version=${VERSION}' -X 'github.com/actions/actions-runner-controller/build.CommitSHA=${COMMIT_SHA}'" -o /out/ghalistener ./cmd/ghalistener && \
go build -trimpath -ldflags="-s -w" -o /out/github-webhook-server ./cmd/githubwebhookserver && \
go build -trimpath -ldflags="-s -w" -o /out/actions-metrics-server ./cmd/actionsmetricsserver && \
go build -trimpath -ldflags="-s -w" -o /out/sleep ./cmd/sleep
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
+81 -41
View File
@@ -6,7 +6,7 @@ endif
DOCKER_USER ?= $(shell echo ${DOCKER_IMAGE_NAME} | cut -d / -f1)
VERSION ?= dev
COMMIT_SHA = $(shell git rev-parse HEAD)
RUNNER_VERSION ?= 2.334.0
RUNNER_VERSION ?= 2.330.0
TARGETPLATFORM ?= $(shell arch)
RUNNER_NAME ?= ${DOCKER_USER}/actions-runner
RUNNER_TAG ?= ${VERSION}
@@ -32,15 +32,21 @@ else
GOBIN=$(shell go env GOBIN)
endif
TEST_ASSETS=$(PWD)/test-assets
TOOLS_PATH=$(PWD)/.tools
OS_NAME := $(shell uname -s | tr A-Z a-z)
# ENVTEST_VERSION is the version of controller-runtime release branch to fetch the envtest setup script
ENVTEST_VERSION ?= $(shell go list -m -f "{{ .Version }}" sigs.k8s.io/controller-runtime | awk -F'[v.]' '{printf "release-%d.%d", $$2, $$3}')
# ENVTEST_K8S_VERSION is the version of Kubernetes to use for setting up ENVTEST binaries
ENVTEST_K8S_VERSION ?= $(shell go list -m -f "{{ .Version }}" k8s.io/api | awk -F'[v.]' '{printf "1.%d", $$3}')
ENVTEST ?= $(GOBIN)/setup-envtest
# The etcd packages that coreos maintain use different extensions for each *nix OS on their github release page.
# ETCD_EXTENSION: the storage format file extension listed on the release page.
# EXTRACT_COMMAND: the appropriate CLI command for extracting this file format.
ifeq ($(OS_NAME), darwin)
ETCD_EXTENSION:=zip
EXTRACT_COMMAND:=unzip
else
ETCD_EXTENSION:=tar.gz
EXTRACT_COMMAND:=tar -xzf
endif
# default list of platforms for which multiarch image is built
ifeq (${PLATFORMS}, )
@@ -62,23 +68,22 @@ endif
all: manager
lint:
docker run --rm -v $(PWD):/app -w /app golangci/golangci-lint:v2.11.2 golangci-lint run
docker run --rm -v $(PWD):/app -w /app golangci/golangci-lint:v2.5.0 golangci-lint run
GO_TEST_ARGS ?= -short
# Run tests
test: generate fmt vet manifests shellcheck setup-envtest
KUBEBUILDER_ASSETS="$$($(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(GOBIN) -p path)" \
go test $(GO_TEST_ARGS) `go list ./... | grep -v ./test_e2e_arc` -coverprofile cover.out
KUBEBUILDER_ASSETS="$$($(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(GOBIN) -p path)" \
go test -fuzz=Fuzz -fuzztime=10s -run=Fuzz* ./controllers/actions.summerwind.net
test: generate fmt vet manifests shellcheck
go test $(GO_TEST_ARGS) `go list ./... | grep -v ./test_e2e_arc` -coverprofile cover.out
go test -fuzz=Fuzz -fuzztime=10s -run=Fuzz* ./controllers/actions.summerwind.net
test-with-deps: setup-envtest
KUBEBUILDER_ASSETS="$$($(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(GOBIN) -p path)" \
test-with-deps: kube-apiserver etcd kubectl
# See https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest#pkg-constants
TEST_ASSET_KUBE_APISERVER=$(KUBE_APISERVER_BIN) \
TEST_ASSET_ETCD=$(ETCD_BIN) \
TEST_ASSET_KUBECTL=$(KUBECTL_BIN) \
make test
# Build manager binary
manager: generate fmt vet
go build -o bin/manager main.go
@@ -177,10 +182,6 @@ chart-crds:
cp config/crd/bases/actions.github.com_autoscalinglisteners.yaml charts/gha-runner-scale-set-controller/crds/
cp config/crd/bases/actions.github.com_ephemeralrunnersets.yaml charts/gha-runner-scale-set-controller/crds/
cp config/crd/bases/actions.github.com_ephemeralrunners.yaml charts/gha-runner-scale-set-controller/crds/
cp config/crd/bases/actions.github.com_autoscalingrunnersets.yaml charts/gha-runner-scale-set-controller-experimental/crds/
cp config/crd/bases/actions.github.com_autoscalinglisteners.yaml charts/gha-runner-scale-set-controller-experimental/crds/
cp config/crd/bases/actions.github.com_ephemeralrunnersets.yaml charts/gha-runner-scale-set-controller-experimental/crds/
cp config/crd/bases/actions.github.com_ephemeralrunners.yaml charts/gha-runner-scale-set-controller-experimental/crds/
rm charts/actions-runner-controller/crds/actions.github.com_autoscalingrunnersets.yaml
rm charts/actions-runner-controller/crds/actions.github.com_autoscalinglisteners.yaml
rm charts/actions-runner-controller/crds/actions.github.com_ephemeralrunnersets.yaml
@@ -308,7 +309,7 @@ github-release: release
# Otherwise we get errors like the below:
# Error: failed to install CRD crds/actions.summerwind.dev_runnersets.yaml: CustomResourceDefinition.apiextensions.k8s.io "runnersets.actions.summerwind.dev" is invalid: [spec.validation.openAPIV3Schema.properties[spec].properties[template].properties[spec].properties[containers].items.properties[ports].items.properties[protocol].default: Required value: this property is in x-kubernetes-list-map-keys, so it must have a default or be a required property, spec.validation.openAPIV3Schema.properties[spec].properties[template].properties[spec].properties[initContainers].items.properties[ports].items.properties[protocol].default: Required value: this property is in x-kubernetes-list-map-keys, so it must have a default or be a required property]
#
# Note that controller-gen newer than 0.8.1 is needed due to https://github.com/kubernetes-sigs/controller-tools/issues/448
# Note that controller-gen newer than 0.8.0 is needed due to https://github.com/kubernetes-sigs/controller-tools/issues/448
# Otherwise ObjectMeta embedded in Spec results in empty on the storage.
controller-gen:
ifeq (, $(shell which controller-gen))
@@ -318,7 +319,7 @@ ifeq (, $(wildcard $(GOBIN)/controller-gen))
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
cd $$CONTROLLER_GEN_TMP_DIR ;\
go mod init tmp ;\
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.20.1 ;\
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.19.0 ;\
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
}
endif
@@ -363,29 +364,68 @@ ifeq (, $(wildcard $(TOOLS_PATH)/shellcheck))
endif
SHELLCHECK=$(TOOLS_PATH)/shellcheck
# find or download envtest
envtest:
ifeq (, $(shell which setup-envtest))
ifeq (, $(wildcard $(GOBIN)/setup-envtest))
# find or download etcd
etcd:
ifeq (, $(shell which etcd))
ifeq (, $(wildcard $(TEST_ASSETS)/etcd))
@{ \
set -e ;\
ENVTEST_TMP_DIR=$$(mktemp -d) ;\
cd $$ENVTEST_TMP_DIR ;\
go mod init tmp ;\
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@$(ENVTEST_VERSION) ;\
rm -rf $$ENVTEST_TMP_DIR ;\
set -xe ;\
INSTALL_TMP_DIR=$$(mktemp -d) ;\
cd $$INSTALL_TMP_DIR ;\
wget https://github.com/coreos/etcd/releases/download/v3.4.22/etcd-v3.4.22-$(OS_NAME)-amd64.$(ETCD_EXTENSION);\
mkdir -p $(TEST_ASSETS) ;\
$(EXTRACT_COMMAND) etcd-v3.4.22-$(OS_NAME)-amd64.$(ETCD_EXTENSION) ;\
mv etcd-v3.4.22-$(OS_NAME)-amd64/etcd $(TEST_ASSETS)/etcd ;\
rm -rf $$INSTALL_TMP_DIR ;\
}
endif
ENVTEST=$(GOBIN)/setup-envtest
ETCD_BIN=$(TEST_ASSETS)/etcd
else
ENVTEST=$(shell which setup-envtest)
ETCD_BIN=$(TEST_ASSETS)/etcd
endif
else
ETCD_BIN=$(shell which etcd)
endif
.PHONY: setup-envtest
setup-envtest: envtest
@echo "Setting up envtest binaries for Kubernetes version $(ENVTEST_K8S_VERSION)..."
@$(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(GOBIN) -p path || { \
echo "Error: Failed to set up envtest binaries for version $(ENVTEST_K8S_VERSION)."; \
exit 1; \
# find or download kube-apiserver
kube-apiserver:
ifeq (, $(shell which kube-apiserver))
ifeq (, $(wildcard $(TEST_ASSETS)/kube-apiserver))
@{ \
set -xe ;\
INSTALL_TMP_DIR=$$(mktemp -d) ;\
cd $$INSTALL_TMP_DIR ;\
wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.3.2/kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
mkdir -p $(TEST_ASSETS) ;\
tar zxvf kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kube-apiserver $(TEST_ASSETS)/kube-apiserver ;\
rm -rf $$INSTALL_TMP_DIR ;\
}
KUBE_APISERVER_BIN=$(TEST_ASSETS)/kube-apiserver
else
KUBE_APISERVER_BIN=$(TEST_ASSETS)/kube-apiserver
endif
else
KUBE_APISERVER_BIN=$(shell which kube-apiserver)
endif
# find or download kubectl
kubectl:
ifeq (, $(shell which kubectl))
ifeq (, $(wildcard $(TEST_ASSETS)/kubectl))
@{ \
set -xe ;\
INSTALL_TMP_DIR=$$(mktemp -d) ;\
cd $$INSTALL_TMP_DIR ;\
wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.3.2/kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
mkdir -p $(TEST_ASSETS) ;\
tar zxvf kubebuilder_2.3.2_$(OS_NAME)_amd64.tar.gz ;\
mv kubebuilder_2.3.2_$(OS_NAME)_amd64/bin/kubectl $(TEST_ASSETS)/kubectl ;\
rm -rf $$INSTALL_TMP_DIR ;\
}
KUBECTL_BIN=$(TEST_ASSETS)/kubectl
else
KUBECTL_BIN=$(TEST_ASSETS)/kubectl
endif
else
KUBECTL_BIN=$(shell which kubectl)
endif
@@ -24,13 +24,13 @@ import (
// AutoscalingListenerSpec defines the desired state of AutoscalingListener
type AutoscalingListenerSpec struct {
// Required
GitHubConfigUrl string `json:"githubConfigUrl,omitempty"`
GitHubConfigURL string `json:"githubConfigUrl,omitempty"`
// Required
GitHubConfigSecret string `json:"githubConfigSecret,omitempty"`
// Required
RunnerScaleSetId int `json:"runnerScaleSetId,omitempty"`
RunnerScaleSetID int `json:"runnerScaleSetId,omitempty"`
// Required
AutoscalingRunnerSetNamespace string `json:"autoscalingRunnerSetNamespace,omitempty"`
@@ -69,18 +69,6 @@ type AutoscalingListenerSpec struct {
// +optional
Template *corev1.PodTemplateSpec `json:"template,omitempty"`
// +optional
ConfigSecretMetadata *ResourceMeta `json:"configSecretMetadata,omitempty"`
// +optional
ServiceAccountMetadata *ResourceMeta `json:"serviceAccountMetadata,omitempty"`
// +optional
RoleMetadata *ResourceMeta `json:"roleMetadata,omitempty"`
// +optional
RoleBindingMetadata *ResourceMeta `json:"roleBindingMetadata,omitempty"`
}
// AutoscalingListenerStatus defines the observed state of AutoscalingListener
@@ -46,16 +46,16 @@ import (
// AutoscalingRunnerSet is the Schema for the autoscalingrunnersets API
type AutoscalingRunnerSet struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
metav1.ObjectMeta `json:"metadata"`
Spec AutoscalingRunnerSetSpec `json:"spec,omitempty"`
Status AutoscalingRunnerSetStatus `json:"status,omitempty"`
Spec AutoscalingRunnerSetSpec `json:"spec"`
Status AutoscalingRunnerSetStatus `json:"status"`
}
// AutoscalingRunnerSetSpec defines the desired state of AutoscalingRunnerSet
type AutoscalingRunnerSetSpec struct {
// Required
GitHubConfigUrl string `json:"githubConfigUrl,omitempty"`
GitHubConfigURL string `json:"githubConfigUrl,omitempty"`
// Required
GitHubConfigSecret string `json:"githubConfigSecret,omitempty"`
@@ -66,9 +66,6 @@ type AutoscalingRunnerSetSpec struct {
// +optional
RunnerScaleSetName string `json:"runnerScaleSetName,omitempty"`
// +optional
RunnerScaleSetLabels []string `json:"runnerScaleSetLabels,omitempty"`
// +optional
Proxy *ProxyConfig `json:"proxy,omitempty"`
@@ -79,10 +76,7 @@ type AutoscalingRunnerSetSpec struct {
VaultConfig *VaultConfig `json:"vaultConfig,omitempty"`
// Required
Template corev1.PodTemplateSpec `json:"template,omitempty"`
// +optional
AutoscalingListenerMetadata *ResourceMeta `json:"autoscalingListener,omitempty"`
Template corev1.PodTemplateSpec `json:"template"`
// +optional
ListenerMetrics *MetricsConfig `json:"listenerMetrics,omitempty"`
@@ -90,27 +84,6 @@ type AutoscalingRunnerSetSpec struct {
// +optional
ListenerTemplate *corev1.PodTemplateSpec `json:"listenerTemplate,omitempty"`
// +optional
ListenerServiceAccountMetadata *ResourceMeta `json:"listenerServiceAccountMetadata,omitempty"`
// +optional
ListenerRoleMetadata *ResourceMeta `json:"listenerRoleMetadata,omitempty"`
// +optional
ListenerRoleBindingMetadata *ResourceMeta `json:"listenerRoleBindingMetadata,omitempty"`
// +optional
ListenerConfigSecretMetadata *ResourceMeta `json:"listenerConfigSecretMetadata,omitempty"`
// +optional
EphemeralRunnerSetMetadata *ResourceMeta `json:"ephemeralRunnerSetMetadata,omitempty"`
// +optional
EphemeralRunnerMetadata *ResourceMeta `json:"ephemeralRunnerMetadata,omitempty"`
// +optional
EphemeralRunnerConfigSecretMetadata *ResourceMeta `json:"ephemeralRunnerConfigSecretMetadata,omitempty"`
// +optional
// +kubebuilder:validation:Minimum:=0
MaxRunners *int `json:"maxRunners,omitempty"`
@@ -179,9 +152,9 @@ func (c *ProxyConfig) ToHTTPProxyConfig(secretFetcher func(string) (*corev1.Secr
}
if c.HTTP != nil {
u, err := url.Parse(c.HTTP.Url)
u, err := url.Parse(c.HTTP.URL)
if err != nil {
return nil, fmt.Errorf("failed to parse proxy http url %q: %w", c.HTTP.Url, err)
return nil, fmt.Errorf("failed to parse proxy http url %q: %w", c.HTTP.URL, err)
}
if c.HTTP.CredentialSecretRef != "" {
@@ -204,9 +177,9 @@ func (c *ProxyConfig) ToHTTPProxyConfig(secretFetcher func(string) (*corev1.Secr
}
if c.HTTPS != nil {
u, err := url.Parse(c.HTTPS.Url)
u, err := url.Parse(c.HTTPS.URL)
if err != nil {
return nil, fmt.Errorf("failed to parse proxy https url %q: %w", c.HTTPS.Url, err)
return nil, fmt.Errorf("failed to parse proxy https url %q: %w", c.HTTPS.URL, err)
}
if c.HTTPS.CredentialSecretRef != "" {
@@ -260,7 +233,7 @@ func (c *ProxyConfig) ProxyFunc(secretFetcher func(string) (*corev1.Secret, erro
type ProxyServerConfig struct {
// Required
Url string `json:"url,omitempty"`
URL string `json:"url,omitempty"`
// +optional
CredentialSecretRef string `json:"credentialSecretRef,omitempty"`
@@ -318,7 +291,7 @@ type AutoscalingRunnerSetStatus struct {
CurrentRunners int `json:"currentRunners"`
// +optional
Phase AutoscalingRunnerSetPhase `json:"phase"`
State string `json:"state"`
// EphemeralRunner counts separated by the stage ephemeral runners are in, taken from the EphemeralRunnerSet
@@ -330,30 +303,6 @@ type AutoscalingRunnerSetStatus struct {
FailedEphemeralRunners int `json:"failedEphemeralRunners"`
}
type AutoscalingRunnerSetPhase string
const (
// AutoscalingRunnerSetPhasePending phase means that the listener is not
// yet started
AutoscalingRunnerSetPhasePending AutoscalingRunnerSetPhase = "Pending"
AutoscalingRunnerSetPhaseRunning AutoscalingRunnerSetPhase = "Running"
AutoscalingRunnerSetPhaseOutdated AutoscalingRunnerSetPhase = "Outdated"
)
func (ars *AutoscalingRunnerSet) Hash() string {
type data struct {
Spec *AutoscalingRunnerSetSpec
Labels map[string]string
}
d := &data{
Spec: ars.Spec.DeepCopy(),
Labels: ars.Labels,
}
return hash.ComputeTemplateHash(d)
}
func (ars *AutoscalingRunnerSet) ListenerSpecHash() string {
arsSpec := ars.Spec.DeepCopy()
spec := arsSpec
@@ -364,8 +313,8 @@ func (ars *AutoscalingRunnerSet) GitHubConfigSecret() string {
return ars.Spec.GitHubConfigSecret
}
func (ars *AutoscalingRunnerSet) GitHubConfigUrl() string {
return ars.Spec.GitHubConfigUrl
func (ars *AutoscalingRunnerSet) GitHubConfigURL() string {
return ars.Spec.GitHubConfigURL
}
func (ars *AutoscalingRunnerSet) GitHubProxy() *ProxyConfig {
@@ -389,7 +338,7 @@ func (ars *AutoscalingRunnerSet) VaultProxy() *ProxyConfig {
func (ars *AutoscalingRunnerSet) RunnerSetSpecHash() string {
type runnerSetSpec struct {
GitHubConfigUrl string
GitHubConfigURL string
GitHubConfigSecret string
RunnerGroup string
RunnerScaleSetName string
@@ -398,7 +347,7 @@ func (ars *AutoscalingRunnerSet) RunnerSetSpecHash() string {
Template corev1.PodTemplateSpec
}
spec := &runnerSetSpec{
GitHubConfigUrl: ars.Spec.GitHubConfigUrl,
GitHubConfigURL: ars.Spec.GitHubConfigURL,
GitHubConfigSecret: ars.Spec.GitHubConfigSecret,
RunnerGroup: ars.Spec.RunnerGroup,
RunnerScaleSetName: ars.Spec.RunnerScaleSetName,
@@ -414,7 +363,7 @@ func (ars *AutoscalingRunnerSet) RunnerSetSpecHash() string {
// AutoscalingRunnerSetList contains a list of AutoscalingRunnerSet
type AutoscalingRunnerSetList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
metav1.ListMeta `json:"metadata"`
Items []AutoscalingRunnerSet `json:"items"`
}
@@ -1,9 +0,0 @@
package v1alpha1
// ResourceMeta carries metadata common to all internal resources
type ResourceMeta struct {
// +optional
Labels map[string]string `json:"labels,omitempty"`
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
}
@@ -41,14 +41,14 @@ const EphemeralRunnerContainerName = "runner"
// EphemeralRunner is the Schema for the ephemeralrunners API
type EphemeralRunner struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
metav1.ObjectMeta `json:"metadata"`
Spec EphemeralRunnerSpec `json:"spec,omitempty"`
Status EphemeralRunnerStatus `json:"status,omitempty"`
Spec EphemeralRunnerSpec `json:"spec"`
Status EphemeralRunnerStatus `json:"status"`
}
func (er *EphemeralRunner) IsDone() bool {
return er.Status.Phase == EphemeralRunnerPhaseSucceeded || er.Status.Phase == EphemeralRunnerPhaseFailed || er.Status.Phase == EphemeralRunnerPhaseOutdated
return er.Status.Phase == corev1.PodSucceeded || er.Status.Phase == corev1.PodFailed
}
func (er *EphemeralRunner) HasJob() bool {
@@ -76,8 +76,8 @@ func (er *EphemeralRunner) GitHubConfigSecret() string {
return er.Spec.GitHubConfigSecret
}
func (er *EphemeralRunner) GitHubConfigUrl() string {
return er.Spec.GitHubConfigUrl
func (er *EphemeralRunner) GitHubConfigURL() string {
return er.Spec.GitHubConfigURL
}
func (er *EphemeralRunner) GitHubProxy() *ProxyConfig {
@@ -102,7 +102,7 @@ func (er *EphemeralRunner) VaultProxy() *ProxyConfig {
// EphemeralRunnerSpec defines the desired state of EphemeralRunner
type EphemeralRunnerSpec struct {
// +required
GitHubConfigUrl string `json:"githubConfigUrl,omitempty"`
GitHubConfigURL string `json:"githubConfigUrl,omitempty"`
// +required
GitHubConfigSecret string `json:"githubConfigSecret,omitempty"`
@@ -122,9 +122,6 @@ type EphemeralRunnerSpec struct {
// +optional
VaultConfig *VaultConfig `json:"vaultConfig,omitempty"`
// +optional
EphemeralRunnerConfigSecretMetadata *ResourceMeta `json:"ephemeralRunnerConfigSecretMetadata,omitempty"`
corev1.PodTemplateSpec `json:",inline"`
}
@@ -143,7 +140,7 @@ type EphemeralRunnerStatus struct {
// The PodSucceded phase should be set only when confirmed that EphemeralRunner
// actually executed the job and has been removed from the service.
// +optional
Phase EphemeralRunnerPhase `json:"phase,omitempty"`
Phase corev1.PodPhase `json:"phase,omitempty"`
// +optional
Reason string `json:"reason,omitempty"`
// +optional
@@ -176,27 +173,6 @@ type EphemeralRunnerStatus struct {
JobDisplayName string `json:"jobDisplayName,omitempty"`
}
// EphemeralRunnerPhase is the phase of the ephemeral runner.
// It must be a superset of the pod phase.
type EphemeralRunnerPhase string
const (
// EphemeralRunnerPhasePending is a phase set when the ephemeral runner is
// being provisioned and is not yet online.
EphemeralRunnerPhasePending EphemeralRunnerPhase = "Pending"
// EphemeralRunnerPhaseRunning is a phase set when the ephemeral runner is online and
// waiting for a job to execute.
EphemeralRunnerPhaseRunning EphemeralRunnerPhase = "Running"
// EphemeralRunnerPhaseSucceeded is a phase set when the ephemeral runner
// successfully executed the job and has been removed from the service.
EphemeralRunnerPhaseSucceeded EphemeralRunnerPhase = "Succeeded"
// EphemeralRunnerPhaseFailed is a phase set when the ephemeral runner
// fails with unrecoverable failure.
EphemeralRunnerPhaseFailed EphemeralRunnerPhase = "Failed"
// EphemeralRunnerPhaseOutdated is a special phase that indicates the runner is outdated and should be upgraded.
EphemeralRunnerPhaseOutdated EphemeralRunnerPhase = "Outdated"
)
func (s *EphemeralRunnerStatus) LastFailure() metav1.Time {
var maxTime metav1.Time
if len(s.Failures) == 0 {
@@ -216,7 +192,7 @@ func (s *EphemeralRunnerStatus) LastFailure() metav1.Time {
// EphemeralRunnerList contains a list of EphemeralRunner
type EphemeralRunnerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
metav1.ListMeta `json:"metadata"`
Items []EphemeralRunner `json:"items"`
}
@@ -27,9 +27,7 @@ type EphemeralRunnerSetSpec struct {
// PatchID is the unique identifier for the patch issued by the listener app
PatchID int `json:"patchID"`
// EphemeralRunnerSpec is the spec of the ephemeral runner
EphemeralRunnerSpec EphemeralRunnerSpec `json:"ephemeralRunnerSpec,omitempty"`
// +optional
EphemeralRunnerMetadata *ResourceMeta `json:"ephemeralRunnerMetadata,omitempty"`
EphemeralRunnerSpec EphemeralRunnerSpec `json:"ephemeralRunnerSpec"`
}
// EphemeralRunnerSetStatus defines the observed state of EphemeralRunnerSet
@@ -42,20 +40,8 @@ type EphemeralRunnerSetStatus struct {
RunningEphemeralRunners int `json:"runningEphemeralRunners"`
// +optional
FailedEphemeralRunners int `json:"failedEphemeralRunners"`
// +optional
Phase EphemeralRunnerSetPhase `json:"phase"`
}
// EphemeralRunnerSetPhase is the phase of the ephemeral runner set resource
type EphemeralRunnerSetPhase string
const (
EphemeralRunnerSetPhaseRunning EphemeralRunnerSetPhase = "Running"
// EphemeralRunnerSetPhaseOutdated is set when at least one ephemeral runner
// contains the outdated phase
EphemeralRunnerSetPhaseOutdated EphemeralRunnerSetPhase = "Outdated"
)
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:JSONPath=".spec.replicas",name="DesiredReplicas",type="integer"
@@ -68,18 +54,18 @@ const (
// EphemeralRunnerSet is the Schema for the ephemeralrunnersets API
type EphemeralRunnerSet struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
metav1.ObjectMeta `json:"metadata"`
Spec EphemeralRunnerSetSpec `json:"spec,omitempty"`
Status EphemeralRunnerSetStatus `json:"status,omitempty"`
Spec EphemeralRunnerSetSpec `json:"spec"`
Status EphemeralRunnerSetStatus `json:"status"`
}
func (ers *EphemeralRunnerSet) GitHubConfigSecret() string {
return ers.Spec.EphemeralRunnerSpec.GitHubConfigSecret
}
func (ers *EphemeralRunnerSet) GitHubConfigUrl() string {
return ers.Spec.EphemeralRunnerSpec.GitHubConfigUrl
func (ers *EphemeralRunnerSet) GitHubConfigURL() string {
return ers.Spec.EphemeralRunnerSpec.GitHubConfigURL
}
func (ers *EphemeralRunnerSet) GitHubProxy() *ProxyConfig {
@@ -105,7 +91,7 @@ func (ers *EphemeralRunnerSet) VaultProxy() *ProxyConfig {
// +kubebuilder:object:root=true
type EphemeralRunnerSetList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
metav1.ListMeta `json:"metadata"`
Items []EphemeralRunnerSet `json:"items"`
}
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1 contains API Schema definitions for the batch v1 API group
// Package v1alpha1 contains API Schema definitions for the batch v1 API group
// +kubebuilder:object:generate=true
// +groupName=actions.github.com
package v1alpha1
@@ -14,11 +14,11 @@ import (
func TestProxyConfig_ToSecret(t *testing.T) {
config := &v1alpha1.ProxyConfig{
HTTP: &v1alpha1.ProxyServerConfig{
Url: "http://proxy.example.com:8080",
URL: "http://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
HTTPS: &v1alpha1.ProxyServerConfig{
Url: "https://proxy.example.com:8080",
URL: "https://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
NoProxy: []string{
@@ -48,11 +48,11 @@ func TestProxyConfig_ToSecret(t *testing.T) {
func TestProxyConfig_ProxyFunc(t *testing.T) {
config := &v1alpha1.ProxyConfig{
HTTP: &v1alpha1.ProxyServerConfig{
Url: "http://proxy.example.com:8080",
URL: "http://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
HTTPS: &v1alpha1.ProxyServerConfig{
Url: "https://proxy.example.com:8080",
URL: "https://proxy.example.com:8080",
CredentialSecretRef: "my-secret",
},
NoProxy: []string{
@@ -0,0 +1,105 @@
package v1alpha1_test
import (
"crypto/tls"
"crypto/x509"
"net/http"
"os"
"path/filepath"
"testing"
"github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1"
"github.com/actions/actions-runner-controller/github/actions/testserver"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
)
func TestGitHubServerTLSConfig_ToCertPool(t *testing.T) {
t.Run("returns an error if CertificateFrom not specified", func(t *testing.T) {
c := &v1alpha1.TLSConfig{
CertificateFrom: nil,
}
pool, err := c.ToCertPool(nil)
assert.Nil(t, pool)
require.Error(t, err)
assert.Equal(t, err.Error(), "certificateFrom not specified")
})
t.Run("returns an error if CertificateFrom.ConfigMapKeyRef not specified", func(t *testing.T) {
c := &v1alpha1.TLSConfig{
CertificateFrom: &v1alpha1.TLSCertificateSource{},
}
pool, err := c.ToCertPool(nil)
assert.Nil(t, pool)
require.Error(t, err)
assert.Equal(t, err.Error(), "configMapKeyRef not specified")
})
t.Run("returns a valid cert pool with correct configuration", func(t *testing.T) {
c := &v1alpha1.TLSConfig{
CertificateFrom: &v1alpha1.TLSCertificateSource{
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: "name",
},
Key: "key",
},
},
}
certsFolder := filepath.Join(
"../../../",
"github",
"actions",
"testdata",
)
fetcher := func(name, key string) ([]byte, error) {
cert, err := os.ReadFile(filepath.Join(certsFolder, "rootCA.crt"))
require.NoError(t, err)
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM(cert)
assert.True(t, ok)
return cert, nil
}
pool, err := c.ToCertPool(fetcher)
require.NoError(t, err)
require.NotNil(t, pool)
// can be used to communicate with a server
serverSuccessfullyCalled := false
server := testserver.NewUnstarted(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
serverSuccessfullyCalled = true
w.WriteHeader(http.StatusOK)
}))
cert, err := tls.LoadX509KeyPair(
filepath.Join(certsFolder, "server.crt"),
filepath.Join(certsFolder, "server.key"),
)
require.NoError(t, err)
server.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
server.StartTLS()
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: pool,
},
},
}
_, err = client.Get(server.URL)
assert.NoError(t, err)
assert.True(t, serverSuccessfullyCalled)
})
}
@@ -118,26 +118,6 @@ func (in *AutoscalingListenerSpec) DeepCopyInto(out *AutoscalingListenerSpec) {
*out = new(v1.PodTemplateSpec)
(*in).DeepCopyInto(*out)
}
if in.ConfigSecretMetadata != nil {
in, out := &in.ConfigSecretMetadata, &out.ConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ServiceAccountMetadata != nil {
in, out := &in.ServiceAccountMetadata, &out.ServiceAccountMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.RoleMetadata != nil {
in, out := &in.RoleMetadata, &out.RoleMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.RoleBindingMetadata != nil {
in, out := &in.RoleBindingMetadata, &out.RoleBindingMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoscalingListenerSpec.
@@ -227,11 +207,6 @@ func (in *AutoscalingRunnerSetList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AutoscalingRunnerSetSpec) DeepCopyInto(out *AutoscalingRunnerSetSpec) {
*out = *in
if in.RunnerScaleSetLabels != nil {
in, out := &in.RunnerScaleSetLabels, &out.RunnerScaleSetLabels
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Proxy != nil {
in, out := &in.Proxy, &out.Proxy
*out = new(ProxyConfig)
@@ -248,11 +223,6 @@ func (in *AutoscalingRunnerSetSpec) DeepCopyInto(out *AutoscalingRunnerSetSpec)
(*in).DeepCopyInto(*out)
}
in.Template.DeepCopyInto(&out.Template)
if in.AutoscalingListenerMetadata != nil {
in, out := &in.AutoscalingListenerMetadata, &out.AutoscalingListenerMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerMetrics != nil {
in, out := &in.ListenerMetrics, &out.ListenerMetrics
*out = new(MetricsConfig)
@@ -263,41 +233,6 @@ func (in *AutoscalingRunnerSetSpec) DeepCopyInto(out *AutoscalingRunnerSetSpec)
*out = new(v1.PodTemplateSpec)
(*in).DeepCopyInto(*out)
}
if in.ListenerServiceAccountMetadata != nil {
in, out := &in.ListenerServiceAccountMetadata, &out.ListenerServiceAccountMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerRoleMetadata != nil {
in, out := &in.ListenerRoleMetadata, &out.ListenerRoleMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerRoleBindingMetadata != nil {
in, out := &in.ListenerRoleBindingMetadata, &out.ListenerRoleBindingMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerConfigSecretMetadata != nil {
in, out := &in.ListenerConfigSecretMetadata, &out.ListenerConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.EphemeralRunnerSetMetadata != nil {
in, out := &in.EphemeralRunnerSetMetadata, &out.EphemeralRunnerSetMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.EphemeralRunnerMetadata != nil {
in, out := &in.EphemeralRunnerMetadata, &out.EphemeralRunnerMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.EphemeralRunnerConfigSecretMetadata != nil {
in, out := &in.EphemeralRunnerConfigSecretMetadata, &out.EphemeralRunnerConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.MaxRunners != nil {
in, out := &in.MaxRunners, &out.MaxRunners
*out = new(int)
@@ -492,11 +427,6 @@ func (in *EphemeralRunnerSetList) DeepCopyObject() runtime.Object {
func (in *EphemeralRunnerSetSpec) DeepCopyInto(out *EphemeralRunnerSetSpec) {
*out = *in
in.EphemeralRunnerSpec.DeepCopyInto(&out.EphemeralRunnerSpec)
if in.EphemeralRunnerMetadata != nil {
in, out := &in.EphemeralRunnerMetadata, &out.EphemeralRunnerMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EphemeralRunnerSetSpec.
@@ -542,11 +472,6 @@ func (in *EphemeralRunnerSpec) DeepCopyInto(out *EphemeralRunnerSpec) {
*out = new(VaultConfig)
(*in).DeepCopyInto(*out)
}
if in.EphemeralRunnerConfigSecretMetadata != nil {
in, out := &in.EphemeralRunnerConfigSecretMetadata, &out.EphemeralRunnerConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
in.PodTemplateSpec.DeepCopyInto(&out.PodTemplateSpec)
}
@@ -735,35 +660,6 @@ func (in *ProxyServerConfig) DeepCopy() *ProxyServerConfig {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceMeta) DeepCopyInto(out *ResourceMeta) {
*out = *in
if in.Labels != nil {
in, out := &in.Labels, &out.Labels
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Annotations != nil {
in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMeta.
func (in *ResourceMeta) DeepCopy() *ResourceMeta {
if in == nil {
return nil
}
out := new(ResourceMeta)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSCertificateSource) DeepCopyInto(out *TLSCertificateSource) {
*out = *in
@@ -18,11 +18,14 @@ package v1alpha1
import (
"context"
"fmt"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)
@@ -30,7 +33,8 @@ import (
var runnerLog = logf.Log.WithName("runner-resource")
func (r *Runner) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr, r).
return ctrl.NewWebhookManagedBy(mgr).
For(r).
WithDefaulter(&RunnerDefaulter{}).
WithValidator(&RunnerValidator{}).
Complete()
@@ -38,35 +42,44 @@ func (r *Runner) SetupWebhookWithManager(mgr ctrl.Manager) error {
// +kubebuilder:webhook:path=/mutate-actions-summerwind-dev-v1alpha1-runner,verbs=create;update,mutating=true,failurePolicy=fail,groups=actions.summerwind.dev,resources=runners,versions=v1alpha1,name=mutate.runner.actions.summerwind.dev,sideEffects=None,admissionReviewVersions=v1beta1
var _ admission.Defaulter[*Runner] = &RunnerDefaulter{}
var _ webhook.CustomDefaulter = &RunnerDefaulter{}
type RunnerDefaulter struct{}
// Default implements [admission.Defaulter].
func (in *RunnerDefaulter) Default(ctx context.Context, obj *Runner) error {
// Default implements webhook.Defaulter so a webhook will be registered for the type
func (*RunnerDefaulter) Default(ctx context.Context, obj runtime.Object) error {
// Nothing to do.
return nil
}
// +kubebuilder:webhook:path=/validate-actions-summerwind-dev-v1alpha1-runner,verbs=create;update,mutating=false,failurePolicy=fail,groups=actions.summerwind.dev,resources=runners,versions=v1alpha1,name=validate.runner.actions.summerwind.dev,sideEffects=None,admissionReviewVersions=v1beta1
var _ admission.Validator[*Runner] = &RunnerValidator{}
var _ webhook.CustomValidator = &RunnerValidator{}
type RunnerValidator struct{}
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (*RunnerValidator) ValidateCreate(ctx context.Context, r *Runner) (admission.Warnings, error) {
func (*RunnerValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
r, ok := obj.(*Runner)
if !ok {
return nil, fmt.Errorf("expected Runner object, got %T", obj)
}
runnerLog.Info("validate resource to be created", "name", r.Name)
return nil, r.Validate()
}
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (*RunnerValidator) ValidateUpdate(ctx context.Context, old, r *Runner) (admission.Warnings, error) {
func (*RunnerValidator) ValidateUpdate(ctx context.Context, old, obj runtime.Object) (admission.Warnings, error) {
r, ok := obj.(*Runner)
if !ok {
return nil, fmt.Errorf("expected Runner object, got %T", obj)
}
runnerLog.Info("validate resource to be updated", "name", r.Name)
return nil, r.Validate()
}
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (*RunnerValidator) ValidateDelete(ctx context.Context, obj *Runner) (admission.Warnings, error) {
func (*RunnerValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
return nil, nil
}
@@ -18,11 +18,14 @@ package v1alpha1
import (
"context"
"fmt"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)
@@ -30,7 +33,8 @@ import (
var runnerDeploymentLog = logf.Log.WithName("runnerdeployment-resource")
func (r *RunnerDeployment) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr, r).
return ctrl.NewWebhookManagedBy(mgr).
For(r).
WithDefaulter(&RunnerDeploymentDefaulter{}).
WithValidator(&RunnerDeploymentValidator{}).
Complete()
@@ -38,36 +42,44 @@ func (r *RunnerDeployment) SetupWebhookWithManager(mgr ctrl.Manager) error {
// +kubebuilder:webhook:path=/mutate-actions-summerwind-dev-v1alpha1-runnerdeployment,verbs=create;update,mutating=true,failurePolicy=fail,groups=actions.summerwind.dev,resources=runnerdeployments,versions=v1alpha1,name=mutate.runnerdeployment.actions.summerwind.dev,sideEffects=None,admissionReviewVersions=v1beta1
var _ admission.Defaulter[*RunnerDeployment] = &RunnerDeploymentDefaulter{}
var _ webhook.CustomDefaulter = &RunnerDeploymentDefaulter{}
type RunnerDeploymentDefaulter struct{}
// Default implements webhook.Defaulter so a webhook will be registered for the type
func (*RunnerDeploymentDefaulter) Default(context.Context, *RunnerDeployment) error {
func (*RunnerDeploymentDefaulter) Default(context.Context, runtime.Object) error {
// Nothing to do.
return nil
}
// +kubebuilder:webhook:path=/validate-actions-summerwind-dev-v1alpha1-runnerdeployment,verbs=create;update,mutating=false,failurePolicy=fail,groups=actions.summerwind.dev,resources=runnerdeployments,versions=v1alpha1,name=validate.runnerdeployment.actions.summerwind.dev,sideEffects=None,admissionReviewVersions=v1beta1
var _ admission.Validator[*RunnerDeployment] = &RunnerDeploymentValidator{}
var _ webhook.CustomValidator = &RunnerDeploymentValidator{}
type RunnerDeploymentValidator struct{}
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (*RunnerDeploymentValidator) ValidateCreate(ctx context.Context, r *RunnerDeployment) (admission.Warnings, error) {
func (*RunnerDeploymentValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
r, ok := obj.(*RunnerDeployment)
if !ok {
return nil, fmt.Errorf("expected RunnerDeployment object, got %T", obj)
}
runnerDeploymentLog.Info("validate resource to be created", "name", r.Name)
return nil, r.Validate()
}
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (*RunnerDeploymentValidator) ValidateUpdate(ctx context.Context, old, r *RunnerDeployment) (admission.Warnings, error) {
func (*RunnerDeploymentValidator) ValidateUpdate(ctx context.Context, old, obj runtime.Object) (admission.Warnings, error) {
r, ok := obj.(*RunnerDeployment)
if !ok {
return nil, fmt.Errorf("expected RunnerDeployment object, got %T", obj)
}
runnerDeploymentLog.Info("validate resource to be updated", "name", r.Name)
return nil, r.Validate()
}
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (*RunnerDeploymentValidator) ValidateDelete(context.Context, *RunnerDeployment) (admission.Warnings, error) {
func (*RunnerDeploymentValidator) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) {
return nil, nil
}
@@ -18,11 +18,14 @@ package v1alpha1
import (
"context"
"fmt"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)
@@ -30,7 +33,8 @@ import (
var runnerReplicaSetLog = logf.Log.WithName("runnerreplicaset-resource")
func (r *RunnerReplicaSet) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr, r).
return ctrl.NewWebhookManagedBy(mgr).
For(r).
WithDefaulter(&RunnerReplicaSetDefaulter{}).
WithValidator(&RunnerReplicaSetValidator{}).
Complete()
@@ -38,36 +42,44 @@ func (r *RunnerReplicaSet) SetupWebhookWithManager(mgr ctrl.Manager) error {
// +kubebuilder:webhook:path=/mutate-actions-summerwind-dev-v1alpha1-runnerreplicaset,verbs=create;update,mutating=true,failurePolicy=fail,groups=actions.summerwind.dev,resources=runnerreplicasets,versions=v1alpha1,name=mutate.runnerreplicaset.actions.summerwind.dev,sideEffects=None,admissionReviewVersions=v1beta1
var _ admission.Defaulter[*RunnerReplicaSet] = &RunnerReplicaSetDefaulter{}
var _ webhook.CustomDefaulter = &RunnerReplicaSetDefaulter{}
type RunnerReplicaSetDefaulter struct{}
// Default implements webhook.Defaulter so a webhook will be registered for the type
func (*RunnerReplicaSetDefaulter) Default(context.Context, *RunnerReplicaSet) error {
func (*RunnerReplicaSetDefaulter) Default(context.Context, runtime.Object) error {
// Nothing to do.
return nil
}
// +kubebuilder:webhook:path=/validate-actions-summerwind-dev-v1alpha1-runnerreplicaset,verbs=create;update,mutating=false,failurePolicy=fail,groups=actions.summerwind.dev,resources=runnerreplicasets,versions=v1alpha1,name=validate.runnerreplicaset.actions.summerwind.dev,sideEffects=None,admissionReviewVersions=v1beta1
var _ admission.Validator[*RunnerReplicaSet] = &RunnerReplicaSetValidator{}
var _ webhook.CustomValidator = &RunnerReplicaSetValidator{}
type RunnerReplicaSetValidator struct{}
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (*RunnerReplicaSetValidator) ValidateCreate(ctx context.Context, r *RunnerReplicaSet) (admission.Warnings, error) {
func (*RunnerReplicaSetValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
r, ok := obj.(*RunnerReplicaSet)
if !ok {
return nil, fmt.Errorf("expected RunnerReplicaSet object, got %T", obj)
}
runnerReplicaSetLog.Info("validate resource to be created", "name", r.Name)
return nil, r.Validate()
}
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (*RunnerReplicaSetValidator) ValidateUpdate(ctx context.Context, old, r *RunnerReplicaSet) (admission.Warnings, error) {
func (*RunnerReplicaSetValidator) ValidateUpdate(ctx context.Context, old, obj runtime.Object) (admission.Warnings, error) {
r, ok := obj.(*RunnerReplicaSet)
if !ok {
return nil, fmt.Errorf("expected RunnerReplicaSet object, got %T", obj)
}
runnerReplicaSetLog.Info("validate resource to be updated", "name", r.Name)
return nil, r.Validate()
}
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (*RunnerReplicaSetValidator) ValidateDelete(context.Context, *RunnerReplicaSet) (admission.Warnings, error) {
func (*RunnerReplicaSetValidator) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) {
return nil, nil
}
@@ -23,7 +23,7 @@ package v1alpha1
import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: horizontalrunnerautoscalers.actions.summerwind.dev
spec:
group: actions.summerwind.dev
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: runnerdeployments.actions.summerwind.dev
spec:
group: actions.summerwind.dev
@@ -1861,9 +1861,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5325,9 +5323,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -7094,9 +7090,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -7747,10 +7741,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -8580,7 +8573,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -9415,24 +9408,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: runnerreplicasets.actions.summerwind.dev
spec:
group: actions.summerwind.dev
@@ -1844,9 +1844,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5308,9 +5306,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -7077,9 +7073,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -7730,10 +7724,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -8563,7 +8556,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -9398,24 +9391,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: runners.actions.summerwind.dev
spec:
group: actions.summerwind.dev
@@ -1776,9 +1776,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5240,9 +5238,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -7009,9 +7005,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -7662,10 +7656,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -8495,7 +8488,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -9330,24 +9323,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: runnersets.actions.summerwind.dev
spec:
group: actions.summerwind.dev
@@ -1998,9 +1998,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5067,9 +5065,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5827,8 +5823,8 @@ spec:
will be made available to those containers which consume them
by name.
This is a stable field but requires that the
DynamicResourceAllocation feature gate is enabled.
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
This field is immutable.
items:
@@ -6277,10 +6273,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -7052,7 +7047,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -7887,24 +7882,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -8314,42 +8291,6 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
workloadRef:
description: |-
WorkloadRef provides a reference to the Workload object that this Pod belongs to.
This field is used by the scheduler to identify the PodGroup and apply the
correct group scheduling policies. The Workload object referenced
by this field may not exist at the time the Pod is created.
This field is immutable, but a Workload object with the same name
may be recreated with different policies. Doing this during pod scheduling
may result in the placement not conforming to the expected policies.
properties:
name:
description: |-
Name defines the name of the Workload object this Pod belongs to.
Workload must be in the same namespace as the Pod.
If it doesn't match any existing Workload, the Pod will remain unschedulable
until a Workload object is created and observed by the kube-scheduler.
It must be a DNS subdomain.
type: string
podGroup:
description: |-
PodGroup is the name of the PodGroup within the Workload that this Pod
belongs to. If it doesn't match any existing PodGroup within the Workload,
the Pod will remain unschedulable until the Workload object is recreated
and observed by the kube-scheduler. It must be a DNS label.
type: string
podGroupReplicaKey:
description: |-
PodGroupReplicaKey specifies the replica key of the PodGroup to which this
Pod belongs. It is used to distinguish pods belonging to different replicas
of the same pod group. The pod group policy is applied separately to each replica.
When set, it must be a DNS label.
type: string
required:
- name
- podGroup
type: object
required:
- containers
type: object
@@ -8371,10 +8312,10 @@ spec:
The maximum number of pods that can be unavailable during the update.
Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
Absolute number is calculated from percentage by rounding up. This can not be 0.
Defaults to 1. This field is beta-level and is enabled by default. The field applies to all pods in the range 0 to
Defaults to 1. This field is alpha-level and is only honored by servers that enable the
MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to
Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it
will be counted towards MaxUnavailable.
This setting might not be effective for the OrderedReady podManagementPolicy. That policy ensures pods are created and become ready one at a time.
x-kubernetes-int-or-string: true
partition:
description: |-
@@ -8531,7 +8472,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -8653,7 +8594,7 @@ spec:
that it does not recognizes, then it should ignore that update and let other controllers
handle it.
type: string
description: "allocatedResourceStatuses stores status of resource being resized for the given PVC.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState set when resize controller starts resizing the volume in control-plane.\n\t- ControllerResizeFailed:\n\t\tState set when resize has failed in resize controller with a terminal error.\n\t- NodeResizePending:\n\t\tState set when resize controller has finished resizing the volume but further resizing of\n\t\tvolume is needed on the node.\n\t- NodeResizeInProgress:\n\t\tState set when kubelet starts resizing the volume.\n\t- NodeResizeFailed:\n\t\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeFailed\"\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\n\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC."
description: "allocatedResourceStatuses stores status of resource being resized for the given PVC.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nClaimResourceStatus can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState set when resize controller starts resizing the volume in control-plane.\n\t- ControllerResizeFailed:\n\t\tState set when resize has failed in resize controller with a terminal error.\n\t- NodeResizePending:\n\t\tState set when resize controller has finished resizing the volume but further resizing of\n\t\tvolume is needed on the node.\n\t- NodeResizeInProgress:\n\t\tState set when kubelet starts resizing the volume.\n\t- NodeResizeFailed:\n\t\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] = \"NodeResizeFailed\"\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\n\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature."
type: object
x-kubernetes-map-type: granular
allocatedResources:
@@ -8663,7 +8604,7 @@ spec:
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
description: "allocatedResources tracks the resources allocated to a PVC including its capacity.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\nis requested.\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\nIf a volume expansion capacity request is lowered, allocatedResources is only\nlowered if there are no expansion operations in progress and if the actual volume capacity\nis equal or lower than the requested capacity.\n\nA controller that receives PVC update with previously unknown resourceName\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC."
description: "allocatedResources tracks the resources allocated to a PVC including its capacity.\nKey names follow standard Kubernetes label syntax. Valid values are either:\n\t* Un-prefixed keys:\n\t\t- storage - the capacity of the volume.\n\t* Custom resources must use implementation-defined prefixed names such as \"example.com/my-custom-resource\"\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\nreserved and hence may not be used.\n\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\nis requested.\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\nIf a volume expansion capacity request is lowered, allocatedResources is only\nlowered if there are no expansion operations in progress and if the actual volume capacity\nis equal or lower than the requested capacity.\n\nA controller that receives PVC update with previously unknown resourceName\nshould ignore the update for the purpose it was designed. For example - a controller that\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\nresources associated with PVC.\n\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature."
type: object
capacity:
additionalProperties:
@@ -1,33 +0,0 @@
apiVersion: v2
name: gha-runner-scale-set-controller-experimental
description: A Helm chart for install actions-runner-controller CRD
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: "0.14.1"
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.14.1"
home: https://github.com/actions/actions-runner-controller
sources:
- "https://github.com/actions/actions-runner-controller"
maintainers:
- name: actions
url: https://github.com/actions
@@ -1,3 +0,0 @@
Thank you for installing {{ .Chart.Name }}.
Your release is named {{ .Release.Name }}.
@@ -1,67 +0,0 @@
{{/*
Allow overriding the namespace for the resources.
*/}}
{{- define "gha-controller.namespace" -}}
{{- if .Values.namespaceOverride }}
{{- .Values.namespaceOverride }}
{{- else }}
{{- .Release.Namespace }}
{{- end }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "gha-controller.name" -}}
{{- if .Values.nameOverride }}
{{- .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default (include "gha-base-name" .) .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Labels applied to the controller deployment
*/}}
{{- define "gha-controller.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "controller-manager" -}}
{{- $commonLabels := include "gha-common.labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.controller.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.labels | default (dict)) | fromYaml -}}
{{- $labels := mergeOverwrite $global $userLabels $resourceLabels $commonLabels -}}
{{- /* Reserved actions.github.com/* labels owned by the chart itself */ -}}
{{- $_ := set $labels "actions.github.com/controller-service-account-namespace" (include "gha-controller.namespace" .) -}}
{{- $_ := set $labels "actions.github.com/controller-service-account-name" (include "gha-controller.service-account-name" .) -}}
{{- with .Values.controller.manager.config.watchSingleNamespace }}
{{- $_ := set $labels "actions.github.com/controller-watch-single-namespace" . -}}
{{- end }}
{{- toYaml $labels -}}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "gha-controller.service-account-name" -}}
{{- if eq .Values.controller.serviceAccount.name "default"}}
{{- fail "serviceAccount.name cannot be set to 'default'" }}
{{- end }}
{{- if .Values.controller.serviceAccount.create }}
{{- default (include "gha-controller.name" .) .Values.controller.serviceAccount.name }}
{{- else }}
{{- if not .Values.controller.serviceAccount.name }}
{{- fail "serviceAccount.name must be set if serviceAccount.create is false" }}
{{- else }}
{{- .Values.controller.serviceAccount.name }}
{{- end }}
{{- end }}
{{- end }}
@@ -1,122 +0,0 @@
{{/*
Labels applied to the controller Pod template (spec.template.metadata.labels)
*/}}
{{- define "gha-controller-template.labels" -}}
{{- $static := dict "app.kubernetes.io/part-of" "gha-rs-controller" "app.kubernetes.io/component" "controller-manager" -}}
{{- $_ := set $static "app.kubernetes.io/version" (.Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-") -}}
{{- $selector := include "gha-controller.selector-labels" . | fromYaml -}}
{{- $podUser := include "apply-non-reserved-gha-labels-and-annotations" (.Values.controller.pod.metadata.labels | default (dict)) | fromYaml -}}
{{- $labels := mergeOverwrite $podUser $selector $static -}}
{{- toYaml $labels -}}
{{- end }}
{{/*
Annotations applied to the controller Pod template (spec.template.metadata.annotations)
*/}}
{{- define "gha-controller-template.annotations" -}}
{{- $static := dict "kubectl.kubernetes.io/default-container" "manager" -}}
{{- $podUser := include "apply-non-reserved-gha-labels-and-annotations" (.Values.controller.pod.metadata.annotations | default (dict)) | fromYaml -}}
{{- $annotations := mergeOverwrite $podUser $static -}}
{{- toYaml $annotations -}}
{{- end }}
{{- define "gha-controller-template.manager-container" -}}
name: manager
image: "{{ .Values.controller.manager.container.image }}"
imagePullPolicy: {{ default "IfNotPresent" .Values.controller.manager.container.pullPolicy }}
command:
- "/manager"
args:
- "--auto-scaling-runner-set-only"
{{- if gt (int (default 1 .Values.controller.replicaCount)) 1 }}
- "--enable-leader-election"
- "--leader-election-id={{ include "gha-controller.name" . }}"
{{- end }}
{{- with .Values.imagePullSecrets }}
{{- range . }}
- "--auto-scaler-image-pull-secrets={{- .name -}}"
{{- end }}
{{- end }}
{{- with .Values.controller.manager.config.logLevel }}
- "--log-level={{ . }}"
{{- end }}
{{- with .Values.controller.manager.config.logFormat }}
- "--log-format={{ . }}"
{{- end }}
{{- with .Values.controller.manager.config.watchSingleNamespace }}
- "--watch-single-namespace={{ . }}"
{{- end }}
{{- with .Values.controller.manager.config.runnerMaxConcurrentReconciles }}
- "--runner-max-concurrent-reconciles={{ . }}"
{{- end }}
{{- with .Values.controller.manager.config.updateStrategy }}
- "--update-strategy={{ . }}"
{{- end }}
{{- if .Values.controller.metrics }}
{{- with .Values.controller.metrics }}
- "--listener-metrics-addr={{ .listenerAddr }}"
- "--listener-metrics-endpoint={{ .listenerEndpoint }}"
- "--metrics-addr={{ .controllerManagerAddr }}"
{{- end }}
{{- else }}
- "--listener-metrics-addr=0"
- "--listener-metrics-endpoint="
- "--metrics-addr=0"
{{- end }}
{{- range .Values.controller.manager.config.excludeLabelPropagationPrefixes }}
- "--exclude-label-propagation-prefix={{ . }}"
{{- end }}
{{- with .Values.controller.manager.config.k8sClientRateLimiterQPS }}
- "--k8s-client-rate-limiter-qps={{ . }}"
{{- end }}
{{- with .Values.controller.manager.config.k8sClientRateLimiterBurst }}
- "--k8s-client-rate-limiter-burst={{ . }}"
{{- end }}
{{- with .Values.controller.manager.container.extraArgs }}
{{- range . }}
- "{{ . }}"
{{- end }}
{{- end }}
{{- $ports := list -}}
{{- if .Values.controller.metrics }}
{{- $metricsPort := dict "containerPort" ((regexReplaceAll ":([0-9]+)" .Values.controller.metrics.controllerManagerAddr "${1}") | int) "protocol" "TCP" "name" "metrics" -}}
{{- $ports = append $ports $metricsPort -}}
{{- end }}
{{- with .Values.controller.manager.container.extraPorts }}
{{- if kindIs "slice" . }}
{{- $ports = concat $ports . -}}
{{- end }}
{{- end }}
{{- if gt (len $ports) 0 }}
ports:
{{- toYaml $ports | nindent 2 }}
{{- end }}
env:
- name: CONTROLLER_MANAGER_CONTAINER_IMAGE
value: "{{ .Values.controller.manager.container.image }}"
- name: CONTROLLER_MANAGER_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- with .Values.controller.manager.container.env }}
{{- if kindIs "slice" . }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- with .Values.controller.manager.container.resources }}
resources:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.controller.manager.container.securityContext }}
securityContext:
{{- toYaml . | nindent 2 }}
{{- end }}
volumeMounts:
- mountPath: /tmp
name: tmp
{{- $podVolumeMounts := (.Values.controller.pod.volumeMounts | default list) -}}
{{- range $podVolumeMounts }}
- {{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -1,74 +0,0 @@
{{- define "gha-base-name" -}}
gha-rs-controller
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "gha-controller.chart" -}}
{{- printf "%s-%s" (include "gha-base-name" .) .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "gha-common.labels" -}}
helm.sh/chart: {{ include "gha-controller.chart" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/part-of: "gha-rs-controller"
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/name: {{ include "gha-controller.name" . }}
app.kubernetes.io/namespace: {{ include "gha-controller.namespace" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "gha-controller.manager-cluster-role-name" -}}
{{- include "gha-controller.name" . }}
{{- end }}
{{- define "gha-controller.manager-cluster-role-binding" -}}
{{- include "gha-controller.name" . }}
{{- end }}
{{- define "gha-controller.manager-single-namespace-role-name" -}}
{{- include "gha-controller.name" . }}-single-namespace
{{- end }}
{{- define "gha-controller.manager-single-namespace-role-binding" -}}
{{- include "gha-controller.name" . }}-single-namespace
{{- end }}
{{- define "gha-controller.manager-single-namespace-watch-role-name" -}}
{{- include "gha-controller.name" . }}-single-namespace-watch
{{- end }}
{{- define "gha-controller.manager-single-namespace-watch-role-binding" -}}
{{- include "gha-controller.name" . }}-single-namespace-watch
{{- end }}
{{- define "gha-controller.manager-listener-role-name" -}}
{{- include "gha-controller.name" . }}-listener
{{- end }}
{{- define "gha-controller.manager-listener-role-binding" -}}
{{- include "gha-controller.name" . }}-listener
{{- end }}
{{- define "gha-controller.leaderElectionRoleName" -}}
{{- include "gha-controller.name" . }}-leader-election
{{- end }}
{{- define "gha-controller.leader-election-role-name" -}}
{{- include "gha-controller.leaderElectionRoleName" . -}}
{{- end }}
{{- define "gha-controller.leaderElectionRoleBinding" -}}
{{- include "gha-controller.name" . }}-leader-election
{{- end }}
{{- define "gha-controller.leader-election-role-binding" -}}
{{- include "gha-controller.leaderElectionRoleBinding" . -}}
{{- end }}
@@ -1,21 +0,0 @@
{{/*
Takes a map of user labels and removes the ones with "actions.github.com/" prefix
*/}}
{{- define "apply-non-reserved-gha-labels-and-annotations" -}}
{{- $userLabels := . -}}
{{- $processed := dict -}}
{{- range $key, $value := $userLabels -}}
{{- if not (hasPrefix "actions.github.com/" $key) -}}
{{- $_ := set $processed $key $value -}}
{{- end -}}
{{- end -}}
{{- if not (empty $processed) -}}
{{- $processed | toYaml }}
{{- end }}
{{- end }}
{{- define "gha-controller.selector-labels" -}}
app.kubernetes.io/name: {{ include "gha-controller.name" . }}
app.kubernetes.io/namespace: {{ include "gha-controller.namespace" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
@@ -1,54 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "gha-controller.name" . }}
namespace: {{ include "gha-controller.namespace" . }}
labels:
{{- include "gha-controller.labels" . | nindent 4 }}
spec:
replicas: {{ default 1 .Values.controller.replicaCount }}
selector:
matchLabels:
{{- include "gha-controller.selector-labels" . | nindent 6 }}
template:
metadata:
annotations:
{{- include "gha-controller-template.annotations" . | nindent 8 }}
labels:
{{- include "gha-controller-template.labels" . | nindent 8 }}
spec:
{{- $pod := (.Values.controller.pod | default dict) -}}
{{- if and (hasKey .Values.controller "pod") (not (kindIs "map" $pod)) -}}
{{- fail "controller.pod must be an object" -}}
{{- end -}}
{{- $podSpec := (index $pod "spec" | default dict) -}}
{{- if and (hasKey $pod "spec") (not (kindIs "map" $podSpec)) -}}
{{- fail "controller.pod.spec must be an object" -}}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "gha-controller.service-account-name" . }}
containers:
-
{{- include "gha-controller-template.manager-container" . | nindent 10 }}
{{- $extraContainers := (index $podSpec "containers" | default list) -}}
{{- range $extraContainers }}
-
{{- toYaml . | nindent 10 }}
{{- end }}
terminationGracePeriodSeconds: {{ default 10 (index $podSpec "terminationGracePeriodSeconds") }}
volumes:
- name: tmp
emptyDir: {}
{{- $podVolumes := (index $podSpec "volumes" | default list) -}}
{{- range $podVolumes }}
- {{- toYaml . | nindent 10 }}
{{- end }}
{{- $runnerPodSpecExtraFields := (omit $podSpec "containers" "serviceAccountName" "terminationGracePeriodSeconds" "volumes") -}}
{{- if gt (len $runnerPodSpecExtraFields) 0 }}
{{- toYaml $runnerPodSpecExtraFields | nindent 6 }}
{{- end }}
@@ -1,15 +0,0 @@
{{- if gt (int (default 1 .Values.controller.replicaCount)) 1 }}
# permissions to do leader election.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "gha-controller.leader-election-role-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
rules:
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "watch", "list", "delete", "update", "create"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
{{- end }}
@@ -1,15 +0,0 @@
{{- if gt (int (default 1 .Values.controller.replicaCount)) 1 }}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "gha-controller.leader-election-role-binding" . }}
namespace: {{ include "gha-controller.namespace" . }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "gha-controller.leader-election-role-name" . }}
subjects:
- kind: ServiceAccount
name: {{ include "gha-controller.service-account-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
{{- end }}
@@ -1,144 +0,0 @@
{{- if empty .Values.controller.manager.config.watchSingleNamespace }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "gha-controller.manager-cluster-role-name" . }}
rules:
- apiGroups:
- actions.github.com
resources:
- autoscalingrunnersets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- autoscalingrunnersets/finalizers
verbs:
- patch
- update
- apiGroups:
- actions.github.com
resources:
- autoscalingrunnersets/status
verbs:
- get
- patch
- update
- apiGroups:
- actions.github.com
resources:
- autoscalinglisteners
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- autoscalinglisteners/status
verbs:
- get
- patch
- update
- apiGroups:
- actions.github.com
resources:
- autoscalinglisteners/finalizers
verbs:
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunnersets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- ephemeralrunnersets/status
verbs:
- get
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunnersets/finalizers
verbs:
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunners
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- ephemeralrunners/finalizers
verbs:
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunners/status
verbs:
- get
- patch
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
verbs:
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
verbs:
- list
- watch
- patch
{{- end }}
@@ -1,14 +0,0 @@
{{- if empty .Values.controller.manager.config.watchSingleNamespace }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "gha-controller.manager-cluster-role-binding" . }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "gha-controller.manager-cluster-role-name" . }}
subjects:
- kind: ServiceAccount
name: {{ include "gha-controller.service-account-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
{{- end }}
@@ -1,40 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "gha-controller.manager-listener-role-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- get
- apiGroups:
- ""
resources:
- pods/status
verbs:
- get
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- get
- patch
- update
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- delete
- get
- patch
- update
@@ -1,13 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "gha-controller.manager-listener-role-binding" . }}
namespace: {{ include "gha-controller.namespace" . }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "gha-controller.manager-listener-role-name" . }}
subjects:
- kind: ServiceAccount
name: {{ include "gha-controller.service-account-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
@@ -1,84 +0,0 @@
{{- if .Values.controller.manager.config.watchSingleNamespace }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "gha-controller.manager-single-namespace-role-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
rules:
- apiGroups:
- actions.github.com
resources:
- autoscalinglisteners
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- autoscalinglisteners/status
verbs:
- get
- patch
- update
- apiGroups:
- actions.github.com
resources:
- autoscalinglisteners/finalizers
verbs:
- patch
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
verbs:
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
verbs:
- list
- watch
- apiGroups:
- actions.github.com
resources:
- autoscalingrunnersets
verbs:
- list
- watch
- apiGroups:
- actions.github.com
resources:
- ephemeralrunnersets
verbs:
- list
- watch
- apiGroups:
- actions.github.com
resources:
- ephemeralrunners
verbs:
- list
- watch
{{- end }}
@@ -1,15 +0,0 @@
{{- if .Values.controller.manager.config.watchSingleNamespace }}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "gha-controller.manager-single-namespace-role-binding" . }}
namespace: {{ include "gha-controller.namespace" . }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "gha-controller.manager-single-namespace-role-name" . }}
subjects:
- kind: ServiceAccount
name: {{ include "gha-controller.service-account-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
{{- end }}
@@ -1,125 +0,0 @@
{{- if .Values.controller.manager.config.watchSingleNamespace }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "gha-controller.manager-single-namespace-watch-role-name" . }}
namespace: {{ .Values.controller.manager.config.watchSingleNamespace }}
rules:
- apiGroups:
- actions.github.com
resources:
- autoscalingrunnersets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- autoscalingrunnersets/finalizers
verbs:
- patch
- update
- apiGroups:
- actions.github.com
resources:
- autoscalingrunnersets/status
verbs:
- get
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunnersets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- ephemeralrunnersets/status
verbs:
- get
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunnersets/finalizers
verbs:
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunners
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- actions.github.com
resources:
- ephemeralrunners/finalizers
verbs:
- patch
- update
- apiGroups:
- actions.github.com
resources:
- ephemeralrunners/status
verbs:
- get
- patch
- update
- apiGroups:
- actions.github.com
resources:
- autoscalinglisteners
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
verbs:
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
verbs:
- list
- watch
- patch
{{- end }}
@@ -1,15 +0,0 @@
{{- if .Values.controller.manager.config.watchSingleNamespace }}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "gha-controller.manager-single-namespace-watch-role-binding" . }}
namespace: {{ .Values.controller.manager.config.watchSingleNamespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "gha-controller.manager-single-namespace-watch-role-name" . }}
subjects:
- kind: ServiceAccount
name: {{ include "gha-controller.service-account-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
{{- end }}
@@ -1,13 +0,0 @@
{{- if .Values.controller.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "gha-controller.service-account-name" . }}
namespace: {{ include "gha-controller.namespace" . }}
labels:
{{- include "gha-controller.labels" . | nindent 4 }}
{{- with .Values.controller.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -1,75 +0,0 @@
suite: "Controller Deployment args"
templates:
- deployment.yaml
tests:
- it: should include metrics-disabled flags by default
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: "--metrics-addr=0"
- contains:
path: spec.template.spec.containers[0].args
content: "--listener-metrics-addr=0"
- contains:
path: spec.template.spec.containers[0].args
content: "--listener-metrics-endpoint="
- it: should include watch-single-namespace flag when configured
set:
controller:
manager:
config:
watchSingleNamespace: "demo"
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: "--watch-single-namespace=demo"
- it: should include exclude-label-propagation-prefix flags when configured
set:
controller:
manager:
config:
excludeLabelPropagationPrefixes:
- "prefix.com/"
- "complete.io/label"
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: "--exclude-label-propagation-prefix=prefix.com/"
- contains:
path: spec.template.spec.containers[0].args
content: "--exclude-label-propagation-prefix=complete.io/label"
- it: should render metrics port when metrics are enabled
set:
controller:
metrics:
controllerManagerAddr: ":8080"
listenerAddr: ":8081"
listenerEndpoint: "/metrics"
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- equal:
path: spec.template.spec.containers[0].ports[0].containerPort
value: 8080
- contains:
path: spec.template.spec.containers[0].args
content: "--metrics-addr=:8080"
- contains:
path: spec.template.spec.containers[0].args
content: "--listener-metrics-addr=:8081"
- contains:
path: spec.template.spec.containers[0].args
content: "--listener-metrics-endpoint=/metrics"
@@ -1,46 +0,0 @@
suite: "Controller Deployment env"
templates:
- deployment.yaml
tests:
- it: should not render envFrom in manager container
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- notExists:
path: spec.template.spec.containers[0].envFrom
- notExists:
path: spec.template.spec.containers[0].ports
- it: should include extra env entries from values
set:
controller:
manager:
container:
env:
- name: "FOO"
value: "bar"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: "FOO"
value: "bar"
- it: should enable leader election when replicaCount > 1
set:
controller:
replicaCount: 2
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- contains:
path: spec.template.spec.containers[0].args
content: "--enable-leader-election"
- contains:
path: spec.template.spec.containers[0].args
content: "--leader-election-id=test-name-gha-rs-controller"
@@ -1,55 +0,0 @@
suite: "Controller Deployment extra containers"
templates:
- deployment.yaml
tests:
- it: should render manager container first and then extra containers
set:
controller:
pod:
spec:
containers:
- name: "sidecar"
image: "busybox:1.36"
command:
- "sh"
- "-c"
args:
- "echo hello && sleep 3600"
- name: "another"
image: "alpine:3.19"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: spec.template.spec.containers[0].name
value: "manager"
- equal:
path: spec.template.spec.containers[1].name
value: "sidecar"
- equal:
path: spec.template.spec.containers[1].image
value: "busybox:1.36"
- equal:
path: spec.template.spec.containers[1].command[0]
value: "sh"
- equal:
path: spec.template.spec.containers[1].args[0]
value: "echo hello && sleep 3600"
- equal:
path: spec.template.spec.containers[2].name
value: "another"
- equal:
path: spec.template.spec.containers[2].image
value: "alpine:3.19"
- it: should not fail when extra containers are unset
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: spec.template.spec.containers[0].name
value: "manager"
- notExists:
path: spec.template.spec.containers[1]
@@ -1,33 +0,0 @@
suite: "Controller Deployment imagePullSecrets"
templates:
- deployment.yaml
tests:
- it: should not render imagePullSecrets by default
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- notExists:
path: spec.template.spec.imagePullSecrets
- it: should render imagePullSecrets and forward them as args when configured
set:
imagePullSecrets:
- name: regcred
- name: another
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: spec.template.spec.imagePullSecrets[0].name
value: regcred
- equal:
path: spec.template.spec.imagePullSecrets[1].name
value: another
- contains:
path: spec.template.spec.containers[0].args
content: "--auto-scaler-image-pull-secrets=regcred"
- contains:
path: spec.template.spec.containers[0].args
content: "--auto-scaler-image-pull-secrets=another"
@@ -1,54 +0,0 @@
suite: "Controller Deployment pod extra fields"
templates:
- deployment.yaml
tests:
- it: should render extra pod spec fields from controller.pod
set:
controller:
pod:
spec:
nodeSelector:
kubernetes.io/os: linux
tolerations:
- key: "dedicated"
operator: "Equal"
value: "arc"
effect: "NoSchedule"
hostNetwork: true
dnsPolicy: "ClusterFirstWithHostNet"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: spec.template.spec.nodeSelector["kubernetes.io/os"]
value: "linux"
- equal:
path: spec.template.spec.tolerations[0].key
value: "dedicated"
- equal:
path: spec.template.spec.tolerations[0].value
value: "arc"
- equal:
path: spec.template.spec.hostNetwork
value: true
- equal:
path: spec.template.spec.dnsPolicy
value: "ClusterFirstWithHostNet"
- it: should not allow overriding serviceAccountName via controller.pod
set:
controller:
pod:
spec:
serviceAccountName: "hacker-sa"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: spec.template.spec.serviceAccountName
value: "test-name-gha-rs-controller"
- notEqual:
path: spec.template.spec.serviceAccountName
value: "hacker-sa"
@@ -1,27 +0,0 @@
suite: "Controller Deployment smoke"
templates:
- deployment.yaml
tests:
- it: should render deployment basics
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: apiVersion
value: "apps/v1"
- equal:
path: kind
value: "Deployment"
- equal:
path: metadata.name
value: "test-name-gha-rs-controller"
- equal:
path: metadata.namespace
value: "test-namespace"
- equal:
path: spec.template.spec.containers[0].name
value: "manager"
- contains:
path: spec.template.spec.containers[0].command
content: "/manager"
@@ -1,25 +0,0 @@
suite: "Controller Deployment volume mounts"
templates:
- deployment.yaml
tests:
- it: should append controller.pod.volumeMounts to manager container
set:
controller:
manager:
container:
image: "ghcr.io/actions/gha-runner-scale-set-controller:latest"
pod:
volumeMounts:
- name: my-config
mountPath: /etc/my-config
readOnly: true
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- contains:
path: spec.template.spec.containers[0].volumeMounts
content:
name: my-config
mountPath: /etc/my-config
readOnly: true
@@ -1,26 +0,0 @@
suite: "Controller Deployment volumes"
templates:
- deployment.yaml
tests:
- it: should append controller.pod.spec.volumes to pod spec volumes
set:
controller:
manager:
container:
image: "ghcr.io/actions/gha-runner-scale-set-controller:latest"
pod:
spec:
volumes:
- name: my-config
configMap:
name: my-config
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- contains:
path: spec.template.spec.volumes
content:
name: my-config
configMap:
name: my-config
@@ -1,37 +0,0 @@
suite: "Controller Manager ClusterRoleBinding"
templates:
- manager_cluster_role_binding.yaml
tests:
- it: should render when watchSingleNamespace is empty
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: apiVersion
value: "rbac.authorization.k8s.io/v1"
- equal:
path: kind
value: "ClusterRoleBinding"
- equal:
path: subjects[0].kind
value: "ServiceAccount"
- equal:
path: subjects[0].name
value: "test-name-gha-rs-controller"
- equal:
path: subjects[0].namespace
value: "test-namespace"
- it: should not render when watchSingleNamespace is set
set:
controller:
manager:
config:
watchSingleNamespace: "my-ns"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- hasDocuments:
count: 0
@@ -1,24 +0,0 @@
suite: "Controller namespaceOverride"
templates:
- deployment.yaml
- serviceaccount.yaml
tests:
- it: should apply namespaceOverride to deployment and serviceaccount
set:
namespaceOverride: "override-ns"
release:
name: "test-name"
namespace: "release-ns"
asserts:
- equal:
path: metadata.namespace
value: "override-ns"
template: deployment.yaml
- equal:
path: metadata.labels["actions.github.com/controller-service-account-namespace"]
value: "override-ns"
template: deployment.yaml
- equal:
path: metadata.namespace
value: "override-ns"
template: serviceaccount.yaml
@@ -1,38 +0,0 @@
suite: "Controller RBAC cluster"
templates:
- manager_cluster_role.yaml
tests:
- it: should render manager ClusterRole when watchSingleNamespace is empty
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- equal:
path: kind
value: "ClusterRole"
- equal:
path: metadata.name
value: "test-arc-gha-rs-controller"
- contains:
path: rules
content:
apiGroups:
- ""
resources:
- pods
verbs:
- list
- watch
- it: should not render manager ClusterRole when watchSingleNamespace is set
set:
controller:
manager:
config:
watchSingleNamespace: "demo"
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- hasDocuments:
count: 0
@@ -1,52 +0,0 @@
suite: "Controller RBAC leader election"
templates:
- leader_election_role.yaml
- leader_election_role_binding.yaml
tests:
- it: should not render leader election resources when replicaCount is 1
set:
controller:
replicaCount: 1
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- hasDocuments:
count: 0
template: leader_election_role.yaml
- hasDocuments:
count: 0
template: leader_election_role_binding.yaml
- it: should render leader election resources when replicaCount > 1
set:
controller:
replicaCount: 2
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- equal:
path: kind
value: "Role"
template: leader_election_role.yaml
- equal:
path: metadata.name
value: "test-arc-gha-rs-controller-leader-election"
template: leader_election_role.yaml
- equal:
path: metadata.namespace
value: "test-ns"
template: leader_election_role.yaml
- equal:
path: kind
value: "RoleBinding"
template: leader_election_role_binding.yaml
- equal:
path: roleRef.name
value: "test-arc-gha-rs-controller-leader-election"
template: leader_election_role_binding.yaml
- equal:
path: subjects[0].name
value: "test-arc-gha-rs-controller"
template: leader_election_role_binding.yaml
@@ -1,68 +0,0 @@
suite: "Controller RBAC listener"
templates:
- manager_listener_role.yaml
- manager_listener_role_binding.yaml
tests:
- it: should render listener role with expected rules
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- equal:
path: kind
value: "Role"
template: manager_listener_role.yaml
- equal:
path: metadata.name
value: "test-arc-gha-rs-controller-listener"
template: manager_listener_role.yaml
- equal:
path: metadata.namespace
value: "test-ns"
template: manager_listener_role.yaml
- equal:
path: rules[0].resources[0]
value: "pods"
template: manager_listener_role.yaml
- equal:
path: rules[1].resources[0]
value: "pods/status"
template: manager_listener_role.yaml
- equal:
path: rules[2].resources[0]
value: "secrets"
template: manager_listener_role.yaml
- equal:
path: rules[3].resources[0]
value: "serviceaccounts"
template: manager_listener_role.yaml
- it: should bind listener role to controller serviceaccount
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- equal:
path: kind
value: "RoleBinding"
template: manager_listener_role_binding.yaml
- equal:
path: metadata.name
value: "test-arc-gha-rs-controller-listener"
template: manager_listener_role_binding.yaml
- equal:
path: metadata.namespace
value: "test-ns"
template: manager_listener_role_binding.yaml
- equal:
path: roleRef.name
value: "test-arc-gha-rs-controller-listener"
template: manager_listener_role_binding.yaml
- equal:
path: subjects[0].name
value: "test-arc-gha-rs-controller"
template: manager_listener_role_binding.yaml
- equal:
path: subjects[0].namespace
value: "test-ns"
template: manager_listener_role_binding.yaml
@@ -1,56 +0,0 @@
suite: "Controller RBAC single-namespace mode"
templates:
- manager_single_namespace_controller_role.yaml
- manager_single_namespace_controller_role_binding.yaml
- manager_single_namespace_watch_role.yaml
- manager_single_namespace_watch_role_binding.yaml
tests:
- it: should not render single-namespace roles when watchSingleNamespace is empty
set:
controller:
manager:
config:
watchSingleNamespace: ""
release:
name: "test-arc"
namespace: "test-ns"
asserts:
- hasDocuments:
count: 0
template: manager_single_namespace_controller_role.yaml
- hasDocuments:
count: 0
template: manager_single_namespace_controller_role_binding.yaml
- hasDocuments:
count: 0
template: manager_single_namespace_watch_role.yaml
- hasDocuments:
count: 0
template: manager_single_namespace_watch_role_binding.yaml
- it: should render roles in controller namespace and watch namespace
set:
controller:
manager:
config:
watchSingleNamespace: "demo"
release:
name: "test-arc"
namespace: "ctrl-ns"
asserts:
- equal:
path: metadata.namespace
value: "ctrl-ns"
template: manager_single_namespace_controller_role.yaml
- equal:
path: metadata.namespace
value: "ctrl-ns"
template: manager_single_namespace_controller_role_binding.yaml
- equal:
path: metadata.namespace
value: "demo"
template: manager_single_namespace_watch_role.yaml
- equal:
path: metadata.namespace
value: "demo"
template: manager_single_namespace_watch_role_binding.yaml
@@ -1,46 +0,0 @@
suite: "Controller serviceAccount.create toggle"
templates:
- serviceaccount.yaml
- deployment.yaml
tests:
- it: should create ServiceAccount and use it in Deployment when create is true
set:
controller:
manager:
container:
image: "ghcr.io/actions/gha-runner-scale-set-controller:latest"
serviceAccount:
create: true
name: ""
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- hasDocuments:
count: 1
template: serviceaccount.yaml
- equal:
path: spec.template.spec.serviceAccountName
value: "test-name-gha-rs-controller"
template: deployment.yaml
- it: should not create ServiceAccount and use provided name in Deployment when create is false
set:
controller:
manager:
container:
image: "ghcr.io/actions/gha-runner-scale-set-controller:latest"
serviceAccount:
create: false
name: "existing-sa"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- hasDocuments:
count: 0
template: serviceaccount.yaml
- equal:
path: spec.template.spec.serviceAccountName
value: "existing-sa"
template: deployment.yaml
@@ -1,72 +0,0 @@
suite: "Controller ServiceAccount"
templates:
- serviceaccount.yaml
tests:
- it: should render serviceaccount by default
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: apiVersion
value: "v1"
- equal:
path: kind
value: "ServiceAccount"
- equal:
path: metadata.name
value: "test-name-gha-rs-controller"
- equal:
path: metadata.namespace
value: "test-namespace"
- equal:
path: metadata.labels["actions.github.com/controller-service-account-name"]
value: "test-name-gha-rs-controller"
- equal:
path: metadata.labels["actions.github.com/controller-service-account-namespace"]
value: "test-namespace"
- it: should allow overriding serviceAccount.name when create is true
set:
controller:
serviceAccount:
create: true
name: "overwritten-name"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: metadata.name
value: "overwritten-name"
- equal:
path: metadata.labels["actions.github.com/controller-service-account-name"]
value: "overwritten-name"
- it: should render serviceAccount annotations
set:
controller:
serviceAccount:
create: true
annotations:
foo: bar
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: metadata.annotations.foo
value: "bar"
- it: should not render when serviceAccount.create is false
set:
controller:
serviceAccount:
create: false
name: "existing-sa"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- hasDocuments:
count: 0
@@ -1,32 +0,0 @@
suite: "Controller ServiceAccount validation"
templates:
- serviceaccount.yaml
- deployment.yaml
tests:
- it: should fail if serviceAccount.name is 'default'
set:
controller:
serviceAccount:
create: true
name: "default"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- failedTemplate:
errorMessage: "serviceAccount.name cannot be set to 'default'"
template: serviceaccount.yaml
- it: should fail when serviceAccount.create is false and name is not set
set:
controller:
serviceAccount:
create: false
name: ""
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- failedTemplate:
errorMessage: "serviceAccount.name must be set if serviceAccount.create is false"
template: deployment.yaml
@@ -1,52 +0,0 @@
package tests
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/gruntwork-io/terratest/modules/helm"
"github.com/gruntwork-io/terratest/modules/k8s"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
appsv1 "k8s.io/api/apps/v1"
)
type Chart struct {
Version string `yaml:"version"`
AppVersion string `yaml:"appVersion"`
}
func TestTemplate_RenderedDeployment_UsesChartMetadataLabels(t *testing.T) {
t.Parallel()
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set-controller-experimental")
require.NoError(t, err)
chartContent, err := os.ReadFile(filepath.Join(helmChartPath, "Chart.yaml"))
require.NoError(t, err)
chart := new(Chart)
err = yaml.Unmarshal(chartContent, chart)
require.NoError(t, err)
releaseName := "test-arc"
namespaceName := "test-" + strings.ToLower(random.UniqueId())
options := &helm.Options{
Logger: logger.Discard,
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
}
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/deployment.yaml"})
var deployment appsv1.Deployment
helm.UnmarshalK8SYaml(t, output, &deployment)
assert.Equal(t, "gha-rs-controller-"+chart.Version, deployment.Labels["helm.sh/chart"])
assert.Equal(t, chart.AppVersion, deployment.Labels["app.kubernetes.io/version"])
}
@@ -1,106 +0,0 @@
# Global chart-level labels applied to all resources (Deployment, RBAC, etc.).
labels: {}
# Overrides the default `.Release.Namespace` for all resources in this chart.
namespaceOverride: ""
# Optional imagePullSecrets added to the controller Pod spec.
# When set, the manager container also receives `--auto-scaler-image-pull-secrets=<name>` args.
imagePullSecrets: []
controller:
# Number of controller replicas.
replicaCount: 1
# Deployment-level metadata
metadata:
labels: {}
annotations: {}
manager:
config:
# Log level: "debug", "info", "warn", "error".
logLevel: "debug"
# Log format: "text", "json".
logFormat: "text"
# Restricts the controller to only watch resources in the desired namespace.
# Defaults to watch all namespaces when unset.
watchSingleNamespace: ""
# The maximum number of concurrent reconciles which can be run by the EphemeralRunner controller.
runnerMaxConcurrentReconciles: 2
# How the controller handles upgrades with running jobs: "immediate" or "eventual".
updateStrategy: "immediate"
# List of label prefixes that should NOT be propagated to internal resources.
excludeLabelPropagationPrefixes: []
# Example:
# excludeLabelPropagationPrefixes:
# - "argocd.argoproj.io/instance"
# K8s client rate limiter parameters.
k8sClientRateLimiterQPS: null
k8sClientRateLimiterBurst: null
container:
image: "ghcr.io/actions/gha-runner-scale-set-controller:latest"
pullPolicy: IfNotPresent
# Extra arguments appended to the default set generated by the chart.
extraArgs: []
# Container-level environment variables.
env: []
# Container-level security context.
securityContext: {}
# Container-level resource requests/limits.
resources: {}
# Extra container ports (metrics port is derived from controller.metrics).
extraPorts: []
serviceAccount:
# Specifies whether a service account should be created.
create: true
# Annotations to add to the service account.
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template.
name: ""
# Pod-level configuration.
pod:
metadata:
labels: {}
annotations: {}
# PodSpec fields applied to spec.template.spec.
# Note: containers provided here are appended after the built-in manager container.
spec:
# Pod-level security context.
securityContext: {}
# Pod priority class name.
priorityClassName: ""
# Node selection constraints.
nodeSelector: {}
# Pod tolerations.
tolerations: []
# Pod affinity.
affinity: {}
# Pod topology spread constraints.
topologySpreadConstraints: []
# Pod termination grace period (overrides default 10s).
terminationGracePeriodSeconds: null
# Additional volumes appended to the default ones.
volumes: []
# Additional containers appended after the manager container.
containers: []
# Additional volume mounts appended to the manager container's default ones.
volumeMounts: []
# Metrics configuration. If omitted, metrics are disabled.
# metrics:
# controllerManagerAddr: ":8080"
# listenerAddr: ":8080"
# listenerEndpoint: "/metrics"
@@ -15,13 +15,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.14.1
version: 0.13.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.14.1"
appVersion: "0.13.1"
home: https://github.com/actions/actions-runner-controller
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: autoscalinglisteners.actions.github.com
spec:
group: actions.github.com
@@ -56,19 +56,6 @@ spec:
autoscalingRunnerSetNamespace:
description: Required
type: string
configSecretMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSetName:
description: Required
type: string
@@ -209,48 +196,9 @@ spec:
type: string
type: array
type: object
roleBindingMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
roleMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
runnerScaleSetId:
description: Required
type: integer
serviceAccountMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
template:
description: PodTemplateSpec describes the data a pod should have
when created from a template
@@ -2101,9 +2049,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource
resize policy for the container.
@@ -5326,9 +5272,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource
resize policy for the container.
@@ -6115,8 +6059,8 @@ spec:
will be made available to those containers which consume them
by name.
This is a stable field but requires that the
DynamicResourceAllocation feature gate is enabled.
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
This field is immutable.
items:
@@ -6575,10 +6519,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -7389,7 +7332,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -8275,24 +8218,6 @@ spec:
description: Kubelet's generated CSRs
will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -8718,42 +8643,6 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
workloadRef:
description: |-
WorkloadRef provides a reference to the Workload object that this Pod belongs to.
This field is used by the scheduler to identify the PodGroup and apply the
correct group scheduling policies. The Workload object referenced
by this field may not exist at the time the Pod is created.
This field is immutable, but a Workload object with the same name
may be recreated with different policies. Doing this during pod scheduling
may result in the placement not conforming to the expected policies.
properties:
name:
description: |-
Name defines the name of the Workload object this Pod belongs to.
Workload must be in the same namespace as the Pod.
If it doesn't match any existing Workload, the Pod will remain unschedulable
until a Workload object is created and observed by the kube-scheduler.
It must be a DNS subdomain.
type: string
podGroup:
description: |-
PodGroup is the name of the PodGroup within the Workload that this Pod
belongs to. If it doesn't match any existing PodGroup within the Workload,
the Pod will remain unschedulable until the Workload object is recreated
and observed by the kube-scheduler. It must be a DNS label.
type: string
podGroupReplicaKey:
description: |-
PodGroupReplicaKey specifies the replica key of the PodGroup to which this
Pod belongs. It is used to distinguish pods belonging to different replicas
of the same pod group. The pod group policy is applied separately to each replica.
When set, it must be a DNS label.
type: string
required:
- name
- podGroup
type: object
required:
- containers
type: object
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: autoscalingrunnersets.actions.github.com
spec:
group: actions.github.com
@@ -64,54 +64,6 @@ spec:
spec:
description: AutoscalingRunnerSetSpec defines the desired state of AutoscalingRunnerSet
properties:
autoscalingListener:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSetMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret:
description: Required
type: string
@@ -147,18 +99,6 @@ spec:
x-kubernetes-map-type: atomic
type: object
type: object
listenerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerMetrics:
description: MetricsConfig holds configuration parameters for each metric type
properties:
@@ -203,42 +143,6 @@ spec:
type: object
type: object
type: object
listenerRoleBindingMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerRoleMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerServiceAccountMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerTemplate:
description: PodTemplateSpec describes the data a pod should have when created from a template
properties:
@@ -1986,9 +1890,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5061,9 +4963,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5824,8 +5724,8 @@ spec:
will be made available to those containers which consume them
by name.
This is a stable field but requires that the
DynamicResourceAllocation feature gate is enabled.
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
This field is immutable.
items:
@@ -6277,10 +6177,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -7052,7 +6951,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -7887,24 +7786,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -8314,42 +8195,6 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
workloadRef:
description: |-
WorkloadRef provides a reference to the Workload object that this Pod belongs to.
This field is used by the scheduler to identify the PodGroup and apply the
correct group scheduling policies. The Workload object referenced
by this field may not exist at the time the Pod is created.
This field is immutable, but a Workload object with the same name
may be recreated with different policies. Doing this during pod scheduling
may result in the placement not conforming to the expected policies.
properties:
name:
description: |-
Name defines the name of the Workload object this Pod belongs to.
Workload must be in the same namespace as the Pod.
If it doesn't match any existing Workload, the Pod will remain unschedulable
until a Workload object is created and observed by the kube-scheduler.
It must be a DNS subdomain.
type: string
podGroup:
description: |-
PodGroup is the name of the PodGroup within the Workload that this Pod
belongs to. If it doesn't match any existing PodGroup within the Workload,
the Pod will remain unschedulable until the Workload object is recreated
and observed by the kube-scheduler. It must be a DNS label.
type: string
podGroupReplicaKey:
description: |-
PodGroupReplicaKey specifies the replica key of the PodGroup to which this
Pod belongs. It is used to distinguish pods belonging to different replicas
of the same pod group. The pod group policy is applied separately to each replica.
When set, it must be a DNS label.
type: string
required:
- name
- podGroup
type: object
required:
- containers
type: object
@@ -8385,10 +8230,6 @@ spec:
type: object
runnerGroup:
type: string
runnerScaleSetLabels:
items:
type: string
type: array
runnerScaleSetName:
type: string
template:
@@ -10138,9 +9979,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -13207,9 +13046,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -13967,8 +13804,8 @@ spec:
will be made available to those containers which consume them
by name.
This is a stable field but requires that the
DynamicResourceAllocation feature gate is enabled.
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
This field is immutable.
items:
@@ -14417,10 +14254,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -15192,7 +15028,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -16027,24 +15863,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -16454,42 +16272,6 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
workloadRef:
description: |-
WorkloadRef provides a reference to the Workload object that this Pod belongs to.
This field is used by the scheduler to identify the PodGroup and apply the
correct group scheduling policies. The Workload object referenced
by this field may not exist at the time the Pod is created.
This field is immutable, but a Workload object with the same name
may be recreated with different policies. Doing this during pod scheduling
may result in the placement not conforming to the expected policies.
properties:
name:
description: |-
Name defines the name of the Workload object this Pod belongs to.
Workload must be in the same namespace as the Pod.
If it doesn't match any existing Workload, the Pod will remain unschedulable
until a Workload object is created and observed by the kube-scheduler.
It must be a DNS subdomain.
type: string
podGroup:
description: |-
PodGroup is the name of the PodGroup within the Workload that this Pod
belongs to. If it doesn't match any existing PodGroup within the Workload,
the Pod will remain unschedulable until the Workload object is recreated
and observed by the kube-scheduler. It must be a DNS label.
type: string
podGroupReplicaKey:
description: |-
PodGroupReplicaKey specifies the replica key of the PodGroup to which this
Pod belongs. It is used to distinguish pods belonging to different replicas
of the same pod group. The pod group policy is applied separately to each replica.
When set, it must be a DNS label.
type: string
required:
- name
- podGroup
type: object
required:
- containers
type: object
@@ -16541,6 +16323,8 @@ spec:
It is used to identify which vault integration should be used to resolve secrets.
type: string
type: object
required:
- template
type: object
status:
description: AutoscalingRunnerSetStatus defines the observed state of AutoscalingRunnerSet
@@ -16551,11 +16335,15 @@ spec:
type: integer
pendingEphemeralRunners:
type: integer
phase:
type: string
runningEphemeralRunners:
type: integer
state:
type: string
type: object
required:
- metadata
- spec
- status
type: object
served: true
storage: true
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: ephemeralrunners.actions.github.com
spec:
group: actions.github.com
@@ -70,18 +70,6 @@ spec:
spec:
description: EphemeralRunnerSpec defines the desired state of EphemeralRunner
properties:
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret:
type: string
githubConfigUrl:
@@ -1886,9 +1874,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -4955,9 +4941,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5715,8 +5699,8 @@ spec:
will be made available to those containers which consume them
by name.
This is a stable field but requires that the
DynamicResourceAllocation feature gate is enabled.
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
This field is immutable.
items:
@@ -6168,10 +6152,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -6943,7 +6926,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -7778,24 +7761,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -8205,42 +8170,6 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
workloadRef:
description: |-
WorkloadRef provides a reference to the Workload object that this Pod belongs to.
This field is used by the scheduler to identify the PodGroup and apply the
correct group scheduling policies. The Workload object referenced
by this field may not exist at the time the Pod is created.
This field is immutable, but a Workload object with the same name
may be recreated with different policies. Doing this during pod scheduling
may result in the placement not conforming to the expected policies.
properties:
name:
description: |-
Name defines the name of the Workload object this Pod belongs to.
Workload must be in the same namespace as the Pod.
If it doesn't match any existing Workload, the Pod will remain unschedulable
until a Workload object is created and observed by the kube-scheduler.
It must be a DNS subdomain.
type: string
podGroup:
description: |-
PodGroup is the name of the PodGroup within the Workload that this Pod
belongs to. If it doesn't match any existing PodGroup within the Workload,
the Pod will remain unschedulable until the Workload object is recreated
and observed by the kube-scheduler. It must be a DNS label.
type: string
podGroupReplicaKey:
description: |-
PodGroupReplicaKey specifies the replica key of the PodGroup to which this
Pod belongs. It is used to distinguish pods belonging to different replicas
of the same pod group. The pod group policy is applied separately to each replica.
When set, it must be a DNS label.
type: string
required:
- name
- podGroup
type: object
required:
- containers
type: object
@@ -8342,6 +8271,10 @@ spec:
format: int64
type: integer
type: object
required:
- metadata
- spec
- status
type: object
served: true
storage: true
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.20.1
controller-gen.kubebuilder.io/version: v0.19.0
name: ephemeralrunnersets.actions.github.com
spec:
group: actions.github.com
@@ -58,33 +58,9 @@ spec:
spec:
description: EphemeralRunnerSetSpec defines the desired state of EphemeralRunnerSet
properties:
ephemeralRunnerMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSpec:
description: EphemeralRunnerSpec is the spec of the ephemeral runner
properties:
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret:
type: string
githubConfigUrl:
@@ -1889,9 +1865,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -4958,9 +4932,7 @@ spec:
type: integer
type: object
resizePolicy:
description: |-
Resources resize policy for the container.
This field cannot be set on ephemeral containers.
description: Resources resize policy for the container.
items:
description: ContainerResizePolicy represents resource resize policy for the container.
properties:
@@ -5718,8 +5690,8 @@ spec:
will be made available to those containers which consume them
by name.
This is a stable field but requires that the
DynamicResourceAllocation feature gate is enabled.
This is an alpha field and requires enabling the
DynamicResourceAllocation feature gate.
This field is immutable.
items:
@@ -6171,10 +6143,9 @@ spec:
operator:
description: |-
Operator represents a key's relationship to the value.
Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod can
tolerate all taints of a particular category.
Lt and Gt perform numeric comparisons (requires feature gate TaintTolerationComparisonOperators).
type: string
tolerationSeconds:
description: |-
@@ -6946,7 +6917,7 @@ spec:
resources:
description: |-
resources represents the minimum resources the volume should have.
Users are allowed to specify resource requirements
If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements
that are lower than previous value but must still be higher than capacity recorded in the
status field of the claim.
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources
@@ -7781,24 +7752,6 @@ spec:
signerName:
description: Kubelet's generated CSRs will be addressed to this signer.
type: string
userAnnotations:
additionalProperties:
type: string
description: |-
userAnnotations allow pod authors to pass additional information to
the signer implementation. Kubernetes does not restrict or validate this
metadata in any way.
These values are copied verbatim into the `spec.unverifiedUserAnnotations` field of
the PodCertificateRequest objects that Kubelet creates.
Entries are subject to the same validation as object metadata annotations,
with the addition that all keys must be domain-prefixed. No restrictions
are placed on values, except an overall size limitation on the entire field.
Signers should document the keys and values they support. Signers should
deny requests that contain keys they do not recognize.
type: object
required:
- keyType
- signerName
@@ -8208,42 +8161,6 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
workloadRef:
description: |-
WorkloadRef provides a reference to the Workload object that this Pod belongs to.
This field is used by the scheduler to identify the PodGroup and apply the
correct group scheduling policies. The Workload object referenced
by this field may not exist at the time the Pod is created.
This field is immutable, but a Workload object with the same name
may be recreated with different policies. Doing this during pod scheduling
may result in the placement not conforming to the expected policies.
properties:
name:
description: |-
Name defines the name of the Workload object this Pod belongs to.
Workload must be in the same namespace as the Pod.
If it doesn't match any existing Workload, the Pod will remain unschedulable
until a Workload object is created and observed by the kube-scheduler.
It must be a DNS subdomain.
type: string
podGroup:
description: |-
PodGroup is the name of the PodGroup within the Workload that this Pod
belongs to. If it doesn't match any existing PodGroup within the Workload,
the Pod will remain unschedulable until the Workload object is recreated
and observed by the kube-scheduler. It must be a DNS label.
type: string
podGroupReplicaKey:
description: |-
PodGroupReplicaKey specifies the replica key of the PodGroup to which this
Pod belongs. It is used to distinguish pods belonging to different replicas
of the same pod group. The pod group policy is applied separately to each replica.
When set, it must be a DNS label.
type: string
required:
- name
- podGroup
type: object
required:
- containers
type: object
@@ -8306,6 +8223,7 @@ spec:
description: Replicas is the number of desired EphemeralRunner resources in the k8s namespace.
type: integer
required:
- ephemeralRunnerSpec
- patchID
type: object
status:
@@ -8318,14 +8236,15 @@ spec:
type: integer
pendingEphemeralRunners:
type: integer
phase:
description: EphemeralRunnerSetPhase is the phase of the ephemeral runner set resource
type: string
runningEphemeralRunners:
type: integer
required:
- currentReplicas
type: object
required:
- metadata
- spec
- status
type: object
served: true
storage: true
@@ -84,9 +84,6 @@ spec:
- "--listener-metrics-endpoint="
- "--metrics-addr=0"
{{- end }}
{{- if .Values.pprof.addr }}
- "--pprof-addr={{ .Values.pprof.addr }}"
{{- end }}
{{- range .Values.flags.excludeLabelPropagationPrefixes }}
- "--exclude-label-propagation-prefix={{ . }}"
{{- end }}
@@ -96,26 +93,14 @@ spec:
{{- with .Values.flags.k8sClientRateLimiterBurst }}
- "--k8s-client-rate-limiter-burst={{ . }}"
{{- end }}
{{- with .Values.flags.rateLimiter }}
{{- with .name }}
- "--workqueue-rate-limiter={{ . }}"
{{- end }}
{{- end }}
command:
- "/manager"
{{- if or .Values.metrics .Values.pprof.addr }}
ports:
{{- end }}
{{- with .Values.metrics }}
- containerPort: {{ required "Values.metrics.controllerManagerAddr must end with a numeric port" (regexFind "[0-9]+$" .controllerManagerAddr) }}
ports:
- containerPort: {{regexReplaceAll ":([0-9]+)" .controllerManagerAddr "${1}"}}
protocol: TCP
name: metrics
{{- end }}
{{- if .Values.pprof.addr }}
- containerPort: {{ required "Values.pprof.addr must end with a numeric port" (regexFind "[0-9]+$" .Values.pprof.addr) }}
protocol: TCP
name: pprof
{{- end }}
env:
- name: CONTROLLER_MANAGER_CONTAINER_IMAGE
value: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
@@ -94,10 +94,6 @@ priorityClassName: ""
# listenerAddr: ":8080"
# listenerEndpoint: "/metrics"
## To enable pprof, uncomment the addr field below.
pprof: {}
# addr: ":6060"
flags:
## Log level can be set here with one of the following values: "debug", "info", "warn", "error".
## Defaults to "debug".
@@ -140,13 +136,6 @@ flags:
# excludeLabelPropagationPrefixes:
# - "argocd.argoproj.io/instance"
## Workqueue rate limiter configuration.
## By default, controller-runtime uses a combined rate limiter with both a per-item
## exponential backoff and an overall token bucket (10 QPS, 100 bucket size).
## Valid names: "bucket_rate_limiter" (default), "typed_rate_limiter" (per-item only, no global token bucket).
# rateLimiter:
# name: "bucket_rate_limiter"
# Overrides the default `.Release.Namespace` for all resources in this chart.
namespaceOverride: ""
@@ -1,5 +1,5 @@
apiVersion: v2
name: gha-runner-scale-set-experimental
name: gha-runner-scale-set
description: A Helm chart for deploying an AutoScalingRunnerSet
# A chart can be either an 'application' or a 'library' chart.
@@ -15,13 +15,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: "0.14.1"
version: "0.14.0"
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.14.1"
appVersion: "0.14.0"
home: https://github.com/actions/actions-runner-controller
@@ -0,0 +1,87 @@
{{- define "autoscaling-runner-set.name" -}}
{{- $name := .Values.runnerScaleSetName | default .Release.Name | replace "_" "-" | trimSuffix "-" }}
{{- if or (empty $name) (gt (len $name) 45) }}
{{ fail "Autoscaling runner set name must have up to 45 characters" }}
{{- end }}
{{- $name }}
{{- end }}
{{- define "autoscaling-runner-set.namespace" -}}
{{- .Values.namespaceOverride | default .Release.Namespace -}}
{{- end }}
{{/*
The name of the GitHub secret used for authentication.
*/}}
{{- define "github-secret.name" -}}
{{- if not (empty .Values.auth.secretName) }}
{{- quote .Values.auth.secretName }}
{{- else }}
{{- include "autoscaling-runner-set.name" . }}-github-secret
{{- end }}
{{- end }}
{{/*
Create the labels for the autoscaling runner set.
*/}}
{{- define "autoscaling-runner-set.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "autoscaling-runner-set" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "gha-process-labels" (.Values.resource.autoscalingRunnerSet.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "gha-process-labels" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the common labels used across all resources.
*/}}
{{- define "gha-common-labels" -}}
helm.sh/chart: {{ include "gha-runner-scale-set.chart" . }}
app.kubernetes.io/name: {{ include "autoscaling-runner-set.name" . }}
app.kubernetes.io/instance: {{ include "autoscaling-runner-set.name" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/part-of: "gha-rs"
actions.github.com/scale-set-name: {{ include "autoscaling-runner-set.name" . }}
actions.github.com/scale-set-namespace: {{ include "autoscaling-runner-set.namespace" . }}
{{- end }}
{{/*
Takes a map of user labels and removes the ones with "actions.github.com/" prefix
*/}}
{{- define "gha-process-labels" -}}
{{- $userLabels := . -}}
{{- $processed := dict -}}
{{- range $key, $value := $userLabels -}}
{{- if not (hasPrefix $key "actions.github.com/") -}}
{{- $_ := set $processed $key $value -}}
{{- end -}}
{{- end -}}
{{- $processed | toYaml -}}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "gha-runner-scale-set.chart" -}}
{{- printf "gha-rs-%s" .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Container spec that is expanded for the runner container
*/}}
{{- define "container-spec.runner" -}}
{{- if not .Values.runner.container }}
{{ fail "You must provide a runner container specification in values.runner.container" }}
{{- end }}
{{- $tlsConfig := (default (dict) .Values.githubServerTLS) -}}
name: runner
image: {{ .Values.runner.container.image | default "ghcr.io/actions/runner:latest" }}
command: {{ toJson (default (list "/home/runner/run.sh") .Values.runner.container.command) }}
{{- end }}
@@ -0,0 +1,105 @@
apiVersion: actions.github.com/v1alpha1
kind: AutoscalingRunnerSet
metadata:
name: {{ include "autoscaling-runner-set.name" . | quote }}
namespace: {{ include "autoscaling-runner-set.namespace" . | quote }}
labels:
{{- include "autoscaling-runner-set.labels" . | nindent 4 }}
annotations:
{{- $globalAnnotations := (default (dict) .Values.resource.all.metadata.annotations) }}
{{- $resourceAnnotations := (default (dict) .Values.resource.autoscalingRunnerSet.metadata.annotations) }}
{{- $annotations := mergeOverwrite $globalAnnotations $resourceAnnotations }}
{{- range $k, $v := $annotations }}
{{ $k }}: {{ $v | quote }}
{{- end }}
actions.github.com/values-hash: {{ toJson .Values | sha256sum | trunc 63 }}
spec:
githubConfigUrl: {{ required ".Values.auth.url is required" (trimSuffix "/" .Values.auth.url) | quote }}
githubConfigSecret: {{ include "github-secret.name" . | quote }}
runnerGroup: {{ .Values.scaleset.runnerGroup | quote }}
runnerScaleSetName: {{ .Values.scaleset.name | quote }}
{{- if .Values.githubServerTLS }}
githubServerTLS:
{{- with .Values.githubServerTLS.certificateFrom }}
certificateFrom:
configMapKeyRef:
name: {{ .configMapKeyRef.name }}
key: {{ .configMapKeyRef.key }}
{{- end }}
{{- end }}
{{- if and .Values.secretResolution (ne .Values.secretResolution.type "kubernetes") }}
vaultConfig:
type: {{ .Values.secretResolution.type }}
{{- if .Values.secretResolution.proxy }}
proxy: {{- toYaml .Values.secretResolution.proxy | nindent 6 }}
{{- end }}
{{- if eq .Values.secretResolution.type "azureKeyVault" }}
azureKeyVault:
url: {{ .Values.secretResolution.azureKeyVault.url }}
tenantId: {{ .Values.secretResolution.azureKeyVault.tenantId }}
clientId: {{ .Values.secretResolution.azureKeyVault.clientId }}
certificatePath: {{ .Values.secretResolution.azureKeyVault.certificatePath }}
secretKey: {{ .Values.secretResolution.azureKeyVault.secretKey }}
{{- else }}
{{- fail "Unsupported keyVault type: " .Values.secretResolution.type }}
{{- end }}
{{- end }}
{{- if .Values.proxy }}
proxy:
{{- if .Values.proxy.http }}
http:
url: {{ .Values.proxy.http.url }}
{{- if .Values.proxy.http.credentialSecretRef }}
credentialSecretRef: {{ .Values.proxy.http.credentialSecretRef }}
{{- end }}
{{- end }}
{{- if .Values.proxy.https }}
https:
url: {{ .Values.proxy.https.url }}
{{- if .Values.proxy.https.credentialSecretRef }}
credentialSecretRef: {{ .Values.proxy.https.credentialSecretRef }}
{{- end }}
{{- end }}
{{- if and .Values.proxy.noProxy (kindIs "slice" .Values.proxy.noProxy) }}
noProxy: {{ .Values.proxy.noProxy | toYaml | nindent 6}}
{{- end }}
{{- end }}
{{- if and (or (kindIs "int64" .Values.scaleset.minRunners) (kindIs "float64" .Values.scaleset.minRunners)) (or (kindIs "int64" .Values.scaleset.maxRunners) (kindIs "float64" .Values.scaleset.maxRunners)) }}
{{- if gt .Values.scaleset.minRunners .Values.scaleset.maxRunners }}
{{- fail "maxRunners has to be greater or equal to minRunners" }}
{{- end }}
{{- end }}
{{- if or (kindIs "int64" .Values.scaleset.maxRunners) (kindIs "float64" .Values.scaleset.maxRunners)}}
{{- if lt (.Values.scaleset.maxRunners | int) 0 }}
{{- fail "maxRunners has to be greater or equal to 0" }}
{{- end }}
maxRunners: {{ .Values.scaleset.maxRunners | int }}
{{- end }}
{{- if or (kindIs "int64" .Values.scaleset.minRunners) (kindIs "float64" .Values.scaleset.minRunners) }}
{{- if lt (.Values.scaleset.minRunners | int) 0 }}
{{- fail "minRunners has to be greater or equal to 0" }}
{{- end }}
minRunners: {{ .Values.scaleset.minRunners | int }}
{{- end }}
{{- with .Values.listenerPodTemplate }}
listenerTemplate:
{{- toYaml . | nindent 4}}
{{- end }}
{{- with .Values.listenerMetrics }}
listenerMetrics:
{{- toYaml . | nindent 4 }}
{{- end }}
template:
spec:
containers:
# {{- include "container-spec.runner" . | nindent 8 }}
@@ -74,7 +74,7 @@ tests:
asserts:
- equal:
path: spec.githubConfigSecret
value: "custom-github-secret"
value: '"custom-github-secret"'
- it: should render default runnerGroup when not configured
set:
@@ -230,7 +230,7 @@ tests:
value: "https://github.com/myorg"
- equal:
path: spec.githubConfigSecret
value: "gh-token-secret"
value: '"gh-token-secret"'
- equal:
path: spec.runnerGroup
value: "prod-group"
@@ -12,7 +12,12 @@ tests:
release:
name: "test-name"
namespace: "test-namespace"
chart:
appVersion: "0.14.0"
asserts:
- equal:
path: metadata.labels["helm.sh/chart"]
value: "gha-rs-0.14.0"
- equal:
path: metadata.labels["app.kubernetes.io/name"]
value: "test-name"
@@ -28,9 +33,9 @@ tests:
- equal:
path: metadata.labels["app.kubernetes.io/part-of"]
value: "gha-rs"
- notEqual:
- equal:
path: metadata.labels["app.kubernetes.io/version"]
value: ""
value: "0.14.0"
- equal:
path: metadata.labels["actions.github.com/scale-set-name"]
value: "test-name"
@@ -61,6 +66,9 @@ tests:
- equal:
path: metadata.labels["environment"]
value: "production"
- equal:
path: metadata.labels["helm.sh/chart"]
value: "gha-rs-0.14.0"
- equal:
path: metadata.labels["app.kubernetes.io/name"]
value: "test-name"
@@ -76,9 +84,9 @@ tests:
- equal:
path: metadata.labels["app.kubernetes.io/part-of"]
value: "gha-rs"
- notEqual:
- equal:
path: metadata.labels["app.kubernetes.io/version"]
value: ""
value: "0.14.0"
- equal:
path: metadata.labels["actions.github.com/scale-set-name"]
value: "test-name"
@@ -109,6 +117,9 @@ tests:
- equal:
path: metadata.labels["owner"]
value: "devops"
- equal:
path: metadata.labels["helm.sh/chart"]
value: "gha-rs-0.14.0"
- equal:
path: metadata.labels["app.kubernetes.io/name"]
value: "test-name"
@@ -124,9 +135,9 @@ tests:
- equal:
path: metadata.labels["app.kubernetes.io/part-of"]
value: "gha-rs"
- notEqual:
- equal:
path: metadata.labels["app.kubernetes.io/version"]
value: ""
value: "0.14.0"
- equal:
path: metadata.labels["actions.github.com/scale-set-name"]
value: "test-name"
@@ -165,6 +176,9 @@ tests:
- equal:
path: metadata.labels["environment"]
value: "staging"
- equal:
path: metadata.labels["helm.sh/chart"]
value: "gha-rs-0.14.0"
- equal:
path: metadata.labels["app.kubernetes.io/name"]
value: "test-name"
@@ -180,9 +194,9 @@ tests:
- equal:
path: metadata.labels["app.kubernetes.io/part-of"]
value: "gha-rs"
- notEqual:
- equal:
path: metadata.labels["app.kubernetes.io/version"]
value: ""
value: "0.14.0"
- equal:
path: metadata.labels["actions.github.com/scale-set-name"]
value: "test-name"
@@ -246,8 +260,9 @@ tests:
- equal:
path: metadata.labels["team"]
value: "backend"
- notExists:
- equal:
path: metadata.labels["actions.github.com/custom-label"]
value: "user-value"
- equal:
path: metadata.labels["actions.github.com/scale-set-name"]
value: "test-name"
@@ -272,77 +287,9 @@ tests:
- equal:
path: metadata.labels["owner"]
value: "devops"
- notExists:
- equal:
path: metadata.labels["actions.github.com/global-custom"]
value: "global-value"
- equal:
path: metadata.labels["actions.github.com/scale-set-name"]
value: "test-name"
- it: should render internal resource metadata labels in autoscaling runner set spec
set:
scaleset.name: "test"
auth.url: "https://github.com/org"
auth.githubToken: "gh_token12345"
controllerServiceAccount.name: "arc"
controllerServiceAccount.namespace: "arc-system"
resource:
autoscalingListener:
metadata:
labels:
listener: "true"
listenerServiceAccount:
metadata:
labels:
service-account: "true"
listenerRole:
metadata:
labels:
role: "true"
listenerRoleBinding:
metadata:
labels:
role-binding: "true"
listenerConfigSecret:
metadata:
labels:
config-secret: "true"
ephemeralRunnerSet:
metadata:
labels:
runner-set: "true"
ephemeralRunner:
metadata:
labels:
runner: "true"
ephemeralRunnerConfigSecret:
metadata:
labels:
runner-secret: "true"
release:
name: "test-name"
namespace: "test-namespace"
asserts:
- equal:
path: spec.autoscalingListener.labels.listener
value: "true"
- equal:
path: spec.listenerServiceAccountMetadata.labels.service-account
value: "true"
- equal:
path: spec.listenerRoleMetadata.labels.role
value: "true"
- equal:
path: spec.listenerRoleBindingMetadata.labels.role-binding
value: "true"
- equal:
path: spec.listenerConfigSecretMetadata.labels.config-secret
value: "true"
- equal:
path: spec.ephemeralRunnerSetMetadata.labels.runner-set
value: "true"
- equal:
path: spec.ephemeralRunnerMetadata.labels.runner
value: "true"
- equal:
path: spec.ephemeralRunnerConfigSecretMetadata.labels.runner-secret
value: "true"
value: "test-name"
@@ -5,10 +5,6 @@ scaleset:
# Name of the scaleset
name: ""
runnerGroup: "default"
# Labels are optional list of strings that will be applied to the scaleset
# allowing scaleset to be selected by the listener based on the labels specified in the workflow.
# https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/apply-labels
labels: []
## minRunners is the min number of idle runners. The target number of runners created will be
## calculated as a sum of minRunners and the number of jobs assigned to the scale set.
# minRunners: 0
@@ -106,131 +102,17 @@ resource:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the AutoscalingListener resource
# created by the AutoscalingRunnerSet controller.
autoscalingListener:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the listener ServiceAccount.
listenerServiceAccount:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the listener Role.
listenerRole:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the listener RoleBinding.
listenerRoleBinding:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the listener config Secret.
listenerConfigSecret:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the EphemeralRunnerSet resource.
ephemeralRunnerSet:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the EphemeralRunner resource.
ephemeralRunner:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the EphemeralRunner config Secret.
ephemeralRunnerConfigSecret:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the manager Role resource
managerRole:
metadata:
labels: {}
annotations: {}
extraRules: []
# Specifies metadata that will be applied to the manager RoleBinding resource
managerRoleBinding:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the no-permission ServiceAccount
# (created for non-kubernetes runner modes).
noPermissionServiceAccount:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the kubernetes-mode RoleBinding
# (created when runner.mode is "kubernetes" and a ServiceAccountName is not provided).
kubernetesModeRoleBinding:
metadata:
labels: {}
annotations: {}
# Specifies metadata that will be applied to the kubernetes-mode Role.
kubernetesModeRole:
metadata:
labels: {}
annotations: {}
extraRules: []
# Specifies metadata that will be applied to the kubernetes-mode ServiceAccount.
kubernetesModeServiceAccount:
metadata:
labels: {}
annotations: {}
# TODO: Add more resource customizations when needed
# Template applied for the runner container
runner:
# Mode can be used to automatically add configuration for the selected mode
# The available modes are:
# - "" (default) - no additional configuration is applied
# - "kubernetes" - configuration for running jobs in Kubernetes mode is applied
# - "dind" - configuration for running jobs in Docker-in-Docker mode is
#
# For each mode, we provide configuration out of the box that works for most use
# cases. You can customize our configuration by modifying the fields below,
# or you can leave mode empty and provide your own complete configuration.
mode: ""
# metadata:
# labels: []
# annotations: []
pod:
metadata:
labels: {}
annotations: {}
# Runner pod template customization.
#
# All fields under runner.pod.spec (except those listed below) are applied directly to
# spec.template.spec of the generated runner pod.
#
# Special handling:
# - spec.containers: appended after the generated "runner" container (name "runner" is reserved)
# - spec.initContainers: appended after any generated initContainers (e.g. dind mode)
# - spec.volumes: appended after generated volumes
#
# Note: serviceAccountName is managed by the chart and cannot be overridden via runner.pod.spec.
spec:
# The name "runner" is reserved and must not be used here.
containers: []
initContainers: []
volumes: []
# Mode can be used to automatically add required configuration for the selected mode
mode: "" # Available modes: "", "kubernetes", "dind"
# container field is applied to the container named "runner". You cannot override the name of the runner container
container:
@@ -238,56 +120,14 @@ runner:
command: ["/home/runner/run.sh"]
dind:
# If official runner image is used, or the dind image doesn't contain
# assets from the /home/runner/externals directory, copy externals
# starts the init container whose purpose is to prepare the environment
# for the dind container.
copyRunnerExternals: true
dockerGroupId: "123"
dockerSock: "unix:///var/run/docker.sock"
waitForDockerInSeconds: 120
container:
image: "docker:dind"
# Additional container fields are passed through as-is (e.g. resources, imagePullPolicy, ports, etc.)
# env: []
# volumeMounts: []
# args: [] # overrides the chart-generated dockerd args
# startupProbe: {} # overrides the chart-generated startupProbe
# If default is set to true, we will expand the default spec for the `dind` container, and you can provide fields to override them
default: true
kubernetesMode:
default: true
serviceAccountName: ""
hookPath: "/home/runner/k8s/index.js"
requireJobContainer: true
# workVolumeClaim configures the *ephemeral* PVC used for the runner work directory
# (mounted at /home/runner/_work).
#
# This maps directly to `spec.template.spec.volumes[].ephemeral.volumeClaimTemplate.spec`.
# Any fields you set here are merged onto the chart defaults.
#
# Defaults:
# - accessModes: ["ReadWriteOnce"]
# - storageClassName: "local-path"
# - resources.requests.storage: "1Gi"
workVolumeClaim: {}
# workVolumeClaim:
# accessModes: ["ReadWriteOnce"]
# storageClassName: "fast-ssd"
# resources:
# requests:
# storage: 10Gi
# extensionRef: ""
# extension:
## metadata adds metadata to the config map configured for the hook extension
## NOTE: namespace field is ignored.
# metadata:
# labels: ""
# namespace: ""
# yaml:
# metadata:
# annotations:
# spec:
# containers: []
extraPermissions: []
extension: {}
## A self-signed CA certificate for communication with the GitHub server can be
## provided using a config map key selector. If `runnerMountPath` is set, for
## each runner pod ARC will:
@@ -313,7 +153,6 @@ runner:
controllerServiceAccount:
namespace: ""
name: ""
## listenerMetrics are configurable metrics applied to the listener.
## In order to avoid helm merging these fields, we left the metrics commented out.
## When configuring metrics, please uncomment the listenerMetrics object below.
@@ -1,24 +0,0 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
tests/
@@ -1,58 +0,0 @@
{{/*
Create the labels for the autoscaling runner set.
*/}}
{{- define "autoscaling-runner-set.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "autoscaling-runner-set" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.autoscalingRunnerSet.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the annotations for the autoscaling runner set.
Order of precedence:
1) resource.all.metadata.annotations
2) resource.autoscalingRunnerSet.metadata.annotations
Reserved annotations are excluded from both levels.
*/}}
{{- define "autoscaling-runner-set.annotations" -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $resource := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.autoscalingRunnerSet.metadata.annotations | default (dict))) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $resource -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
{{/*
Render a ResourceMeta block for AutoscalingRunnerSet spec fields.
*/}}
{{- define "autoscaling-runner-set.spec-resource-metadata" -}}
{{- with .labels }}
labels:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .annotations }}
annotations:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- define "autoscaling-runner-set.template-service-account" -}}
{{- $runner := (.Values.runner | default dict) -}}
{{- $runnerMode := (index $runner "mode" | default "") -}}
{{- $kubeMode := (index $runner "kubernetesMode" | default dict) -}}
{{- $kubeServiceAccountName := (index $kubeMode "serviceAccountName" | default "") -}}
{{- $kubeDefaults := (index $kubeMode "default" | default true) -}}
{{- if ne $runnerMode "kubernetes" }}
{{- include "no-permission-serviceaccount.name" . }}
{{- else if not (empty $kubeServiceAccountName) }}
{{- $kubeServiceAccountName }}
{{- else if $kubeDefaults }}
{{- include "kube-mode-serviceaccount.name" . }}
{{- else }}
{{- fail "runner.kubernetesMode.serviceAccountName must be set when runner.mode is 'kubernetes' and runner.kubernetesMode.default is false" -}}
{{- end }}
{{- end }}
@@ -1,135 +0,0 @@
{{- define "autoscaling-runner-set.name" -}}
{{- $name := .Values.runnerScaleSetName | default .Release.Name | replace "_" "-" | trimSuffix "-" }}
{{- if or (empty $name) (gt (len $name) 45) }}
{{ fail "Autoscaling runner set name must have up to 45 characters" }}
{{- end }}
{{- $name }}
{{- end }}
{{- define "autoscaling-runner-set.namespace" -}}
{{- .Values.namespaceOverride | default .Release.Namespace -}}
{{- end }}
{{/*
The name of the manager Role.
*/}}
{{- define "manager-role.name" -}}
{{- printf "%s-manager-role" (include "autoscaling-runner-set.name" .) -}}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "gha-runner-scale-set.chart" -}}
{{- printf "gha-rs-%s" .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
The name of the GitHub secret used for authentication.
*/}}
{{- define "github-secret.name" -}}
{{- if not (empty .Values.auth.secretName) -}}
{{- .Values.auth.secretName -}}
{{- else -}}
{{- printf "%s-github-secret" (include "autoscaling-runner-set.name" .) -}}
{{- end -}}
{{- end }}
{{/*
The name of the no-permission ServiceAccount.
This ServiceAccount is intended for non-kubernetes runner modes when the user
has not specified an explicit ServiceAccount.
*/}}
{{- define "no-permission-serviceaccount.name" -}}
{{- printf "%s-no-permission" (include "autoscaling-runner-set.name" .) -}}
{{- end }}
{{/*
The name of the kubernetes-mode Role.
Kept intentionally aligned with the legacy chart behavior.
*/}}
{{- define "kube-mode-role.name" -}}
{{- printf "%s-kube-mode" (include "autoscaling-runner-set.name" .) -}}
{{- end }}
{{/*
The name of the kubernetes-mode RoleBinding.
Kept intentionally aligned with the kubernetes-mode Role name.
*/}}
{{- define "kube-mode-role-binding.name" -}}
{{- include "kube-mode-role.name" . -}}
{{- end }}
{{/*
The name of the kubernetes-mode ServiceAccount.
Kept intentionally aligned with the legacy chart behavior.
*/}}
{{- define "kube-mode-serviceaccount.name" -}}
{{- include "kube-mode-role.name" . -}}
{{- end }}
{{/*
Create the common labels used across all resources.
*/}}
{{- define "gha-common-labels" -}}
helm.sh/chart: {{ include "gha-runner-scale-set.chart" . }}
app.kubernetes.io/name: {{ include "autoscaling-runner-set.name" . }}
app.kubernetes.io/instance: {{ include "autoscaling-runner-set.name" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/part-of: "gha-rs"
actions.github.com/scale-set-name: {{ include "autoscaling-runner-set.name" . }}
actions.github.com/scale-set-namespace: {{ include "autoscaling-runner-set.namespace" . }}
{{- end }}
{{/*
Get the runner container image.
It defaults to ghcr.io/actions/actions-runner:latest if not specified.
*/}}
{{- define "runner.image" -}}
{{- $runner := .Values.runner.container | default dict -}}
{{- if not (kindIs "map" $runner) -}}
{{- fail "runner.container must be a map/object" -}}
{{- end -}}
{{- $image := $runner.image | default "ghcr.io/actions/actions-runner:latest" -}}
{{- if not (kindIs "string" $image) -}}
{{- fail "runner.container.image must be a string" -}}
{{- end -}}
{{- $image }}
{{- end }}
{{- define "runner.command" -}}
{{- $runner := .Values.runner.container | default dict -}}
{{- if not (kindIs "map" $runner) -}}
{{- fail "runner.container must be a map/object" -}}
{{- end -}}
{{- $command := $runner.command | default (list "/home/runner/run.sh") -}}
{{- if not (kindIs "slice" $command) -}}
{{- fail "runner.container.command must be a list/array" -}}
{{- end -}}
{{- toJson $command -}}
{{- end }}
{{/*
Hook extension ConfigMap name for kubernetes runner mode.
If runner.kubernetesMode.extension.metadata.name is set, use it.
Otherwise, default to a name derived from the scale set name.
*/}}
{{- define "runner-mode-kubernetes.extension-name" -}}
{{- $runner := (.Values.runner | default dict) -}}
{{- $kubeMode := (index $runner "kubernetesMode" | default dict) -}}
{{- $extension := (index $kubeMode "extension" | default dict) -}}
{{- $meta := (index $extension "metadata" | default dict) -}}
{{- $name := (index $meta "name" | default "") -}}
{{- if not (kindIs "string" $name) -}}
{{- fail "runner.kubernetesMode.extension.metadata.name must be a string" -}}
{{- end -}}
{{- default (printf "%s-hook-extension" (include "autoscaling-runner-set.name" .) | trunc 63 | trimSuffix "-") $name -}}
{{- end }}
@@ -1,184 +0,0 @@
{{/*
Create the labels for the GitHub auth secret.
*/}}
{{- define "github-secret.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "github-secret" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the annotations for the GitHub auth secret.
Only global annotations are applied.
Reserved annotations are excluded.
*/}}
{{- define "github-secret.annotations" -}}
{{- $annotations := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
{{/*
Create the labels for the no-permission ServiceAccount.
*/}}
{{- define "no-permission-serviceaccount.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "no-permission-serviceaccount" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.noPermissionServiceAccount.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the annotations for the no-permission ServiceAccount.
Order of precedence:
1) resource.all.metadata.annotations
2) resource.noPermissionServiceAccount.metadata.annotations
Reserved annotations are excluded from both levels.
*/}}
{{- define "no-permission-serviceaccount.annotations" -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $resource := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.noPermissionServiceAccount.metadata.annotations | default (dict))) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $resource -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
{{/*
Takes a map of user labels and removes the ones with "actions.github.com/" prefix
*/}}
{{- define "apply-non-reserved-gha-labels-and-annotations" -}}
{{- $userLabels := . -}}
{{- $processed := dict -}}
{{- range $key, $value := $userLabels -}}
{{- if not (hasPrefix "actions.github.com/" $key) -}}
{{- $_ := set $processed $key $value -}}
{{- end -}}
{{- end -}}
{{- if not (empty $processed) -}}
{{- $processed | toYaml }}
{{- end }}
{{- end }}
{{/*
GitHub Server TLS helper parts
These helpers centralize TLS env/volumeMount/volume snippets so that runner modes
inject the certificate consistently.
Behavior:
- If githubServerTLS.runnerMountPath is empty: emit nothing.
- If runnerMountPath is set: require certificateFrom.configMapKeyRef.name + key.
- Avoid duplicating user-provided env vars / volumeMounts.
*/}}
{{- define "githubServerTLS.config" -}}
{{- $tls := (default (dict) .Values.githubServerTLS) -}}
{{- if and (not (empty $tls)) (not (kindIs "map" $tls)) -}}
{{- fail "githubServerTLS must be a map/object" -}}
{{- end -}}
{{- toYaml $tls -}}
{{- end -}}
{{- define "githubServerTLS.mountPath" -}}
{{- $tls := (include "githubServerTLS.config" .) | fromYaml -}}
{{- (index $tls "runnerMountPath" | default "") -}}
{{- end -}}
{{- define "githubServerTLS.configMapName" -}}
{{- $mountPath := include "githubServerTLS.mountPath" . -}}
{{- if not (empty $mountPath) -}}
{{- $tls := (include "githubServerTLS.config" .) | fromYaml -}}
{{- required "githubServerTLS.certificateFrom.configMapKeyRef.name is required when githubServerTLS.runnerMountPath is set" (dig "certificateFrom" "configMapKeyRef" "name" "" $tls) -}}
{{- end -}}
{{- end -}}
{{- define "githubServerTLS.certKey" -}}
{{- $mountPath := include "githubServerTLS.mountPath" . -}}
{{- if not (empty $mountPath) -}}
{{- $tls := (include "githubServerTLS.config" .) | fromYaml -}}
{{- required "githubServerTLS.certificateFrom.configMapKeyRef.key is required when githubServerTLS.runnerMountPath is set" (dig "certificateFrom" "configMapKeyRef" "key" "" $tls) -}}
{{- end -}}
{{- end -}}
{{- define "githubServerTLS.certFilePath" -}}
{{- $mountPath := include "githubServerTLS.mountPath" . -}}
{{- if not (empty $mountPath) -}}
{{- $key := include "githubServerTLS.certKey" . -}}
{{- printf "%s/%s" (trimSuffix "/" $mountPath) $key -}}
{{- end -}}
{{- end -}}
{{- define "githubServerTLS.envItems" -}}
{{- $root := .root -}}
{{- $mountPath := include "githubServerTLS.mountPath" $root -}}
{{- if not (empty $mountPath) -}}
{{- $existing := (.existingEnv | default list) -}}
{{- $hasNodeExtra := false -}}
{{- $hasRunnerUpdate := false -}}
{{- if kindIs "slice" $existing -}}
{{- range $existing -}}
{{- if and (kindIs "map" .) (eq ((index . "name") | default "") "NODE_EXTRA_CA_CERTS") -}}
{{- $hasNodeExtra = true -}}
{{- end -}}
{{- if and (kindIs "map" .) (eq ((index . "name") | default "") "RUNNER_UPDATE_CA_CERTS") -}}
{{- $hasRunnerUpdate = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $hasNodeExtra -}}
- name: NODE_EXTRA_CA_CERTS
value: {{ include "githubServerTLS.certFilePath" $root | quote }}
{{ end }}
{{- if not $hasRunnerUpdate -}}
- name: RUNNER_UPDATE_CA_CERTS
value: "1"
{{ end }}
{{- end -}}
{{- end -}}
{{- define "githubServerTLS.volumeMountItem" -}}
{{- $root := .root -}}
{{- $mountPath := include "githubServerTLS.mountPath" $root -}}
{{- if not (empty $mountPath) -}}
{{- $existing := (.existingVolumeMounts | default list) -}}
{{- $hasMount := false -}}
{{- if kindIs "slice" $existing -}}
{{- range $existing -}}
{{- if and (kindIs "map" .) (eq ((index . "name") | default "") "github-server-tls-cert") -}}
{{- $hasMount = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $hasMount -}}
- name: github-server-tls-cert
mountPath: {{ $mountPath | quote }}
readOnly: true
{{ end }}
{{- end -}}
{{- end -}}
{{- define "githubServerTLS.podVolumeItem" -}}
{{- $mountPath := include "githubServerTLS.mountPath" . -}}
{{- if not (empty $mountPath) -}}
{{- $cmName := include "githubServerTLS.configMapName" . -}}
{{- $key := include "githubServerTLS.certKey" . -}}
- name: github-server-tls-cert
configMap:
name: {{ $cmName | quote }}
items:
- key: {{ $key | quote }}
path: {{ $key | quote }}
{{ end }}
{{ end }}
@@ -1,26 +0,0 @@
{{- define "listener-template.pod" -}}
{{- $metadata := .Values.listenerPodTemplate.metadata | default dict -}}
{{- $spec := .Values.listenerPodTemplate.spec | default dict -}}
{{- if and (empty $metadata) (empty $spec) -}}
{{- fail "listenerPodTemplate must have at least metadata or spec defined" -}}
{{- end -}}
{{- with $metadata -}}
metadata:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with $spec -}}
spec:
{{- $containers := (index . "containers" | default (list)) -}}
{{- if empty $containers }}
containers:
- name: listener
{{- else }}
containers:
{{- toYaml $containers | nindent 4 }}
{{- end }}
{{- $rest := (omit . "containers") -}}
{{- if gt (len $rest) 0 }}
{{- toYaml $rest | nindent 2 }}
{{- end }}
{{- end }}
{{- end -}}
@@ -1,69 +0,0 @@
{{/*
Create the labels for the manager Role.
*/}}
{{- define "manager-role.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "manager-role" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.managerRole.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the annotations for the manager Role.
Order of precedence:
1) resource.all.metadata.annotations
2) resource.managerRole.metadata.annotations
Reserved annotations are excluded from both levels.
*/}}
{{- define "manager-role.annotations" -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $resource := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.managerRole.metadata.annotations | default (dict))) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $resource -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
{{/*
The name of the manager RoleBinding.
Kept intentionally aligned with the manager Role name, mirroring the legacy
chart behavior.
*/}}
{{- define "manager-role-binding.name" -}}
{{- include "manager-role.name" . -}}
{{- end }}
{{/*
Create the labels for the manager RoleBinding.
*/}}
{{- define "manager-role-binding.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "manager-role-binding" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.managerRoleBinding.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the annotations for the manager RoleBinding.
Order of precedence:
1) resource.all.metadata.annotations
2) resource.managerRoleBinding.metadata.annotations
Reserved annotations are excluded from both levels.
*/}}
{{- define "manager-role-binding.annotations" -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $resource := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.managerRoleBinding.metadata.annotations | default (dict))) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $resource -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
@@ -1,166 +0,0 @@
{{- define "runner-mode-dind.runner-container" -}}
name: runner
image: {{ include "runner.image" . | quote }}
command: {{ include "runner.command" . }}
env:
- {{ include "runner-mode-dind.env-docker-host" . | nindent 4 }}
- {{ include "runner-mode-dind.env-wait-for-docker-timeout" . | nindent 4 }}
{{/* TODO:: Should we skip DOCKER_HOST and RUNNER_WAIT_FOR_DOCKER_IN_SECONDS? */}}
{{- with .Values.runner.env }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{ include "githubServerTLS.envItems" (dict "root" $ "existingEnv" (.Values.runner.env | default list)) | nindent 2 }}
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-sock
mountPath: {{ include "runner-mode-dind.sock-mount-dir" . | quote }}
{{ include "githubServerTLS.volumeMountItem" (dict "root" $ "existingVolumeMounts" (list)) | nindent 2 }}
{{- end }}
{{- define "runner-mode-dind.dind-container" -}}
{{- $dind := .Values.runner.dind | default dict -}}
{{- $dindContainer := ($dind.container | default dict) -}}
{{- if and (hasKey $dind "container") (not (kindIs "map" $dindContainer)) -}}
{{- fail "runner.dind.container must be a map/object" -}}
{{- end -}}
{{- if and (hasKey $dindContainer "env") (not (kindIs "slice" $dindContainer.env)) -}}
{{- fail "runner.dind.container.env must be a list" -}}
{{- end -}}
{{- if and (hasKey $dindContainer "volumeMounts") (not (kindIs "slice" $dindContainer.volumeMounts)) -}}
{{- fail "runner.dind.container.volumeMounts must be a list" -}}
{{- end -}}
{{- if hasKey $dindContainer "volumes" -}}
{{- fail "runner.dind.container.volumes is not supported; use runner.pod.spec.volumes" -}}
{{- end -}}
{{- if and (hasKey $dindContainer "args") (not (kindIs "slice" $dindContainer.args)) -}}
{{- fail "runner.dind.container.args must be a list" -}}
{{- end -}}
{{- if and (hasKey $dindContainer "securityContext") (not (kindIs "map" $dindContainer.securityContext)) -}}
{{- fail "runner.dind.container.securityContext must be a map/object" -}}
{{- end -}}
{{- if and (hasKey $dindContainer "startupProbe") (not (kindIs "map" $dindContainer.startupProbe)) -}}
{{- fail "runner.dind.container.startupProbe must be a map/object" -}}
{{- end -}}
name: {{ $dindContainer.name | default "dind" }}
image: {{ $dindContainer.image | default "docker:dind" | quote }}
args:
{{- if $dindContainer.args }}
{{- toYaml $dindContainer.args | nindent 2 }}
{{- else }}
{{- include "runner-mode-dind.args" . | nindent 2 }}
{{- end }}
env:
- name: DOCKER_GROUP_GID
value: {{ ($dind.dockerGroupId | default "123") | quote }}
{{- with $dindContainer.env }}
{{- toYaml . | nindent 2 }}
{{- end }}
securityContext:
{{- if $dindContainer.securityContext }}
{{- toYaml $dindContainer.securityContext | nindent 2 }}
{{ else }}
{{- toYaml (dict "privileged" true) | nindent 2 }}
{{- end }}
restartPolicy: Always
startupProbe:
{{- if $dindContainer.startupProbe }}
{{- toYaml $dindContainer.startupProbe | nindent 2 }}
{{- else }}
{{- include "runner-mode-dind.startup-probe" . | nindent 2 }}
{{- end }}
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-sock
mountPath: {{ include "runner-mode-dind.sock-mount-dir" . | quote }}
{{- with $dindContainer.volumeMounts }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- if $dind.copyRunnerExternals }}
- name: dind-externals
mountPath: /home/runner/externals
{{ end }}
{{- $extra := omit $dindContainer "name" "image" "args" "env" "securityContext" "startupProbe" "volumeMounts" -}}
{{- if not (empty $extra) -}}
{{ toYaml $extra }}
{{- end -}}
{{- end }}
{{- define "runner-mode-dind.pod-volumes" -}}
- name: work
emptyDir: {}
- name: dind-sock
emptyDir: {}
{{ include "githubServerTLS.podVolumeItem" . }}
{{- if .Values.runner.dind.copyRunnerExternals }}
- name: dind-externals
emptyDir: {}
{{- end }}
{{- end }}
{{- define "runner-mode-dind.copy-externals" -}}
name: init-dind-externals
image: ghcr.io/actions/actions-runner:latest
command: ["cp", "-r", "/home/runner/externals/.", "/home/runner/tmpDir/"]
volumeMounts:
- name: dind-externals
mountPath: /home/runner/tmpDir
{{- end }}
{{- define "runner-mode-dind.startup-probe" -}}
exec:
command:
- docker
- info
initialDelaySeconds: 0
failureThreshold: 24
periodSeconds: 5
{{- end }}
{{- define "runner-mode-dind.args" -}}
{{- $dind := .Values.runner.dind | default dict -}}
{{- $dockerSock := $dind.dockerSock | default "unix:///var/run/docker.sock" -}}
{{- if not (kindIs "string" $dockerSock) -}}
{{- fail "runner.dind.dockerSock must be a string" -}}
{{- end -}}
- dockerd
- {{ printf "--host=%s" $dockerSock }}
- --group=$(DOCKER_GROUP_GID)
{{- end }}
{{- define "runner-mode-dind.env-docker-host" -}}
{{- $dind := .Values.runner.dind | default dict -}}
{{- $dockerSock := $dind.dockerSock | default "unix:///var/run/docker.sock" -}}
{{- if not (kindIs "string" $dockerSock) -}}
{{- fail "runner.dind.dockerSock must be a string" -}}
{{- end -}}
name: DOCKER_HOST
value: {{ $dockerSock | quote }}
{{- end }}
{{- define "runner-mode-dind.env-wait-for-docker-timeout" -}}
{{- $dind := .Values.runner.dind | default dict -}}
{{- $waitForDockerInSeconds := $dind.waitForDockerInSeconds | default 120 -}}
{{- if not (or (kindIs "int" $waitForDockerInSeconds) (kindIs "int64" $waitForDockerInSeconds) (kindIs "float64" $waitForDockerInSeconds)) -}}
{{- fail "runner.dind.waitForDockerInSeconds must be a number" -}}
{{- end -}}
{{- $waitForDockerInSecondsInt := ($waitForDockerInSeconds | int) -}}
{{- if lt $waitForDockerInSecondsInt 0 -}}
{{- fail "runner.dind.waitForDockerInSeconds must be non-negative" -}}
{{- end -}}
name: RUNNER_WAIT_FOR_DOCKER_IN_SECONDS
value: {{ $waitForDockerInSecondsInt | toString | quote }}
{{- end }}
{{- define "runner-mode-dind.sock-mount-dir" -}}
{{- $dind := .Values.runner.dind | default dict -}}
{{- $dockerSock := $dind.dockerSock | default "unix:///var/run/docker.sock" -}}
{{- if not (kindIs "string" $dockerSock) -}}
{{- fail "runner.dind.dockerSock must be a string" -}}
{{- end -}}
{{- $dockerSockPath := trimPrefix "unix://" $dockerSock -}}
{{- dir $dockerSockPath -}}
{{- end }}
@@ -1,34 +0,0 @@
{{/*
Container spec that is expanded for the runner container
*/}}
{{- define "runner-mode-empty.runner-container" -}}
{{- if not .Values.runner.container }}
{{ fail "You must provide a runner container specification in values.runner.container" }}
{{- end }}
name: runner
image: {{ .Values.runner.container.image | default "ghcr.io/actions/actions-runner:latest" }}
command: {{ toJson (default (list "/home/runner/run.sh") .Values.runner.container.command) }}
{{ $tlsEnvItems := include "githubServerTLS.envItems" (dict "root" $ "existingEnv" (.Values.runner.container.env | default list)) }}
{{ if or .Values.runner.container.env $tlsEnvItems }}
env:
{{- with .Values.runner.container.env }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{ $tlsEnvItems | nindent 2 }}
{{ end }}
{{ $tlsVolumeMountItem := include "githubServerTLS.volumeMountItem" (dict "root" $ "existingVolumeMounts" (.Values.runner.container.volumeMounts | default list)) }}
{{ if or .Values.runner.container.volumeMounts $tlsVolumeMountItem }}
volumeMounts:
{{- with .Values.runner.container.volumeMounts }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{ $tlsVolumeMountItem | nindent 2 }}
{{ end }}
{{ $extra := omit .Values.runner.container "name" "image" "command" "env" "volumeMounts" }}
{{- if not (empty $extra) -}}
{{ toYaml $extra }}
{{- end -}}
{{- end }}
@@ -1,242 +0,0 @@
{{- define "runner-mode-kubernetes.runner-container" -}}
{{- $runner := (.Values.runner | default dict) -}}
{{- $kubeMode := (index $runner "kubernetesMode" | default dict) -}}
{{- $hookPath := (index $kubeMode "hookPath" | default "/home/runner/k8s/index.js") -}}
{{- $extensionRef := (index $kubeMode "extensionRef" | default "") -}}
{{- $extension := (index $kubeMode "extension" | default dict) -}}
{{- $extensionYamlRaw := "" -}}
{{- if kindIs "map" $extension -}}
{{- if hasKey $extension "yaml" -}}
{{- $extensionYamlRaw = (index $extension "yaml") -}}
{{- end -}}
{{- end -}}
{{- $extensionYamlStr := "" -}}
{{- if empty $extensionYamlRaw -}}
{{- $extensionYamlStr = "" -}}
{{- else if kindIs "string" $extensionYamlRaw -}}
{{- $extensionYamlStr = $extensionYamlRaw -}}
{{- else if kindIs "map" $extensionYamlRaw -}}
{{- $extensionYamlStr = toYaml $extensionYamlRaw -}}
{{- end -}}
{{- $hasExtension := or (not (empty $extensionRef)) (not (empty $extensionYamlStr)) -}}
{{- $hookTemplatePath := printf "%s/hook-template.yaml" (dir $hookPath) -}}
{{- $setHookTemplateEnv := true -}}
{{- $userEnv := (.Values.runner.env | default list) -}}
{{- if kindIs "slice" $userEnv -}}
{{- range $userEnv -}}
{{- if and (kindIs "map" .) (eq ((index . "name") | default "") "ACTIONS_RUNNER_CONTAINER_HOOK_TEMPLATE") -}}
{{- $setHookTemplateEnv = false -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not (kindIs "string" $hookPath) -}}
{{- fail "runner.kubernetesMode.hookPath must be a string" -}}
{{- end -}}
{{- if not (kindIs "string" $extensionRef) -}}
{{- fail "runner.kubernetesMode.extensionRef must be a string" -}}
{{- end -}}
{{- if and (empty $extensionRef) (hasKey $kubeMode "extension") (not (kindIs "map" $extension)) -}}
{{- fail "runner.kubernetesMode.extension must be an object when runner.kubernetesMode.extensionRef is empty" -}}
{{- end -}}
{{- if and (empty $extensionRef) (not (empty $extensionYamlRaw)) (not (or (kindIs "string" $extensionYamlRaw) (kindIs "map" $extensionYamlRaw))) -}}
{{- fail "runner.kubernetesMode.extension.yaml must be a string or an object" -}}
{{- end -}}
{{- $requireJobContainer := true -}}
{{- if hasKey $kubeMode "requireJobContainer" -}}
{{- $requireJobContainer = (index $kubeMode "requireJobContainer") -}}
{{- end -}}
{{- if not (kindIs "bool" $requireJobContainer) -}}
{{- fail "runner.kubernetesMode.requireJobContainer must be a bool" -}}
{{- end -}}
name: runner
image: {{ include "runner.image" . | quote }}
command: {{ include "runner.command" . }}
{{ $tlsEnvItems := include "githubServerTLS.envItems" (dict "root" $ "existingEnv" (.Values.runner.env | default list)) }}
env:
- name: ACTIONS_RUNNER_CONTAINER_HOOKS
value: {{ $hookPath | quote }}
- name: ACTIONS_RUNNER_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER
value: {{ ternary "true" "false" $requireJobContainer | quote }}
{{- if not $requireJobContainer -}}
{{- printf "# WARNING: runner.kubernetesMode.requireJobContainer is set to false. This means that the runner container will be used to execute jobs, which may lead to security risks if the runner is compromised. It is recommended to set runner.kubernetesMode.requireJobContainer to true in production environments." }}
{{- end -}}
{{- if and $hasExtension $setHookTemplateEnv }}
- name: ACTIONS_RUNNER_CONTAINER_HOOK_TEMPLATE
value: {{ $hookTemplatePath | quote }}
{{- end }}
{{- with .Values.runner.env }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{ $tlsEnvItems | nindent 2 }}
volumeMounts:
- name: work
mountPath: /home/runner/_work
{{- if $hasExtension }}
- name: hook-extension
mountPath: {{ $hookTemplatePath | quote }}
subPath: extension
readOnly: true
{{- end }}
{{ include "githubServerTLS.volumeMountItem" (dict "root" $ "existingVolumeMounts" (list)) | nindent 2 }}
{{- end }}
{{- define "runner-mode-kubernetes.pod-volumes" -}}
{{- $runner := (.Values.runner | default dict) -}}
{{- $kubeMode := (index $runner "kubernetesMode" | default dict) -}}
{{- $extensionRef := (index $kubeMode "extensionRef" | default "") -}}
{{- $extension := (index $kubeMode "extension" | default dict) -}}
{{- $extensionYamlRaw := "" -}}
{{- if kindIs "map" $extension -}}
{{- if hasKey $extension "yaml" -}}
{{- $extensionYamlRaw = (index $extension "yaml") -}}
{{- end -}}
{{- end -}}
{{- $extensionYamlStr := "" -}}
{{- if empty $extensionYamlRaw -}}
{{- $extensionYamlStr = "" -}}
{{- else if kindIs "string" $extensionYamlRaw -}}
{{- $extensionYamlStr = $extensionYamlRaw -}}
{{- else if kindIs "map" $extensionYamlRaw -}}
{{- $extensionYamlStr = toYaml $extensionYamlRaw -}}
{{- end -}}
{{- $hasExtension := or (not (empty $extensionRef)) (not (empty $extensionYamlStr)) -}}
{{- $claim := (index $kubeMode "workVolumeClaim" | default dict) -}}
{{- if and (not (empty $claim)) (not (kindIs "map" $claim)) -}}
{{- fail "runner.kubernetesMode.workVolumeClaim must be a map/object" -}}
{{- end -}}
{{- if not (kindIs "string" $extensionRef) -}}
{{- fail "runner.kubernetesMode.extensionRef must be a string" -}}
{{- end -}}
{{- if and (empty $extensionRef) (hasKey $kubeMode "extension") (not (kindIs "map" $extension)) -}}
{{- fail "runner.kubernetesMode.extension must be an object when runner.kubernetesMode.extensionRef is empty" -}}
{{- end -}}
{{- if and (empty $extensionRef) (not (empty $extensionYamlRaw)) (not (or (kindIs "string" $extensionYamlRaw) (kindIs "map" $extensionYamlRaw))) -}}
{{- fail "runner.kubernetesMode.extension.yaml must be a string or an object" -}}
{{- end -}}
{{- $defaultClaim := dict "accessModes" (list "ReadWriteOnce") "storageClassName" "local-path" "resources" (dict "requests" (dict "storage" "1Gi")) -}}
{{- $claimSpec := mergeOverwrite $defaultClaim $claim -}}
- name: work
ephemeral:
volumeClaimTemplate:
spec:
{{- toYaml $claimSpec | nindent 8 }}
{{- if $hasExtension }}
- name: hook-extension
configMap:
name: {{ if not (empty $extensionRef) }}{{ $extensionRef | quote }}{{ else }}{{ include "runner-mode-kubernetes.extension-name" . | quote }}{{ end }}
{{- end }}
{{ include "githubServerTLS.podVolumeItem" . }}
{{- end }}
{{/*
Create the annotations for the kubernetes-mode ServiceAccount.
Order of precedence:
1) resource.all.metadata.annotations
2) resource.kubernetesModeServiceAccount.metadata.annotations
Reserved annotations are excluded from both levels.
*/}}
{{- define "kube-mode-serviceaccount.annotations" -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $resource := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.kubernetesModeServiceAccount.metadata.annotations | default (dict))) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $resource -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
{{/*
Create the labels for the kubernetes-mode ServiceAccount.
*/}}
{{- define "kube-mode-serviceaccount.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "kube-mode-serviceaccount" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.kubernetesModeServiceAccount.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the labels for the kubernetes-mode Role.
*/}}
{{- define "kube-mode-role.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "kube-mode-role" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.kubernetesModeRole.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the annotations for the kubernetes-mode RoleBinding.
Order of precedence:
1) resource.all.metadata.annotations
2) resource.kubernetesModeRoleBinding.metadata.annotations
Reserved annotations are excluded from both levels.
*/}}
{{- define "kube-mode-role-binding.annotations" -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $resource := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.kubernetesModeRoleBinding.metadata.annotations | default (dict))) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $resource -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
{{/*
Create the labels for the kubernetes-mode RoleBinding.
*/}}
{{- define "kube-mode-role-binding.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "kube-mode-role-binding" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $userLabels := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.kubernetesModeRoleBinding.metadata.labels | default (dict)) | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $userLabels $resourceLabels $commonLabels) }}
{{- end }}
{{/*
Create the annotations for the kubernetes-mode Role.
Order of precedence:
1) resource.all.metadata.annotations
2) resource.kubernetesModeRole.metadata.annotations
Reserved annotations are excluded from both levels.
*/}}
{{- define "kube-mode-role.annotations" -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $resource := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.kubernetesModeRole.metadata.annotations | default (dict))) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $resource -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations }}
{{- end }}
{{- end }}
{{- define "kube-mode-extension.name" -}}
{{- $runner := (.Values.runner | default dict) -}}
{{- $kubeMode := (index $runner "kubernetesMode" | default dict) -}}
{{- $extension := (index $kubeMode "extension" | default dict) -}}
{{- $meta := (index $extension "metadata" | default dict) -}}
{{- $name := (index $meta "name" | default "") -}}
{{- if not (kindIs "string" $name) -}}
{{- fail "runner.kubernetesMode.extension.metadata.name must be a string" -}}
{{- end -}}
{{- default (printf "%s-hook-extension" (include "autoscaling-runner-set.name" .) | trunc 63 | trimSuffix "-") $name -}}
{{- end }}
{{/*
Create the labels for the hook extension ConfigMap.
*/}}
{{- define "kube-mode-extension.labels" -}}
{{- $resourceLabels := dict "app.kubernetes.io/component" "hook-extension" -}}
{{- $commonLabels := include "gha-common-labels" . | fromYaml -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- toYaml (mergeOverwrite $global $resourceLabels $commonLabels) -}}
{{- end }}
@@ -1,65 +0,0 @@
{{/*
Create labels for the runner Pod template (spec.template.metadata.labels).
Order of precedence:
1) resource.all.metadata.labels
2) runner.pod.metadata.labels
3) common labels (cannot be overridden)
Reserved actions.github.com/* labels are excluded from user/global inputs.
*/}}
{{- define "autoscaling-runner-set.runner-pod.labels" -}}
{{- $runner := (.Values.runner | default dict) -}}
{{- $pod := (index $runner "pod" | default dict) -}}
{{- if not (kindIs "map" $pod) -}}
{{- fail ".Values.runner.pod must be a map/object" -}}
{{- end -}}
{{- $podMetadata := (index $pod "metadata" | default dict) -}}
{{- if not (kindIs "map" $podMetadata) -}}
{{- fail ".Values.runner.pod.metadata must be a map/object" -}}
{{- end -}}
{{- $userRaw := (index $podMetadata "labels" | default (dict)) -}}
{{- if not (kindIs "map" $userRaw) -}}
{{- fail ".Values.runner.pod.metadata.labels must be a map/object" -}}
{{- end -}}
{{- $global := include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.labels | default (dict)) | fromYaml -}}
{{- $user := include "apply-non-reserved-gha-labels-and-annotations" $userRaw | fromYaml -}}
{{- $common := include "gha-common-labels" . | fromYaml -}}
{{- $labels := mergeOverwrite $global $user $common -}}
{{- if not (empty $labels) -}}
{{- toYaml $labels -}}
{{- end -}}
{{- end }}
{{/*
Create annotations for the runner Pod template (spec.template.metadata.annotations).
Order of precedence:
1) resource.all.metadata.annotations
2) runner.pod.metadata.annotations
Reserved actions.github.com/* annotations are excluded from user/global inputs.
*/}}
{{- define "autoscaling-runner-set.runner-pod.annotations" -}}
{{- $runner := (.Values.runner | default dict) -}}
{{- $pod := (index $runner "pod" | default dict) -}}
{{- if not (kindIs "map" $pod) -}}
{{- fail ".Values.runner.pod must be a map/object" -}}
{{- end -}}
{{- $podMetadata := (index $pod "metadata" | default dict) -}}
{{- if not (kindIs "map" $podMetadata) -}}
{{- fail ".Values.runner.pod.metadata must be a map/object" -}}
{{- end -}}
{{- $userRaw := (index $podMetadata "annotations" | default (dict)) -}}
{{- if not (kindIs "map" $userRaw) -}}
{{- fail ".Values.runner.pod.metadata.annotations must be a map/object" -}}
{{- end -}}
{{- $global := (include "apply-non-reserved-gha-labels-and-annotations" (.Values.resource.all.metadata.annotations | default (dict))) | fromYaml -}}
{{- $user := (include "apply-non-reserved-gha-labels-and-annotations" $userRaw) | fromYaml -}}
{{- $annotations := mergeOverwrite $global $user -}}
{{- if not (empty $annotations) -}}
{{- toYaml $annotations -}}
{{- end -}}
{{- end }}

Some files were not shown because too many files have changed in this diff Show More