mirror of
https://github.com/actions/actions-runner-controller.git
synced 2026-01-06 18:08:04 +08:00
Rename actions-runner-controller-2 and auto-scaling-runner-set helm charts (#2333)
Co-authored-by: Ava S <avastancu@github.com>
This commit is contained in:
23
charts/gha-runner-scale-set/.helmignore
Normal file
23
charts/gha-runner-scale-set/.helmignore
Normal file
@@ -0,0 +1,23 @@
|
||||
# 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/
|
||||
33
charts/gha-runner-scale-set/Chart.yaml
Normal file
33
charts/gha-runner-scale-set/Chart.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
apiVersion: v2
|
||||
name: gha-runner-scale-set
|
||||
description: A Helm chart for deploying an AutoScalingRunnerSet
|
||||
|
||||
# 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.2.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.2.0"
|
||||
|
||||
home: https://github.com/actions/dev-arc
|
||||
|
||||
sources:
|
||||
- "https://github.com/actions/dev-arc"
|
||||
|
||||
maintainers:
|
||||
- name: actions
|
||||
url: https://github.com/actions
|
||||
6
charts/gha-runner-scale-set/ci/ci-values.yaml
Normal file
6
charts/gha-runner-scale-set/ci/ci-values.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Set the following to dummy values.
|
||||
# This is only useful in CI
|
||||
githubConfigUrl: https://github.com/actions/actions-runner-controller
|
||||
|
||||
githubConfigSecret:
|
||||
github_token: test
|
||||
3
charts/gha-runner-scale-set/templates/NOTES.txt
Normal file
3
charts/gha-runner-scale-set/templates/NOTES.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Thank you for installing {{ .Chart.Name }}.
|
||||
|
||||
Your release is named {{ .Release.Name }}.
|
||||
330
charts/gha-runner-scale-set/templates/_helpers.tpl
Normal file
330
charts/gha-runner-scale-set/templates/_helpers.tpl
Normal file
@@ -0,0 +1,330 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "gha-runner-scale-set.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- 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-runner-scale-set.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.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 }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "gha-runner-scale-set.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "gha-runner-scale-set.labels" -}}
|
||||
helm.sh/chart: {{ include "gha-runner-scale-set.chart" . }}
|
||||
{{ include "gha-runner-scale-set.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "gha-runner-scale-set.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "gha-runner-scale-set.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.githubsecret" -}}
|
||||
{{- if kindIs "string" .Values.githubConfigSecret }}
|
||||
{{- if not (empty .Values.githubConfigSecret) }}
|
||||
{{- .Values.githubConfigSecret }}
|
||||
{{- else}}
|
||||
{{- fail "Values.githubConfigSecret is required for setting auth with GitHub server." }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- include "gha-runner-scale-set.fullname" . }}-github-secret
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.noPermissionServiceAccountName" -}}
|
||||
{{- include "gha-runner-scale-set.fullname" . }}-no-permission-service-account
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.kubeModeRoleName" -}}
|
||||
{{- include "gha-runner-scale-set.fullname" . }}-kube-mode-role
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.kubeModeServiceAccountName" -}}
|
||||
{{- include "gha-runner-scale-set.fullname" . }}-kube-mode-service-account
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.dind-init-container" -}}
|
||||
{{- range $i, $val := .Values.template.spec.containers -}}
|
||||
{{- if eq $val.name "runner" -}}
|
||||
image: {{ $val.image }}
|
||||
{{- if $val.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{ $val.imagePullSecrets | toYaml -}}
|
||||
{{- end }}
|
||||
command: ["cp"]
|
||||
args: ["-r", "-v", "/actions-runner/externals/.", "/actions-runner/tmpDir/"]
|
||||
volumeMounts:
|
||||
- name: dind-externals
|
||||
mountPath: /actions-runner/tmpDir
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.dind-container" -}}
|
||||
image: docker:dind
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- name: work
|
||||
mountPath: /actions-runner/_work
|
||||
- name: dind-cert
|
||||
mountPath: /certs/client
|
||||
- name: dind-externals
|
||||
mountPath: /actions-runner/externals
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.dind-volume" -}}
|
||||
- name: dind-cert
|
||||
emptyDir: {}
|
||||
- name: dind-externals
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.dind-work-volume" -}}
|
||||
{{- $createWorkVolume := 1 }}
|
||||
{{- range $i, $volume := .Values.template.spec.volumes }}
|
||||
{{- if eq $volume.name "work" }}
|
||||
{{- $createWorkVolume = 0 -}}
|
||||
- name: work
|
||||
{{- range $key, $val := $volume }}
|
||||
{{- if ne $key "name" }}
|
||||
{{ $key }}: {{ $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq $createWorkVolume 1 }}
|
||||
- name: work
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.kubernetes-mode-work-volume" -}}
|
||||
{{- $createWorkVolume := 1 }}
|
||||
{{- range $i, $volume := .Values.template.spec.volumes }}
|
||||
{{- if eq $volume.name "work" }}
|
||||
{{- $createWorkVolume = 0 -}}
|
||||
- name: work
|
||||
{{- range $key, $val := $volume }}
|
||||
{{- if ne $key "name" }}
|
||||
{{ $key }}: {{ $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq $createWorkVolume 1 }}
|
||||
- name: work
|
||||
ephemeral:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
{{- .Values.containerMode.kubernetesModeWorkVolumeClaim | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.non-work-volumes" -}}
|
||||
{{- range $i, $volume := .Values.template.spec.volumes }}
|
||||
{{- if ne $volume.name "work" }}
|
||||
- name: {{ $volume.name }}
|
||||
{{- range $key, $val := $volume }}
|
||||
{{- if ne $key "name" }}
|
||||
{{ $key }}: {{ $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.non-runner-containers" -}}
|
||||
{{- range $i, $container := .Values.template.spec.containers -}}
|
||||
{{- if ne $container.name "runner" -}}
|
||||
- name: {{ $container.name }}
|
||||
{{- range $key, $val := $container }}
|
||||
{{- if ne $key "name" }}
|
||||
{{ $key }}: {{ $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.dind-runner-container" -}}
|
||||
{{- range $i, $container := .Values.template.spec.containers -}}
|
||||
{{- if eq $container.name "runner" -}}
|
||||
{{- range $key, $val := $container }}
|
||||
{{- if and (ne $key "env") (ne $key "volumeMounts") (ne $key "name") }}
|
||||
{{ $key }}: {{ $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $setDockerHost := 1 }}
|
||||
{{- $setDockerTlsVerify := 1 }}
|
||||
{{- $setDockerCertPath := 1 }}
|
||||
{{- $setRunnerWaitDocker := 1 }}
|
||||
env:
|
||||
{{- with $container.env }}
|
||||
{{- range $i, $env := . }}
|
||||
{{- if eq $env.name "DOCKER_HOST" }}
|
||||
{{- $setDockerHost = 0 -}}
|
||||
{{- end }}
|
||||
{{- if eq $env.name "DOCKER_TLS_VERIFY" }}
|
||||
{{- $setDockerTlsVerify = 0 -}}
|
||||
{{- end }}
|
||||
{{- if eq $env.name "DOCKER_CERT_PATH" }}
|
||||
{{- $setDockerCertPath = 0 -}}
|
||||
{{- end }}
|
||||
{{- if eq $env.name "RUNNER_WAIT_FOR_DOCKER_IN_SECONDS" }}
|
||||
{{- $setRunnerWaitDocker = 0 -}}
|
||||
{{- end }}
|
||||
- name: {{ $env.name }}
|
||||
{{- range $envKey, $envVal := $env }}
|
||||
{{- if ne $envKey "name" }}
|
||||
{{ $envKey }}: {{ $envVal | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $setDockerHost }}
|
||||
- name: DOCKER_HOST
|
||||
value: tcp://localhost:2376
|
||||
{{- end }}
|
||||
{{- if $setDockerTlsVerify }}
|
||||
- name: DOCKER_TLS_VERIFY
|
||||
value: "1"
|
||||
{{- end }}
|
||||
{{- if $setDockerCertPath }}
|
||||
- name: DOCKER_CERT_PATH
|
||||
value: /certs/client
|
||||
{{- end }}
|
||||
{{- if $setRunnerWaitDocker }}
|
||||
- name: RUNNER_WAIT_FOR_DOCKER_IN_SECONDS
|
||||
value: "120"
|
||||
{{- end }}
|
||||
{{- $mountWork := 1 }}
|
||||
{{- $mountDindCert := 1 }}
|
||||
volumeMounts:
|
||||
{{- with $container.volumeMounts }}
|
||||
{{- range $i, $volMount := . }}
|
||||
{{- if eq $volMount.name "work" }}
|
||||
{{- $mountWork = 0 -}}
|
||||
{{- end }}
|
||||
{{- if eq $volMount.name "dind-cert" }}
|
||||
{{- $mountDindCert = 0 -}}
|
||||
{{- end }}
|
||||
- name: {{ $volMount.name }}
|
||||
{{- range $mountKey, $mountVal := $volMount }}
|
||||
{{- if ne $mountKey "name" }}
|
||||
{{ $mountKey }}: {{ $mountVal | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $mountWork }}
|
||||
- name: work
|
||||
mountPath: /actions-runner/_work
|
||||
{{- end }}
|
||||
{{- if $mountDindCert }}
|
||||
- name: dind-cert
|
||||
mountPath: /certs/client
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gha-runner-scale-set.kubernetes-mode-runner-container" -}}
|
||||
{{- range $i, $container := .Values.template.spec.containers -}}
|
||||
{{- if eq $container.name "runner" -}}
|
||||
{{- range $key, $val := $container }}
|
||||
{{- if and (ne $key "env") (ne $key "volumeMounts") (ne $key "name") }}
|
||||
{{ $key }}: {{ $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $setContainerHooks := 1 }}
|
||||
{{- $setPodName := 1 }}
|
||||
{{- $setRequireJobContainer := 1 }}
|
||||
env:
|
||||
{{- with $container.env }}
|
||||
{{- range $i, $env := . }}
|
||||
{{- if eq $env.name "ACTIONS_RUNNER_CONTAINER_HOOKS" }}
|
||||
{{- $setContainerHooks = 0 -}}
|
||||
{{- end }}
|
||||
{{- if eq $env.name "ACTIONS_RUNNER_POD_NAME" }}
|
||||
{{- $setPodName = 0 -}}
|
||||
{{- end }}
|
||||
{{- if eq $env.name "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER" }}
|
||||
{{- $setRequireJobContainer = 0 -}}
|
||||
{{- end }}
|
||||
- name: {{ $env.name }}
|
||||
{{- range $envKey, $envVal := $env }}
|
||||
{{- if ne $envKey "name" }}
|
||||
{{ $envKey }}: {{ $envVal | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $setContainerHooks }}
|
||||
- name: ACTIONS_RUNNER_CONTAINER_HOOKS
|
||||
value: /actions-runner/k8s/index.js
|
||||
{{- end }}
|
||||
{{- if $setPodName }}
|
||||
- name: ACTIONS_RUNNER_POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
{{- end }}
|
||||
{{- if $setRequireJobContainer }}
|
||||
- name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER
|
||||
value: "true"
|
||||
{{- end }}
|
||||
{{- $mountWork := 1 }}
|
||||
volumeMounts:
|
||||
{{- with $container.volumeMounts }}
|
||||
{{- range $i, $volMount := . }}
|
||||
{{- if eq $volMount.name "work" }}
|
||||
{{- $mountWork = 0 -}}
|
||||
{{- end }}
|
||||
- name: {{ $volMount.name }}
|
||||
{{- range $mountKey, $mountVal := $volMount }}
|
||||
{{- if ne $mountKey "name" }}
|
||||
{{ $mountKey }}: {{ $mountVal | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $mountWork }}
|
||||
- name: work
|
||||
mountPath: /actions-runner/_work
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
108
charts/gha-runner-scale-set/templates/autoscalingrunnerset.yaml
Normal file
108
charts/gha-runner-scale-set/templates/autoscalingrunnerset.yaml
Normal file
@@ -0,0 +1,108 @@
|
||||
apiVersion: actions.github.com/v1alpha1
|
||||
kind: AutoscalingRunnerSet
|
||||
metadata:
|
||||
name: {{ .Release.Name }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gha-runner-scale-set.labels" . | nindent 4 }}
|
||||
spec:
|
||||
githubConfigUrl: {{ required ".Values.githubConfigUrl is required" .Values.githubConfigUrl }}
|
||||
githubConfigSecret: {{ include "gha-runner-scale-set.githubsecret" . }}
|
||||
{{- with .Values.runnerGroup }}
|
||||
runnerGroup: {{ . }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.proxy }}
|
||||
proxy:
|
||||
{{- if .Values.proxy.http }}
|
||||
http:
|
||||
url: {{ .Values.proxy.http.url }}
|
||||
credentialSecretRef: {{ .Values.proxy.http.credentialSecretRef }}
|
||||
{{ end }}
|
||||
{{- if .Values.proxy.https }}
|
||||
https:
|
||||
url: {{ .Values.proxy.https.url }}
|
||||
credentialSecretRef: {{ .Values.proxy.https.credentialSecretRef }}
|
||||
{{ 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.minRunners) (kindIs "float64" .Values.minRunners)) (or (kindIs "int64" .Values.maxRunners) (kindIs "float64" .Values.maxRunners)) }}
|
||||
{{- if gt .Values.minRunners .Values.maxRunners }}
|
||||
{{- fail "maxRunners has to be greater or equal to minRunners" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if or (kindIs "int64" .Values.maxRunners) (kindIs "float64" .Values.maxRunners) }}
|
||||
{{- if lt (.Values.maxRunners | int) 0 }}
|
||||
{{- fail "maxRunners has to be greater or equal to 0" }}
|
||||
{{- end }}
|
||||
maxRunners: {{ .Values.maxRunners | int }}
|
||||
{{- end }}
|
||||
|
||||
{{- if or (kindIs "int64" .Values.minRunners) (kindIs "float64" .Values.minRunners) }}
|
||||
{{- if lt (.Values.minRunners | int) 0 }}
|
||||
{{- fail "minRunners has to be greater or equal to 0" }}
|
||||
{{- end }}
|
||||
minRunners: {{ .Values.minRunners | int }}
|
||||
{{- end }}
|
||||
|
||||
template:
|
||||
{{- with .Values.template.metadata }}
|
||||
metadata:
|
||||
{{- with .labels }}
|
||||
labels:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- range $key, $val := .Values.template.spec }}
|
||||
{{- if and (ne $key "containers") (ne $key "volumes") (ne $key "initContainers") (ne $key "serviceAccountName") }}
|
||||
{{ $key }}: {{ $val | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.containerMode.type "kubernetes" }}
|
||||
serviceAccountName: {{ default (include "gha-runner-scale-set.kubeModeServiceAccountName" .) .Values.template.spec.serviceAccountName }}
|
||||
{{- else }}
|
||||
serviceAccountName: {{ default (include "gha-runner-scale-set.noPermissionServiceAccountName" .) .Values.template.spec.serviceAccountName }}
|
||||
{{- end }}
|
||||
{{- if or .Values.template.spec.initContainers (eq .Values.containerMode.type "dind") }}
|
||||
initContainers:
|
||||
{{- if eq .Values.containerMode.type "dind" }}
|
||||
- name: init-dind-externals
|
||||
{{- include "gha-runner-scale-set.dind-init-container" . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.template.spec.initContainers }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- if eq .Values.containerMode.type "dind" }}
|
||||
- name: runner
|
||||
{{- include "gha-runner-scale-set.dind-runner-container" . | nindent 8 }}
|
||||
- name: dind
|
||||
{{- include "gha-runner-scale-set.dind-container" . | nindent 8 }}
|
||||
{{- include "gha-runner-scale-set.non-runner-containers" . | nindent 6 }}
|
||||
{{- else if eq .Values.containerMode.type "kubernetes" }}
|
||||
- name: runner
|
||||
{{- include "gha-runner-scale-set.kubernetes-mode-runner-container" . | nindent 8 }}
|
||||
{{- include "gha-runner-scale-set.non-runner-containers" . | nindent 6 }}
|
||||
{{- else }}
|
||||
{{ .Values.template.spec.containers | toYaml | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- if or .Values.template.spec.volumes (eq .Values.containerMode.type "dind") (eq .Values.containerMode.type "kubernetes") }}
|
||||
volumes:
|
||||
{{- if eq .Values.containerMode.type "dind" }}
|
||||
{{- include "gha-runner-scale-set.dind-volume" . | nindent 6 }}
|
||||
{{- include "gha-runner-scale-set.dind-work-volume" . | nindent 6 }}
|
||||
{{- else if eq .Values.containerMode.type "kubernetes" }}
|
||||
{{- include "gha-runner-scale-set.kubernetes-mode-work-volume" . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- include "gha-runner-scale-set.non-work-volumes" . | nindent 6 }}
|
||||
{{- end }}
|
||||
39
charts/gha-runner-scale-set/templates/githubsecret.yaml
Normal file
39
charts/gha-runner-scale-set/templates/githubsecret.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
{{- if not (kindIs "string" .Values.githubConfigSecret) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "gha-runner-scale-set.githubsecret" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gha-runner-scale-set.labels" . | nindent 4 }}
|
||||
finalizers:
|
||||
- actions.github.com/secret-protection
|
||||
data:
|
||||
{{- $hasToken := false }}
|
||||
{{- $hasAppId := false }}
|
||||
{{- $hasInstallationId := false }}
|
||||
{{- $hasPrivateKey := false }}
|
||||
{{- range $secretName, $secretValue := (required "Values.githubConfigSecret is required for setting auth with GitHub server." .Values.githubConfigSecret) }}
|
||||
{{- if $secretValue }}
|
||||
{{ $secretName }}: {{ $secretValue | toString | b64enc }}
|
||||
{{- if eq $secretName "github_token" }}
|
||||
{{- $hasToken = true }}
|
||||
{{- end }}
|
||||
{{- if eq $secretName "github_app_id" }}
|
||||
{{- $hasAppId = true }}
|
||||
{{- end }}
|
||||
{{- if eq $secretName "github_app_installation_id" }}
|
||||
{{- $hasInstallationId = true }}
|
||||
{{- end }}
|
||||
{{- if eq $secretName "github_app_private_key" }}
|
||||
{{- $hasPrivateKey = true }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and (not $hasToken) (not ($hasAppId)) }}
|
||||
{{- fail "A valid .Values.githubConfigSecret is required for setting auth with GitHub server, provide .Values.githubConfigSecret.github_token or .Values.githubConfigSecret.github_app_id." }}
|
||||
{{- end }}
|
||||
{{- if and $hasAppId (or (not $hasInstallationId) (not $hasPrivateKey)) }}
|
||||
{{- fail "A valid .Values.githubConfigSecret is required for setting auth with GitHub server, provide .Values.githubConfigSecret.github_app_installation_id and .Values.githubConfigSecret.github_app_private_key." }}
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
24
charts/gha-runner-scale-set/templates/kube_mode_role.yaml
Normal file
24
charts/gha-runner-scale-set/templates/kube_mode_role.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
{{- if and (eq .Values.containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }}
|
||||
# default permission for runner pod service account in kubernetes mode (container hook)
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "gha-runner-scale-set.kubeModeRoleName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "create", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/exec"]
|
||||
verbs: ["get", "create"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/log"]
|
||||
verbs: ["get", "list", "watch",]
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["get", "list", "create", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "list", "create", "delete"]
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- if and (eq .Values.containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "gha-runner-scale-set.kubeModeRoleName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "gha-runner-scale-set.kubeModeRoleName" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "gha-runner-scale-set.kubeModeServiceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,9 @@
|
||||
{{- if and (eq .Values.containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "gha-runner-scale-set.kubeModeServiceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gha-runner-scale-set.labels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,9 @@
|
||||
{{- if and (ne .Values.containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "gha-runner-scale-set.noPermissionServiceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gha-runner-scale-set.labels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
782
charts/gha-runner-scale-set/tests/template_test.go
Normal file
782
charts/gha-runner-scale-set/tests/template_test.go
Normal file
@@ -0,0 +1,782 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1alpha1 "github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1"
|
||||
"github.com/gruntwork-io/terratest/modules/helm"
|
||||
"github.com/gruntwork-io/terratest/modules/k8s"
|
||||
"github.com/gruntwork-io/terratest/modules/random"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
)
|
||||
|
||||
func TestTemplateRenderedGitHubSecretWithGitHubToken(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
||||
|
||||
var githubSecret corev1.Secret
|
||||
helm.UnmarshalK8SYaml(t, output, &githubSecret)
|
||||
|
||||
assert.Equal(t, namespaceName, githubSecret.Namespace)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-github-secret", githubSecret.Name)
|
||||
assert.Equal(t, "gh_token12345", string(githubSecret.Data["github_token"]))
|
||||
assert.Equal(t, "actions.github.com/secret-protection", githubSecret.Finalizers[0])
|
||||
}
|
||||
|
||||
func TestTemplateRenderedGitHubSecretWithGitHubApp(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_app_id": "10",
|
||||
"githubConfigSecret.github_app_installation_id": "100",
|
||||
"githubConfigSecret.github_app_private_key": "private_key",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
||||
|
||||
var githubSecret corev1.Secret
|
||||
helm.UnmarshalK8SYaml(t, output, &githubSecret)
|
||||
|
||||
assert.Equal(t, namespaceName, githubSecret.Namespace)
|
||||
assert.Equal(t, "10", string(githubSecret.Data["github_app_id"]))
|
||||
assert.Equal(t, "100", string(githubSecret.Data["github_app_installation_id"]))
|
||||
assert.Equal(t, "private_key", string(githubSecret.Data["github_app_private_key"]))
|
||||
}
|
||||
|
||||
func TestTemplateRenderedGitHubSecretErrorWithMissingAuthInput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_app_id": "",
|
||||
"githubConfigSecret.github_token": "",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.ErrorContains(t, err, "provide .Values.githubConfigSecret.github_token or .Values.githubConfigSecret.github_app_id")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedGitHubSecretErrorWithMissingAppInput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_app_id": "10",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.ErrorContains(t, err, "provide .Values.githubConfigSecret.github_app_installation_id and .Values.githubConfigSecret.github_app_private_key")
|
||||
}
|
||||
|
||||
func TestTemplateNotRenderedGitHubSecretWithPredefinedSecret(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret": "pre-defined-secret",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
||||
assert.ErrorContains(t, err, "could not find template templates/githubsecret.yaml in chart", "secret should not be rendered since a pre-defined secret is provided")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedSetServiceAccountToNoPermission(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/no_permission_serviceaccount.yaml"})
|
||||
var serviceAccount corev1.ServiceAccount
|
||||
helm.UnmarshalK8SYaml(t, output, &serviceAccount)
|
||||
|
||||
assert.Equal(t, namespaceName, serviceAccount.Namespace)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-no-permission-service-account", serviceAccount.Name)
|
||||
|
||||
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-no-permission-service-account", ars.Spec.Template.Spec.ServiceAccountName)
|
||||
}
|
||||
|
||||
func TestTemplateRenderedSetServiceAccountToKubeMode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"containerMode.type": "kubernetes",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_serviceaccount.yaml"})
|
||||
var serviceAccount corev1.ServiceAccount
|
||||
helm.UnmarshalK8SYaml(t, output, &serviceAccount)
|
||||
|
||||
assert.Equal(t, namespaceName, serviceAccount.Namespace)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-kube-mode-service-account", serviceAccount.Name)
|
||||
|
||||
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role.yaml"})
|
||||
var role rbacv1.Role
|
||||
helm.UnmarshalK8SYaml(t, output, &role)
|
||||
|
||||
assert.Equal(t, namespaceName, role.Namespace)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-kube-mode-role", role.Name)
|
||||
assert.Len(t, role.Rules, 5, "kube mode role should have 5 rules")
|
||||
assert.Equal(t, "pods", role.Rules[0].Resources[0])
|
||||
assert.Equal(t, "pods/exec", role.Rules[1].Resources[0])
|
||||
assert.Equal(t, "pods/log", role.Rules[2].Resources[0])
|
||||
assert.Equal(t, "jobs", role.Rules[3].Resources[0])
|
||||
assert.Equal(t, "secrets", role.Rules[4].Resources[0])
|
||||
|
||||
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role_binding.yaml"})
|
||||
var roleBinding rbacv1.RoleBinding
|
||||
helm.UnmarshalK8SYaml(t, output, &roleBinding)
|
||||
|
||||
assert.Equal(t, namespaceName, roleBinding.Namespace)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-kube-mode-role", roleBinding.Name)
|
||||
assert.Len(t, roleBinding.Subjects, 1)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-kube-mode-service-account", roleBinding.Subjects[0].Name)
|
||||
assert.Equal(t, namespaceName, roleBinding.Subjects[0].Namespace)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-kube-mode-role", roleBinding.RoleRef.Name)
|
||||
assert.Equal(t, "Role", roleBinding.RoleRef.Kind)
|
||||
|
||||
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-kube-mode-service-account", ars.Spec.Template.Spec.ServiceAccountName)
|
||||
}
|
||||
|
||||
func TestTemplateRenderedUserProvideSetServiceAccount(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"template.spec.serviceAccountName": "test-service-account",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/no_permission_serviceaccount.yaml"})
|
||||
assert.ErrorContains(t, err, "could not find template templates/no_permission_serviceaccount.yaml in chart", "no permission service account should not be rendered")
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, "test-service-account", ars.Spec.Template.Spec.ServiceAccountName)
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, namespaceName, ars.Namespace)
|
||||
assert.Equal(t, "test-runners", ars.Name)
|
||||
|
||||
assert.Equal(t, "gha-runner-scale-set", ars.Labels["app.kubernetes.io/name"])
|
||||
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
||||
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-github-secret", ars.Spec.GitHubConfigSecret)
|
||||
|
||||
assert.Empty(t, ars.Spec.RunnerGroup, "RunnerGroup should be empty")
|
||||
|
||||
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
||||
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
||||
assert.Nil(t, ars.Spec.Proxy, "Proxy should be nil")
|
||||
assert.Nil(t, ars.Spec.GitHubServerTLS, "GitHubServerTLS should be nil")
|
||||
|
||||
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
||||
|
||||
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "Template.Spec should have 1 container")
|
||||
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
||||
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_ProvideMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"template.metadata.labels.test1": "test1",
|
||||
"template.metadata.labels.test2": "test2",
|
||||
"template.metadata.annotations.test3": "test3",
|
||||
"template.metadata.annotations.test4": "test4",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, namespaceName, ars.Namespace)
|
||||
assert.Equal(t, "test-runners", ars.Name)
|
||||
|
||||
assert.NotNil(t, ars.Spec.Template.Labels, "Template.Spec.Labels should not be nil")
|
||||
assert.Equal(t, "test1", ars.Spec.Template.Labels["test1"], "Template.Spec.Labels should have test1")
|
||||
assert.Equal(t, "test2", ars.Spec.Template.Labels["test2"], "Template.Spec.Labels should have test2")
|
||||
|
||||
assert.NotNil(t, ars.Spec.Template.Annotations, "Template.Spec.Annotations should not be nil")
|
||||
assert.Equal(t, "test3", ars.Spec.Template.Annotations["test3"], "Template.Spec.Annotations should have test3")
|
||||
assert.Equal(t, "test4", ars.Spec.Template.Annotations["test4"], "Template.Spec.Annotations should have test4")
|
||||
|
||||
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
||||
|
||||
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "Template.Spec should have 1 container")
|
||||
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
||||
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_MaxRunnersValidationError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"maxRunners": "-1",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.ErrorContains(t, err, "maxRunners has to be greater or equal to 0")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_MinRunnersValidationError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"maxRunners": "1",
|
||||
"minRunners": "-1",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.ErrorContains(t, err, "minRunners has to be greater or equal to 0")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidationError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"maxRunners": "0",
|
||||
"minRunners": "1",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.ErrorContains(t, err, "maxRunners has to be greater or equal to minRunners")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidationSameValue(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"maxRunners": "0",
|
||||
"minRunners": "0",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, 0, *ars.Spec.MinRunners, "MinRunners should be 0")
|
||||
assert.Equal(t, 0, *ars.Spec.MaxRunners, "MaxRunners should be 0")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidation_OnlyMin(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"minRunners": "5",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, 5, *ars.Spec.MinRunners, "MinRunners should be 5")
|
||||
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidation_OnlyMax(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"maxRunners": "5",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, 5, *ars.Spec.MaxRunners, "MaxRunners should be 5")
|
||||
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunners_FromValuesFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
testValuesPath, err := filepath.Abs("../tests/values.yaml")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
ValuesFiles: []string{testValuesPath},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, 5, *ars.Spec.MinRunners, "MinRunners should be 5")
|
||||
assert.Equal(t, 10, *ars.Spec.MaxRunners, "MaxRunners should be 10")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_EnableDinD(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"containerMode.type": "dind",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, namespaceName, ars.Namespace)
|
||||
assert.Equal(t, "test-runners", ars.Name)
|
||||
|
||||
assert.Equal(t, "gha-runner-scale-set", ars.Labels["app.kubernetes.io/name"])
|
||||
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
||||
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-github-secret", ars.Spec.GitHubConfigSecret)
|
||||
|
||||
assert.Empty(t, ars.Spec.RunnerGroup, "RunnerGroup should be empty")
|
||||
|
||||
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
||||
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
||||
assert.Nil(t, ars.Spec.Proxy, "Proxy should be nil")
|
||||
assert.Nil(t, ars.Spec.GitHubServerTLS, "GitHubServerTLS should be nil")
|
||||
|
||||
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
||||
|
||||
assert.Len(t, ars.Spec.Template.Spec.InitContainers, 1, "Template.Spec should have 1 init container")
|
||||
assert.Equal(t, "init-dind-externals", ars.Spec.Template.Spec.InitContainers[0].Name)
|
||||
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.InitContainers[0].Image)
|
||||
assert.Equal(t, "cp", ars.Spec.Template.Spec.InitContainers[0].Command[0])
|
||||
assert.Equal(t, "-r -v /actions-runner/externals/. /actions-runner/tmpDir/", strings.Join(ars.Spec.Template.Spec.InitContainers[0].Args, " "))
|
||||
|
||||
assert.Len(t, ars.Spec.Template.Spec.Containers, 2, "Template.Spec should have 2 container")
|
||||
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
||||
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
||||
assert.Len(t, ars.Spec.Template.Spec.Containers[0].Env, 4, "The runner container should have 4 env vars, DOCKER_HOST, DOCKER_TLS_VERIFY, DOCKER_CERT_PATH and RUNNER_WAIT_FOR_DOCKER_IN_SECONDS")
|
||||
assert.Equal(t, "DOCKER_HOST", ars.Spec.Template.Spec.Containers[0].Env[0].Name)
|
||||
assert.Equal(t, "tcp://localhost:2376", ars.Spec.Template.Spec.Containers[0].Env[0].Value)
|
||||
assert.Equal(t, "DOCKER_TLS_VERIFY", ars.Spec.Template.Spec.Containers[0].Env[1].Name)
|
||||
assert.Equal(t, "1", ars.Spec.Template.Spec.Containers[0].Env[1].Value)
|
||||
assert.Equal(t, "DOCKER_CERT_PATH", ars.Spec.Template.Spec.Containers[0].Env[2].Name)
|
||||
assert.Equal(t, "/certs/client", ars.Spec.Template.Spec.Containers[0].Env[2].Value)
|
||||
assert.Equal(t, "RUNNER_WAIT_FOR_DOCKER_IN_SECONDS", ars.Spec.Template.Spec.Containers[0].Env[3].Name)
|
||||
assert.Equal(t, "120", ars.Spec.Template.Spec.Containers[0].Env[3].Value)
|
||||
|
||||
assert.Len(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, 2, "The runner container should have 2 volume mounts, dind-cert and work")
|
||||
assert.Equal(t, "work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name)
|
||||
assert.Equal(t, "/actions-runner/_work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath)
|
||||
assert.False(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].ReadOnly)
|
||||
|
||||
assert.Equal(t, "dind-cert", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].Name)
|
||||
assert.Equal(t, "/certs/client", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath)
|
||||
assert.True(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].ReadOnly)
|
||||
|
||||
assert.Equal(t, "dind", ars.Spec.Template.Spec.Containers[1].Name)
|
||||
assert.Equal(t, "docker:dind", ars.Spec.Template.Spec.Containers[1].Image)
|
||||
assert.True(t, *ars.Spec.Template.Spec.Containers[1].SecurityContext.Privileged)
|
||||
assert.Len(t, ars.Spec.Template.Spec.Containers[1].VolumeMounts, 3, "The dind container should have 3 volume mounts, dind-cert, work and externals")
|
||||
assert.Equal(t, "work", ars.Spec.Template.Spec.Containers[1].VolumeMounts[0].Name)
|
||||
assert.Equal(t, "/actions-runner/_work", ars.Spec.Template.Spec.Containers[1].VolumeMounts[0].MountPath)
|
||||
|
||||
assert.Equal(t, "dind-cert", ars.Spec.Template.Spec.Containers[1].VolumeMounts[1].Name)
|
||||
assert.Equal(t, "/certs/client", ars.Spec.Template.Spec.Containers[1].VolumeMounts[1].MountPath)
|
||||
|
||||
assert.Equal(t, "dind-externals", ars.Spec.Template.Spec.Containers[1].VolumeMounts[2].Name)
|
||||
assert.Equal(t, "/actions-runner/externals", ars.Spec.Template.Spec.Containers[1].VolumeMounts[2].MountPath)
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_EnableKubernetesMode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret.github_token": "gh_token12345",
|
||||
"containerMode.type": "kubernetes",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, namespaceName, ars.Namespace)
|
||||
assert.Equal(t, "test-runners", ars.Name)
|
||||
|
||||
assert.Equal(t, "gha-runner-scale-set", ars.Labels["app.kubernetes.io/name"])
|
||||
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
||||
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
||||
assert.Equal(t, "test-runners-gha-runner-scale-set-github-secret", ars.Spec.GitHubConfigSecret)
|
||||
|
||||
assert.Empty(t, ars.Spec.RunnerGroup, "RunnerGroup should be empty")
|
||||
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
||||
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
||||
assert.Nil(t, ars.Spec.Proxy, "Proxy should be nil")
|
||||
assert.Nil(t, ars.Spec.GitHubServerTLS, "GitHubServerTLS should be nil")
|
||||
|
||||
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
||||
|
||||
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "Template.Spec should have 1 container")
|
||||
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
||||
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
||||
|
||||
assert.Equal(t, "ACTIONS_RUNNER_CONTAINER_HOOKS", ars.Spec.Template.Spec.Containers[0].Env[0].Name)
|
||||
assert.Equal(t, "/actions-runner/k8s/index.js", ars.Spec.Template.Spec.Containers[0].Env[0].Value)
|
||||
assert.Equal(t, "ACTIONS_RUNNER_POD_NAME", ars.Spec.Template.Spec.Containers[0].Env[1].Name)
|
||||
assert.Equal(t, "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER", ars.Spec.Template.Spec.Containers[0].Env[2].Name)
|
||||
assert.Equal(t, "true", ars.Spec.Template.Spec.Containers[0].Env[2].Value)
|
||||
|
||||
assert.Len(t, ars.Spec.Template.Spec.Volumes, 1, "Template.Spec should have 1 volume")
|
||||
assert.Equal(t, "work", ars.Spec.Template.Spec.Volumes[0].Name)
|
||||
assert.NotNil(t, ars.Spec.Template.Spec.Volumes[0].Ephemeral, "Template.Spec should have 1 ephemeral volume")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_UsePredefinedSecret(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret": "pre-defined-secrets",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
assert.Equal(t, namespaceName, ars.Namespace)
|
||||
assert.Equal(t, "test-runners", ars.Name)
|
||||
|
||||
assert.Equal(t, "gha-runner-scale-set", ars.Labels["app.kubernetes.io/name"])
|
||||
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
||||
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
||||
assert.Equal(t, "pre-defined-secrets", ars.Spec.GitHubConfigSecret)
|
||||
}
|
||||
|
||||
func TestTemplateRenderedAutoScalingRunnerSet_ErrorOnEmptyPredefinedSecret(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret": "",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.ErrorContains(t, err, "Values.githubConfigSecret is required for setting auth with GitHub server")
|
||||
}
|
||||
|
||||
func TestTemplateRenderedWithProxy(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Path to the helm chart we will test
|
||||
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
||||
require.NoError(t, err)
|
||||
|
||||
releaseName := "test-runners"
|
||||
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
||||
|
||||
options := &helm.Options{
|
||||
SetValues: map[string]string{
|
||||
"githubConfigUrl": "https://github.com/actions",
|
||||
"githubConfigSecret": "pre-defined-secrets",
|
||||
"proxy.http.url": "http://proxy.example.com",
|
||||
"proxy.http.credentialSecretRef": "http-secret",
|
||||
"proxy.https.url": "https://proxy.example.com",
|
||||
"proxy.https.credentialSecretRef": "https-secret",
|
||||
"proxy.noProxy": "{example.com,example.org}",
|
||||
},
|
||||
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
||||
}
|
||||
|
||||
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
||||
|
||||
var ars v1alpha1.AutoscalingRunnerSet
|
||||
helm.UnmarshalK8SYaml(t, output, &ars)
|
||||
|
||||
require.NotNil(t, ars.Spec.Proxy)
|
||||
require.NotNil(t, ars.Spec.Proxy.HTTP)
|
||||
assert.Equal(t, "http://proxy.example.com", ars.Spec.Proxy.HTTP.Url)
|
||||
assert.Equal(t, "http-secret", ars.Spec.Proxy.HTTP.CredentialSecretRef)
|
||||
|
||||
require.NotNil(t, ars.Spec.Proxy.HTTPS)
|
||||
assert.Equal(t, "https://proxy.example.com", ars.Spec.Proxy.HTTPS.Url)
|
||||
assert.Equal(t, "https-secret", ars.Spec.Proxy.HTTPS.CredentialSecretRef)
|
||||
|
||||
require.NotNil(t, ars.Spec.Proxy.NoProxy)
|
||||
require.Len(t, ars.Spec.Proxy.NoProxy, 2)
|
||||
assert.Contains(t, ars.Spec.Proxy.NoProxy, "example.com")
|
||||
assert.Contains(t, ars.Spec.Proxy.NoProxy, "example.org")
|
||||
}
|
||||
5
charts/gha-runner-scale-set/tests/values.yaml
Normal file
5
charts/gha-runner-scale-set/tests/values.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
githubConfigUrl: https://github.com/actions/actions-runner-controller
|
||||
githubConfigSecret:
|
||||
github_token: test
|
||||
maxRunners: 10
|
||||
minRunners: 5
|
||||
139
charts/gha-runner-scale-set/values.yaml
Normal file
139
charts/gha-runner-scale-set/values.yaml
Normal file
@@ -0,0 +1,139 @@
|
||||
## githubConfigUrl is the GitHub url for where you want to configure runners
|
||||
## ex: https://github.com/myorg/myrepo or https://github.com/myorg
|
||||
githubConfigUrl: ""
|
||||
|
||||
## githubConfigSecret is the k8s secrets to use when auth with GitHub API.
|
||||
## You can choose to use GitHub App or a PAT token
|
||||
githubConfigSecret:
|
||||
### GitHub Apps Configuration
|
||||
## NOTE: IDs MUST be strings, use quotes
|
||||
#github_app_id: ""
|
||||
#github_app_installation_id: ""
|
||||
#github_app_private_key: |
|
||||
|
||||
### GitHub PAT Configuration
|
||||
github_token: ""
|
||||
## If you have a pre-define Kubernetes secret in the same namespace the gha-runner-scale-set is going to deploy,
|
||||
## you can also reference it via `githubConfigSecret: pre-defined-secret`.
|
||||
## You need to make sure your predefined secret has all the required secret data set properly.
|
||||
## For a pre-defined secret using GitHub PAT, the secret needs to be created like this:
|
||||
## > kubectl create secret generic pre-defined-secret --namespace=my_namespace --from-literal=github_token='ghp_your_pat'
|
||||
## For a pre-defined secret using GitHub App, the secret needs to be created like this:
|
||||
## > kubectl create secret generic pre-defined-secret --namespace=my_namespace --from-literal=github_app_id=123456 --from-literal=github_app_installation_id=654321 --from-literal=github_app_private_key='-----BEGIN CERTIFICATE-----*******'
|
||||
# githubConfigSecret: pre-defined-secret
|
||||
|
||||
## proxy can be used to define proxy settings that will be used by the
|
||||
## controller, the listener and the runner of this scale set.
|
||||
#
|
||||
# proxy:
|
||||
# http:
|
||||
# url: http://proxy.com:1234
|
||||
# credentialSecretRef: proxy-auth # a secret with `username` and `password` keys
|
||||
# https:
|
||||
# url: http://proxy.com:1234
|
||||
# credentialSecretRef: proxy-auth # a secret with `username` and `password` keys
|
||||
# noProxy:
|
||||
# - example.com
|
||||
# - example.org
|
||||
|
||||
## maxRunners is the max number of runners the auto scaling runner set will scale up to.
|
||||
# maxRunners: 5
|
||||
|
||||
## minRunners is the min number of runners the auto scaling runner set will scale down to.
|
||||
# minRunners: 0
|
||||
|
||||
# runnerGroup: "default"
|
||||
|
||||
## template is the PodSpec for each runner Pod
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: runner
|
||||
image: ghcr.io/actions/actions-runner:latest
|
||||
command: ["/actions-runner/run.sh"]
|
||||
|
||||
containerMode:
|
||||
type: "" ## type can be set to dind or kubernetes
|
||||
## with containerMode.type=dind, we will populate the template.spec with following pod spec
|
||||
## template:
|
||||
## spec:
|
||||
## initContainers:
|
||||
## - name: initExternalsInternalVolume
|
||||
## image: ghcr.io/actions/actions-runner:latest
|
||||
## command: ["cp", "-r", "-v", "/actions-runner/externals/.", "/actions-runner/tmpDir/"]
|
||||
## volumeMounts:
|
||||
## - name: externalsInternal
|
||||
## mountPath: /actions-runner/tmpDir
|
||||
## containers:
|
||||
## - name: runner
|
||||
## image: ghcr.io/actions/actions-runner:latest
|
||||
## env:
|
||||
## - name: DOCKER_HOST
|
||||
## value: tcp://localhost:2376
|
||||
## - name: DOCKER_TLS_VERIFY
|
||||
## value: "1"
|
||||
## - name: DOCKER_CERT_PATH
|
||||
## value: /certs/client
|
||||
## volumeMounts:
|
||||
## - name: workingDirectoryInternal
|
||||
## mountPath: /actions-runner/_work
|
||||
## - name: dinDInternal
|
||||
## mountPath: /certs/client
|
||||
## readOnly: true
|
||||
## - name: dind
|
||||
## image: docker:dind
|
||||
## securityContext:
|
||||
## privileged: true
|
||||
## volumeMounts:
|
||||
## - mountPath: /certs/client
|
||||
## name: dinDInternal
|
||||
## - mountPath: /actions-runner/_work
|
||||
## name: workingDirectoryInternal
|
||||
## - mountPath: /actions-runner/externals
|
||||
## name: externalsInternal
|
||||
## volumes:
|
||||
## - name: dinDInternal
|
||||
## emptyDir: {}
|
||||
## - name: workingDirectoryInternal
|
||||
## emptyDir: {}
|
||||
## - name: externalsInternal
|
||||
## emptyDir: {}
|
||||
######################################################################################################
|
||||
## with containerMode.type=kubernetes, we will populate the template.spec with following pod spec
|
||||
## template:
|
||||
## spec:
|
||||
## containers:
|
||||
## - name: runner
|
||||
## image: ghcr.io/actions/actions-runner:latest
|
||||
## env:
|
||||
## - name: ACTIONS_RUNNER_CONTAINER_HOOKS
|
||||
## value: /actions-runner/k8s/index.js
|
||||
## - name: ACTIONS_RUNNER_POD_NAME
|
||||
## valueFrom:
|
||||
## fieldRef:
|
||||
## fieldPath: metadata.name
|
||||
## - name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER
|
||||
## value: "true"
|
||||
## volumeMounts:
|
||||
## - name: work
|
||||
## mountPath: /actions-runner/_work
|
||||
## volumes:
|
||||
## - name: work
|
||||
## ephemeral:
|
||||
## volumeClaimTemplate:
|
||||
## spec:
|
||||
## accessModes: [ "ReadWriteOnce" ]
|
||||
## storageClassName: "local-path"
|
||||
## resources:
|
||||
## requests:
|
||||
## storage: 1Gi
|
||||
|
||||
## the following is required when containerMode.type=kubernetes
|
||||
kubernetesModeWorkVolumeClaim:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
# For testing, use https://github.com/rancher/local-path-provisioner to provide dynamic provision volume
|
||||
# TODO: remove before release
|
||||
storageClassName: "dynamic-blob-storage"
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
Reference in New Issue
Block a user