From 8a73560dbccc46df9fda7284173057b556b909fc Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 7 Jan 2022 02:01:40 +0100 Subject: [PATCH] if a Volume is defined by the operator don't add another "work" volume. (#1015) This allows providing a different `work` Volume. This should be a cloud agnostic way of allowing the operator to use (for example) NVME backed storage. This is a working example where the workDir will use the provided volume, additionally here docker is placed on the same NVME. ``` apiVersion: actions.summerwind.dev/v1alpha1 kind: RunnerDeployment metadata: name: runner-2 spec: template: spec: dockerdContainerResources: {} env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name # this is to mount the docker in docker onto NVME disk dockerVolumeMounts: - mountPath: /var/lib/docker name: scratch subPathExpr: $(POD_NAME)-docker - mountPath: /runner/_work name: work subPathExpr: $(POD_NAME)-work volumeMounts: - mountPath: /runner/_work name: work subPathExpr: $(POD_NAME)-work dockerEnv: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name volumes: - hostPath: path: /mnt/disks/ssd0 name: scratch - hostPath: path: /mnt/disks/ssd0 name: work nodeSelector: cloud.google.com/gke-nodepool: runner-16-with-nvme ephemeral: false image: "" imagePullPolicy: Always labels: - runner-2 - self-hosted organization: yourorganization ``` --- controllers/runner_controller.go | 51 +++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/controllers/runner_controller.go b/controllers/runner_controller.go index d22e89ae..82743b44 100644 --- a/controllers/runner_controller.go +++ b/controllers/runner_controller.go @@ -672,10 +672,29 @@ func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) { runnerSpec := runner.Spec if len(runnerSpec.VolumeMounts) != 0 { + // if operater provides a work volume mount, use that + isPresent, _ := workVolumeMountPresent(runnerSpec.VolumeMounts) + if isPresent { + // remove work volume since it will be provided from runnerSpec.Volumes + // if we don't remove it here we would get a duplicate key error, i.e. two volumes named work + _, index := workVolumeMountPresent(pod.Spec.Containers[0].VolumeMounts) + pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts[:index], pod.Spec.Containers[0].VolumeMounts[index+1:]...) + } + pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, runnerSpec.VolumeMounts...) } if len(runnerSpec.Volumes) != 0 { + // if operator provides a work volume. use that + isPresent, _ := workVolumePresent(runnerSpec.Volumes) + if isPresent { + _, index := workVolumePresent(pod.Spec.Volumes) + + // remove work volume since it will be provided from runnerSpec.Volumes + // if we don't remove it here we would get a duplicate key error, i.e. two volumes named work + pod.Spec.Volumes = append(pod.Spec.Volumes[:index], pod.Spec.Volumes[index+1:]...) + } + pod.Spec.Volumes = append(pod.Spec.Volumes, runnerSpec.Volumes...) } if len(runnerSpec.InitContainers) != 0 { @@ -991,6 +1010,7 @@ func newRunnerPod(template corev1.Pod, runnerSpec v1alpha1.RunnerConfig, default }, }, ) + runnerContainer.VolumeMounts = append(runnerContainer.VolumeMounts, corev1.VolumeMount{ Name: "work", @@ -1002,6 +1022,7 @@ func newRunnerPod(template corev1.Pod, runnerSpec v1alpha1.RunnerConfig, default ReadOnly: true, }, ) + runnerContainer.Env = append(runnerContainer.Env, []corev1.EnvVar{ { Name: "DOCKER_HOST", @@ -1020,10 +1041,6 @@ func newRunnerPod(template corev1.Pod, runnerSpec v1alpha1.RunnerConfig, default // Determine the volume mounts assigned to the docker sidecar. In case extra mounts are included in the RunnerSpec, append them to the standard // set of mounts. See https://github.com/actions-runner-controller/actions-runner-controller/issues/435 for context. dockerVolumeMounts := []corev1.VolumeMount{ - { - Name: "work", - MountPath: workDir, - }, { Name: runnerVolumeName, MountPath: runnerVolumeMountPath, @@ -1034,6 +1051,14 @@ func newRunnerPod(template corev1.Pod, runnerSpec v1alpha1.RunnerConfig, default }, } + mountPresent, _ := workVolumeMountPresent(dockerdContainer.VolumeMounts) + if !mountPresent { + dockerVolumeMounts = append(dockerVolumeMounts, corev1.VolumeMount{ + Name: "work", + MountPath: workDir, + }) + } + if dockerdContainer.Image == "" { dockerdContainer.Image = defaultDockerImage } @@ -1139,3 +1164,21 @@ func removeFinalizer(finalizers []string, finalizerName string) ([]string, bool) return result, removed } + +func workVolumePresent(items []corev1.Volume) (bool, int) { + for index, item := range items { + if item.Name == "work" { + return true, index + } + } + return false, 0 +} + +func workVolumeMountPresent(items []corev1.VolumeMount) (bool, int) { + for index, item := range items { + if item.Name == "work" { + return true, index + } + } + return false, 0 +}