Merge branch 'master' into nikola-jokic/bump-dependencies
This commit is contained in:
		
						commit
						00088e4433
					
				|  | @ -377,6 +377,101 @@ volumeMounts: | |||
| {{- end }} | ||||
| {{- end }} | ||||
| 
 | ||||
| {{- define "gha-runner-scale-set.kubernetes-novolume-mode-runner-container" -}} | ||||
| {{- $tlsConfig := (default (dict) .Values.githubServerTLS) }} | ||||
| {{- range $i, $container := .Values.template.spec.containers }} | ||||
|   {{- if eq $container.name "runner" }} | ||||
|     {{- $setRunnerImage := "" }} | ||||
|     {{- range $key, $val := $container }} | ||||
|       {{- if and (ne $key "env") (ne $key "volumeMounts") (ne $key "name") }} | ||||
|       {{- if eq $key "image" }} | ||||
|         {{- $setRunnerImage = $val }} | ||||
|       {{- end }} | ||||
| {{ $key }}: {{ $val | toYaml | nindent 2 }} | ||||
|       {{- end }} | ||||
|     {{- end }} | ||||
|     {{- $setContainerHooks := 1 }} | ||||
|     {{- $setPodName := 1 }} | ||||
|     {{- $setRequireJobContainer := 1 }} | ||||
|     {{- $setActionsRunnerImage := 1 }} | ||||
|     {{- $setNodeExtraCaCerts := 0 }} | ||||
|     {{- $setRunnerUpdateCaCerts := 0 }} | ||||
|     {{- if $tlsConfig.runnerMountPath }} | ||||
|       {{- $setNodeExtraCaCerts = 1 }} | ||||
|       {{- $setRunnerUpdateCaCerts = 1 }} | ||||
|     {{- end }} | ||||
| env: | ||||
|     {{- with $container.env }} | ||||
|       {{- range $i, $env := . }} | ||||
|         {{- if eq $env.name "ACTIONS_RUNNER_CONTAINER_HOOKS" }} | ||||
|           {{- $setContainerHooks = 0 }} | ||||
|         {{- end }} | ||||
|         {{- if eq $env.name "ACTIONS_RUNNER_IMAGE" }} | ||||
|           {{- $setActionsRunnerImage = 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 }} | ||||
|         {{- if eq $env.name "NODE_EXTRA_CA_CERTS" }} | ||||
|           {{- $setNodeExtraCaCerts = 0 }} | ||||
|         {{- end }} | ||||
|         {{- if eq $env.name "RUNNER_UPDATE_CA_CERTS" }} | ||||
|           {{- $setRunnerUpdateCaCerts = 0 }} | ||||
|         {{- end }} | ||||
|   - {{ $env | toYaml | nindent 4 }} | ||||
|       {{- end }} | ||||
|     {{- end }} | ||||
|     {{- if $setContainerHooks }} | ||||
|   - name: ACTIONS_RUNNER_CONTAINER_HOOKS | ||||
|     value: /home/runner/k8s-novolume/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 }} | ||||
|     {{- if $setActionsRunnerImage }} | ||||
|   - name: ACTIONS_RUNNER_IMAGE | ||||
|     value: "{{- $setRunnerImage -}}" | ||||
|     {{- end }} | ||||
|     {{- if $setNodeExtraCaCerts }} | ||||
|   - name: NODE_EXTRA_CA_CERTS | ||||
|     value: {{ clean (print $tlsConfig.runnerMountPath "/" $tlsConfig.certificateFrom.configMapKeyRef.key) }} | ||||
|     {{- end }} | ||||
|     {{- if $setRunnerUpdateCaCerts }} | ||||
|   - name: RUNNER_UPDATE_CA_CERTS | ||||
|     value: "1" | ||||
|     {{- end }} | ||||
|     {{- $mountGitHubServerTLS := 0 }} | ||||
|     {{- if $tlsConfig.runnerMountPath }} | ||||
|       {{- $mountGitHubServerTLS = 1 }} | ||||
|     {{- end }} | ||||
| volumeMounts: | ||||
|     {{- with $container.volumeMounts }} | ||||
|       {{- range $i, $volMount := . }} | ||||
|         {{- if eq $volMount.name "github-server-tls-cert" }} | ||||
|           {{- $mountGitHubServerTLS = 0 }} | ||||
|         {{- end }} | ||||
|   - {{ $volMount | toYaml | nindent 4 }} | ||||
|       {{- end }} | ||||
|     {{- end }} | ||||
|     {{- if $mountGitHubServerTLS }} | ||||
|   - name: github-server-tls-cert | ||||
|     mountPath: {{ clean (print $tlsConfig.runnerMountPath "/" $tlsConfig.certificateFrom.configMapKeyRef.key) }} | ||||
|     subPath: {{ $tlsConfig.certificateFrom.configMapKeyRef.key }} | ||||
|     {{- end }} | ||||
|   {{- end }} | ||||
| {{- end }} | ||||
| {{- end }} | ||||
| 
 | ||||
| {{- define "gha-runner-scale-set.default-mode-runner-containers" -}} | ||||
| {{- $tlsConfig := (default (dict) .Values.githubServerTLS) }} | ||||
| {{- range $i, $container := .Values.template.spec.containers }} | ||||
|  |  | |||
|  | @ -56,12 +56,12 @@ metadata: | |||
|     {{- end }} | ||||
|     actions.github.com/cleanup-manager-role-binding: {{ include "gha-runner-scale-set.managerRoleBindingName" . }} | ||||
|     actions.github.com/cleanup-manager-role-name: {{ include "gha-runner-scale-set.managerRoleName" . }} | ||||
|     {{- if and $containerMode (eq $containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }} | ||||
|     {{- if and (or (eq $containerMode.type "kubernetes") (eq $containerMode.type "kubernetes-novolume")) (not .Values.template.spec.serviceAccountName) }} | ||||
|     actions.github.com/cleanup-kubernetes-mode-role-binding-name: {{ include "gha-runner-scale-set.kubeModeRoleBindingName" . }} | ||||
|     actions.github.com/cleanup-kubernetes-mode-role-name: {{ include "gha-runner-scale-set.kubeModeRoleName" . }} | ||||
|     actions.github.com/cleanup-kubernetes-mode-service-account-name: {{ include "gha-runner-scale-set.kubeModeServiceAccountName" . }} | ||||
|     {{- end }} | ||||
|     {{- if and (ne $containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }} | ||||
|     {{- if and (ne $containerMode.type "kubernetes") (ne $containerMode.type "kubernetes-novolume") (not .Values.template.spec.serviceAccountName) }} | ||||
|     actions.github.com/cleanup-no-permission-service-account-name: {{ include "gha-runner-scale-set.noPermissionServiceAccountName" . }} | ||||
|     {{- end }} | ||||
| 
 | ||||
|  | @ -176,7 +176,7 @@ spec: | |||
|       restartPolicy: Never | ||||
|       {{- end }} | ||||
|       {{- $containerMode := .Values.containerMode }} | ||||
|       {{- if eq $containerMode.type "kubernetes" }} | ||||
|       {{- if or (eq $containerMode.type "kubernetes") (eq $containerMode.type "kubernetes-novolume") }} | ||||
|       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 }} | ||||
|  | @ -208,11 +208,15 @@ spec: | |||
|       - name: runner | ||||
|         {{- include "gha-runner-scale-set.kubernetes-mode-runner-container" . | nindent 8 }} | ||||
|       {{- include "gha-runner-scale-set.non-runner-containers" . | nindent 6 }} | ||||
|       {{- else if eq $containerMode.type "kubernetes-novolume" }} | ||||
|       - name: runner | ||||
|         {{- include "gha-runner-scale-set.kubernetes-novolume-mode-runner-container" . | nindent 8 }} | ||||
|       {{- include "gha-runner-scale-set.non-runner-containers" . | nindent 6 }} | ||||
|       {{- else }} | ||||
|       {{- include "gha-runner-scale-set.default-mode-runner-containers" . | nindent 6 }} | ||||
|       {{- end }} | ||||
|       {{- $tlsConfig := (default (dict) .Values.githubServerTLS) }} | ||||
|       {{- if or .Values.template.spec.volumes (eq $containerMode.type "dind") (eq $containerMode.type "kubernetes") $tlsConfig.runnerMountPath }} | ||||
|       {{- if or .Values.template.spec.volumes (eq $containerMode.type "dind") (eq $containerMode.type "kubernetes") (eq $containerMode.type "kubernetes-novolume") $tlsConfig.runnerMountPath }} | ||||
|       volumes: | ||||
|         {{- if $tlsConfig.runnerMountPath }} | ||||
|           {{- include "gha-runner-scale-set.tls-volume" $tlsConfig | nindent 6 }} | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| {{- $containerMode := .Values.containerMode }} | ||||
| {{- $hasCustomResourceMeta := (and .Values.resourceMeta .Values.resourceMeta.kubernetesModeRole) }} | ||||
| {{- if and (eq $containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }} | ||||
| {{- if and (or (eq $containerMode.type "kubernetes") (eq $containerMode.type "kubernetes-novolume")) (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 | ||||
|  | @ -45,9 +45,11 @@ rules: | |||
| - apiGroups: [""] | ||||
|   resources: ["pods/log"] | ||||
|   verbs: ["get", "list", "watch",] | ||||
| {{- if ne $containerMode.type "kubernetes-novolume" }} | ||||
| - apiGroups: ["batch"] | ||||
|   resources: ["jobs"] | ||||
|   verbs: ["get", "list", "create", "delete"] | ||||
| {{- end }} | ||||
| - apiGroups: [""] | ||||
|   resources: ["secrets"] | ||||
|   verbs: ["get", "list", "create", "delete"] | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| {{- $containerMode := .Values.containerMode }} | ||||
| {{- $hasCustomResourceMeta := (and .Values.resourceMeta .Values.resourceMeta.kubernetesModeRoleBinding) }} | ||||
| {{- if and (eq $containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }} | ||||
| {{- if and (or (eq $containerMode.type "kubernetes") (eq $containerMode.type "kubernetes-novolume")) (not .Values.template.spec.serviceAccountName) }} | ||||
| apiVersion: rbac.authorization.k8s.io/v1 | ||||
| kind: RoleBinding | ||||
| metadata: | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| {{- $containerMode := .Values.containerMode }} | ||||
| {{- $hasCustomResourceMeta := (and .Values.resourceMeta .Values.resourceMeta.kubernetesModeServiceAccount) }} | ||||
| {{- if and (eq $containerMode.type "kubernetes") (not .Values.template.spec.serviceAccountName) }} | ||||
| {{- if and (or (eq $containerMode.type "kubernetes") (eq $containerMode.type "kubernetes-novolume")) (not .Values.template.spec.serviceAccountName) }} | ||||
| apiVersion: v1 | ||||
| kind: ServiceAccount | ||||
| metadata: | ||||
|  |  | |||
|  | @ -204,7 +204,6 @@ func TestTemplateRenderedSetServiceAccountToNoPermission(t *testing.T) { | |||
| 
 | ||||
| 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) | ||||
|  | @ -270,6 +269,72 @@ func TestTemplateRenderedSetServiceAccountToKubeMode(t *testing.T) { | |||
| 	assert.Equal(t, expectedServiceAccountName, ars.Annotations[actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName]) | ||||
| } | ||||
| 
 | ||||
| func TestTemplateRenderedSetServiceAccountToKubeNoVolumeMode(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{ | ||||
| 		Logger: logger.Discard, | ||||
| 		SetValues: map[string]string{ | ||||
| 			"githubConfigUrl":                    "https://github.com/actions", | ||||
| 			"githubConfigSecret.github_token":    "gh_token12345", | ||||
| 			"containerMode.type":                 "kubernetes-novolume", | ||||
| 			"controllerServiceAccount.name":      "arc", | ||||
| 			"controllerServiceAccount.namespace": "arc-system", | ||||
| 		}, | ||||
| 		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-rs-kube-mode", serviceAccount.Name) | ||||
| 	assert.Equal(t, "actions.github.com/cleanup-protection", serviceAccount.Finalizers[0]) | ||||
| 
 | ||||
| 	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-rs-kube-mode", role.Name) | ||||
| 
 | ||||
| 	assert.Equal(t, "actions.github.com/cleanup-protection", role.Finalizers[0]) | ||||
| 
 | ||||
| 	assert.Len(t, role.Rules, 4, "kube mode role should have 4 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, "secrets", role.Rules[3].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-rs-kube-mode", roleBinding.Name) | ||||
| 	assert.Len(t, roleBinding.Subjects, 1) | ||||
| 	assert.Equal(t, "test-runners-gha-rs-kube-mode", roleBinding.Subjects[0].Name) | ||||
| 	assert.Equal(t, namespaceName, roleBinding.Subjects[0].Namespace) | ||||
| 	assert.Equal(t, "test-runners-gha-rs-kube-mode", roleBinding.RoleRef.Name) | ||||
| 	assert.Equal(t, "Role", roleBinding.RoleRef.Kind) | ||||
| 	assert.Equal(t, "actions.github.com/cleanup-protection", serviceAccount.Finalizers[0]) | ||||
| 
 | ||||
| 	output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"}) | ||||
| 	var ars v1alpha1.AutoscalingRunnerSet | ||||
| 	helm.UnmarshalK8SYaml(t, output, &ars) | ||||
| 
 | ||||
| 	expectedServiceAccountName := "test-runners-gha-rs-kube-mode" | ||||
| 	assert.Equal(t, expectedServiceAccountName, ars.Spec.Template.Spec.ServiceAccountName) | ||||
| 	assert.Equal(t, expectedServiceAccountName, ars.Annotations[actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName]) | ||||
| } | ||||
| 
 | ||||
| func TestTemplateRenderedUserProvideSetServiceAccount(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 
 | ||||
|  | @ -961,6 +1026,65 @@ func TestTemplateRenderedAutoScalingRunnerSet_EnableKubernetesMode(t *testing.T) | |||
| 	assert.NotNil(t, ars.Spec.Template.Spec.Volumes[0].Ephemeral, "Template.Spec should have 1 ephemeral volume") | ||||
| } | ||||
| 
 | ||||
| func TestTemplateRenderedAutoScalingRunnerSet_EnableKubernetesModeNoVolume(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{ | ||||
| 		Logger: logger.Discard, | ||||
| 		SetValues: map[string]string{ | ||||
| 			"githubConfigUrl":                    "https://github.com/actions", | ||||
| 			"githubConfigSecret.github_token":    "gh_token12345", | ||||
| 			"containerMode.type":                 "kubernetes-novolume", | ||||
| 			"controllerServiceAccount.name":      "arc", | ||||
| 			"controllerServiceAccount.namespace": "arc-system", | ||||
| 		}, | ||||
| 		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, "test-runners", 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-rs-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) | ||||
| 
 | ||||
| 	require.Len(t, ars.Spec.Template.Spec.Containers[0].Env, 4, "The runner container should have 4 env vars") | ||||
| 	assert.Equal(t, "ACTIONS_RUNNER_CONTAINER_HOOKS", ars.Spec.Template.Spec.Containers[0].Env[0].Name) | ||||
| 	assert.Equal(t, "/home/runner/k8s-novolume/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.Equal(t, "ACTIONS_RUNNER_IMAGE", ars.Spec.Template.Spec.Containers[0].Env[3].Name) | ||||
| 	assert.Equal(t, ars.Spec.Template.Spec.Containers[0].Image, ars.Spec.Template.Spec.Containers[0].Env[3].Value) | ||||
| 
 | ||||
| 	assert.Len(t, ars.Spec.Template.Spec.Volumes, 0, "Template.Spec should have 0 volumes") | ||||
| } | ||||
| 
 | ||||
| func TestTemplateRenderedAutoscalingRunnerSet_ListenerPodTemplate(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 
 | ||||
|  | @ -1140,7 +1264,7 @@ func TestTemplateRenderedWithTLS(t *testing.T) { | |||
| 	} | ||||
| 
 | ||||
| 	t.Run("providing githubServerTLS.runnerMountPath", func(t *testing.T) { | ||||
| 		t.Run("mode: default", func(t *testing.T) { | ||||
| 		t.Run("mode default", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
|  | @ -1199,7 +1323,7 @@ func TestTemplateRenderedWithTLS(t *testing.T) { | |||
| 			}) | ||||
| 		}) | ||||
| 
 | ||||
| 		t.Run("mode: dind", func(t *testing.T) { | ||||
| 		t.Run("mode dind", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
|  | @ -1259,7 +1383,7 @@ func TestTemplateRenderedWithTLS(t *testing.T) { | |||
| 			}) | ||||
| 		}) | ||||
| 
 | ||||
| 		t.Run("mode: kubernetes", func(t *testing.T) { | ||||
| 		t.Run("mode kubernetes", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
|  | @ -1318,10 +1442,70 @@ func TestTemplateRenderedWithTLS(t *testing.T) { | |||
| 				Value: "1", | ||||
| 			}) | ||||
| 		}) | ||||
| 
 | ||||
| 		t.Run("mode kubernetes-novolume", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
| 					"githubConfigUrl":    "https://github.com/actions", | ||||
| 					"githubConfigSecret": "pre-defined-secrets", | ||||
| 					"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap", | ||||
| 					"githubServerTLS.certificateFrom.configMapKeyRef.key":  "cert.pem", | ||||
| 					"githubServerTLS.runnerMountPath":                      "/runner/mount/path", | ||||
| 					"containerMode.type":                                   "kubernetes-novolume", | ||||
| 					"controllerServiceAccount.name":                        "arc", | ||||
| 					"controllerServiceAccount.namespace":                   "arc-system", | ||||
| 				}, | ||||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName), | ||||
| 			} | ||||
| 
 | ||||
| 			ars := render(t, options) | ||||
| 
 | ||||
| 			require.NotNil(t, ars.Spec.GitHubServerTLS) | ||||
| 			expected := &v1alpha1.TLSConfig{ | ||||
| 				CertificateFrom: &v1alpha1.TLSCertificateSource{ | ||||
| 					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ | ||||
| 						LocalObjectReference: corev1.LocalObjectReference{ | ||||
| 							Name: "certs-configmap", | ||||
| 						}, | ||||
| 						Key: "cert.pem", | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
| 			assert.Equal(t, expected, ars.Spec.GitHubServerTLS) | ||||
| 
 | ||||
| 			var volume *corev1.Volume | ||||
| 			for _, v := range ars.Spec.Template.Spec.Volumes { | ||||
| 				if v.Name == "github-server-tls-cert" { | ||||
| 					volume = &v | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			require.NotNil(t, volume) | ||||
| 			assert.Equal(t, "certs-configmap", volume.ConfigMap.Name) | ||||
| 			assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Key) | ||||
| 			assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Path) | ||||
| 
 | ||||
| 			assert.Contains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{ | ||||
| 				Name:      "github-server-tls-cert", | ||||
| 				MountPath: "/runner/mount/path/cert.pem", | ||||
| 				SubPath:   "cert.pem", | ||||
| 			}) | ||||
| 
 | ||||
| 			assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ | ||||
| 				Name:  "NODE_EXTRA_CA_CERTS", | ||||
| 				Value: "/runner/mount/path/cert.pem", | ||||
| 			}) | ||||
| 
 | ||||
| 			assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ | ||||
| 				Name:  "RUNNER_UPDATE_CA_CERTS", | ||||
| 				Value: "1", | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("without providing githubServerTLS.runnerMountPath", func(t *testing.T) { | ||||
| 		t.Run("mode: default", func(t *testing.T) { | ||||
| 		t.Run("mode default", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
|  | @ -1376,7 +1560,7 @@ func TestTemplateRenderedWithTLS(t *testing.T) { | |||
| 			}) | ||||
| 		}) | ||||
| 
 | ||||
| 		t.Run("mode: dind", func(t *testing.T) { | ||||
| 		t.Run("mode dind", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
|  | @ -1432,7 +1616,7 @@ func TestTemplateRenderedWithTLS(t *testing.T) { | |||
| 			}) | ||||
| 		}) | ||||
| 
 | ||||
| 		t.Run("mode: kubernetes", func(t *testing.T) { | ||||
| 		t.Run("mode kubernetes", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
|  | @ -1487,6 +1671,62 @@ func TestTemplateRenderedWithTLS(t *testing.T) { | |||
| 				Value: "1", | ||||
| 			}) | ||||
| 		}) | ||||
| 
 | ||||
| 		t.Run("mode kubernetes-novolume", func(t *testing.T) { | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
| 					"githubConfigUrl":    "https://github.com/actions", | ||||
| 					"githubConfigSecret": "pre-defined-secrets", | ||||
| 					"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap", | ||||
| 					"githubServerTLS.certificateFrom.configMapKeyRef.key":  "cert.pem", | ||||
| 					"containerMode.type":                 "kubernetes-novolume", | ||||
| 					"controllerServiceAccount.name":      "arc", | ||||
| 					"controllerServiceAccount.namespace": "arc-system", | ||||
| 				}, | ||||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName), | ||||
| 			} | ||||
| 
 | ||||
| 			ars := render(t, options) | ||||
| 
 | ||||
| 			require.NotNil(t, ars.Spec.GitHubServerTLS) | ||||
| 			expected := &v1alpha1.TLSConfig{ | ||||
| 				CertificateFrom: &v1alpha1.TLSCertificateSource{ | ||||
| 					ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ | ||||
| 						LocalObjectReference: corev1.LocalObjectReference{ | ||||
| 							Name: "certs-configmap", | ||||
| 						}, | ||||
| 						Key: "cert.pem", | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
| 			assert.Equal(t, expected, ars.Spec.GitHubServerTLS) | ||||
| 
 | ||||
| 			var volume *corev1.Volume | ||||
| 			for _, v := range ars.Spec.Template.Spec.Volumes { | ||||
| 				if v.Name == "github-server-tls-cert" { | ||||
| 					volume = &v | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			assert.Nil(t, volume) | ||||
| 
 | ||||
| 			assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{ | ||||
| 				Name:      "github-server-tls-cert", | ||||
| 				MountPath: "/runner/mount/path/cert.pem", | ||||
| 				SubPath:   "cert.pem", | ||||
| 			}) | ||||
| 
 | ||||
| 			assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ | ||||
| 				Name:  "NODE_EXTRA_CA_CERTS", | ||||
| 				Value: "/runner/mount/path/cert.pem", | ||||
| 			}) | ||||
| 
 | ||||
| 			assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ | ||||
| 				Name:  "RUNNER_UPDATE_CA_CERTS", | ||||
| 				Value: "1", | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
|  | @ -1951,40 +2191,44 @@ func TestTemplateRenderedAutoscalingRunnerSetAnnotation_GitHubSecret(t *testing. | |||
| func TestTemplateRenderedAutoscalingRunnerSetAnnotation_KubernetesModeCleanup(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) | ||||
| 	for _, mode := range []string{"kubernetes", "kubernetes-novolume"} { | ||||
| 		t.Run("containerMode "+mode, func(t *testing.T) { | ||||
| 			// 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()) | ||||
| 			releaseName := "test-runners" | ||||
| 			namespaceName := "test-" + strings.ToLower(random.UniqueId()) | ||||
| 
 | ||||
| 	options := &helm.Options{ | ||||
| 		Logger: logger.Discard, | ||||
| 		SetValues: map[string]string{ | ||||
| 			"githubConfigUrl":                    "https://github.com/actions", | ||||
| 			"githubConfigSecret.github_token":    "gh_token12345", | ||||
| 			"controllerServiceAccount.name":      "arc", | ||||
| 			"controllerServiceAccount.namespace": "arc-system", | ||||
| 			"containerMode.type":                 "kubernetes", | ||||
| 		}, | ||||
| 		KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName), | ||||
| 	} | ||||
| 			options := &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
| 					"githubConfigUrl":                    "https://github.com/actions", | ||||
| 					"githubConfigSecret.github_token":    "gh_token12345", | ||||
| 					"controllerServiceAccount.name":      "arc", | ||||
| 					"controllerServiceAccount.namespace": "arc-system", | ||||
| 					"containerMode.type":                 mode, | ||||
| 				}, | ||||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName), | ||||
| 			} | ||||
| 
 | ||||
| 	output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"}) | ||||
| 	var autoscalingRunnerSet v1alpha1.AutoscalingRunnerSet | ||||
| 	helm.UnmarshalK8SYaml(t, output, &autoscalingRunnerSet) | ||||
| 			output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"}) | ||||
| 			var autoscalingRunnerSet v1alpha1.AutoscalingRunnerSet | ||||
| 			helm.UnmarshalK8SYaml(t, output, &autoscalingRunnerSet) | ||||
| 
 | ||||
| 	annotationValues := map[string]string{ | ||||
| 		actionsgithubcom.AnnotationKeyGitHubSecretName:                 "test-runners-gha-rs-github-secret", | ||||
| 		actionsgithubcom.AnnotationKeyManagerRoleName:                  "test-runners-gha-rs-manager", | ||||
| 		actionsgithubcom.AnnotationKeyManagerRoleBindingName:           "test-runners-gha-rs-manager", | ||||
| 		actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName: "test-runners-gha-rs-kube-mode", | ||||
| 		actionsgithubcom.AnnotationKeyKubernetesModeRoleName:           "test-runners-gha-rs-kube-mode", | ||||
| 		actionsgithubcom.AnnotationKeyKubernetesModeRoleBindingName:    "test-runners-gha-rs-kube-mode", | ||||
| 	} | ||||
| 			annotationValues := map[string]string{ | ||||
| 				actionsgithubcom.AnnotationKeyGitHubSecretName:                 "test-runners-gha-rs-github-secret", | ||||
| 				actionsgithubcom.AnnotationKeyManagerRoleName:                  "test-runners-gha-rs-manager", | ||||
| 				actionsgithubcom.AnnotationKeyManagerRoleBindingName:           "test-runners-gha-rs-manager", | ||||
| 				actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName: "test-runners-gha-rs-kube-mode", | ||||
| 				actionsgithubcom.AnnotationKeyKubernetesModeRoleName:           "test-runners-gha-rs-kube-mode", | ||||
| 				actionsgithubcom.AnnotationKeyKubernetesModeRoleBindingName:    "test-runners-gha-rs-kube-mode", | ||||
| 			} | ||||
| 
 | ||||
| 	for annotation, value := range annotationValues { | ||||
| 		assert.Equal(t, value, autoscalingRunnerSet.Annotations[annotation], fmt.Sprintf("Annotation %q does not match the expected value", annotation)) | ||||
| 			for annotation, value := range annotationValues { | ||||
| 				assert.Equal(t, value, autoscalingRunnerSet.Annotations[annotation], fmt.Sprintf("Annotation %q does not match the expected value", annotation)) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -2416,6 +2660,21 @@ func TestNamespaceOverride(t *testing.T) { | |||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace), | ||||
| 			}, | ||||
| 		}, | ||||
| 		"kube_novolume_mode_role": { | ||||
| 			file: "kube_mode_role.yaml", | ||||
| 			options: &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
| 					"namespaceOverride":                  namespaceOverride, | ||||
| 					"containerMode.type":                 "kubernetes-novolume", | ||||
| 					"controllerServiceAccount.name":      "foo", | ||||
| 					"controllerServiceAccount.namespace": "bar", | ||||
| 					"githubConfigSecret.github_token":    "gh_token12345", | ||||
| 					"githubConfigUrl":                    "https://github.com", | ||||
| 				}, | ||||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace), | ||||
| 			}, | ||||
| 		}, | ||||
| 		"kube_mode_role_binding": { | ||||
| 			file: "kube_mode_role_binding.yaml", | ||||
| 			options: &helm.Options{ | ||||
|  | @ -2431,6 +2690,21 @@ func TestNamespaceOverride(t *testing.T) { | |||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace), | ||||
| 			}, | ||||
| 		}, | ||||
| 		"kube_novolume_mode_role_binding": { | ||||
| 			file: "kube_mode_role_binding.yaml", | ||||
| 			options: &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
| 					"namespaceOverride":                  namespaceOverride, | ||||
| 					"containerMode.type":                 "kubernetes-novolume", | ||||
| 					"controllerServiceAccount.name":      "foo", | ||||
| 					"controllerServiceAccount.namespace": "bar", | ||||
| 					"githubConfigSecret.github_token":    "gh_token12345", | ||||
| 					"githubConfigUrl":                    "https://github.com", | ||||
| 				}, | ||||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace), | ||||
| 			}, | ||||
| 		}, | ||||
| 		"kube_mode_serviceaccount": { | ||||
| 			file: "kube_mode_serviceaccount.yaml", | ||||
| 			options: &helm.Options{ | ||||
|  | @ -2446,6 +2720,21 @@ func TestNamespaceOverride(t *testing.T) { | |||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace), | ||||
| 			}, | ||||
| 		}, | ||||
| 		"kube_novolume_mode_serviceaccount": { | ||||
| 			file: "kube_mode_serviceaccount.yaml", | ||||
| 			options: &helm.Options{ | ||||
| 				Logger: logger.Discard, | ||||
| 				SetValues: map[string]string{ | ||||
| 					"namespaceOverride":                  namespaceOverride, | ||||
| 					"containerMode.type":                 "kubernetes-novolume", | ||||
| 					"controllerServiceAccount.name":      "foo", | ||||
| 					"controllerServiceAccount.namespace": "bar", | ||||
| 					"githubConfigSecret.github_token":    "gh_token12345", | ||||
| 					"githubConfigUrl":                    "https://github.com", | ||||
| 				}, | ||||
| 				KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace), | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for name, tc := range tt { | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ githubConfigSecret: | |||
| ## If any customization is required for dind or kubernetes mode, containerMode should remain | ||||
| ## empty, and configuration should be applied to the template. | ||||
| # containerMode: | ||||
| #   type: "dind"  ## type can be set to dind or kubernetes | ||||
| #   type: "dind"  ## type can be set to "dind", "kubernetes", or "kubernetes-novolume" | ||||
| #   ## the following is required when containerMode.type=kubernetes | ||||
| #   kubernetesModeWorkVolumeClaim: | ||||
| #     accessModes: ["ReadWriteOnce"] | ||||
|  | @ -391,6 +391,25 @@ template: | |||
|   ##               resources: | ||||
|   ##                 requests: | ||||
|   ##                   storage: 1Gi | ||||
|   ###################################################################################################### | ||||
|   ## with containerMode.type=kubernetes-novolume, we will populate the template.spec with following pod spec | ||||
|   ## template: | ||||
|   ##   spec: | ||||
|   ##     containers: | ||||
|   ##     - name: runner | ||||
|   ##       image: ghcr.io/actions/actions-runner:latest | ||||
|   ##       command: ["/home/runner/run.sh"] | ||||
|   ##       env: | ||||
|   ##         - name: ACTIONS_RUNNER_CONTAINER_HOOKS | ||||
|   ##           value: /home/runner/k8s-novolume/index.js | ||||
|   ##         - name: ACTIONS_RUNNER_POD_NAME | ||||
|   ##           valueFrom: | ||||
|   ##             fieldRef: | ||||
|   ##               fieldPath: metadata.name | ||||
|   ##         - name: ACTIONS_RUNNER_IMAGE | ||||
|   ##           value: ghcr.io/actions/actions-runner:latest # should match the runnerimage | ||||
|   ##         - name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER | ||||
|   ##           value: "true" | ||||
|   spec: | ||||
|     containers: | ||||
|       - name: runner | ||||
|  |  | |||
|  | @ -336,6 +336,19 @@ func (r *EphemeralRunnerReconciler) Reconcile(ctx context.Context, req ctrl.Requ | |||
| 				log.Error(err, "Failed to delete the ephemeral runner that has a job assigned but the pod has failed") | ||||
| 				return ctrl.Result{}, err | ||||
| 			} | ||||
| 
 | ||||
| 			log.Info("Deleted the ephemeral runner that has a job assigned but the pod has failed") | ||||
| 			log.Info("Trying to remove the runner from the service") | ||||
| 			actionsClient, err := r.GetActionsService(ctx, ephemeralRunner) | ||||
| 			if err != nil { | ||||
| 				log.Error(err, "Failed to get actions client for removing the runner from the service") | ||||
| 				return ctrl.Result{}, nil | ||||
| 			} | ||||
| 			if err := actionsClient.RemoveRunner(ctx, int64(ephemeralRunner.Status.RunnerId)); err != nil { | ||||
| 				log.Error(err, "Failed to remove the runner from the service") | ||||
| 				return ctrl.Result{}, nil | ||||
| 			} | ||||
| 			log.Info("Removed the runner from the service") | ||||
| 			return ctrl.Result{}, nil | ||||
| 		} | ||||
| 		if err := r.deletePodAsFailed(ctx, ephemeralRunner, pod, log); err != nil { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue