diff --git a/api/v1alpha1/runner_types.go b/api/v1alpha1/runner_types.go index c1f78071..54d5ea9b 100644 --- a/api/v1alpha1/runner_types.go +++ b/api/v1alpha1/runner_types.go @@ -48,6 +48,8 @@ type RunnerSpec struct { // +optional DockerdContainerResources corev1.ResourceRequirements `json:"dockerdContainerResources,omitempty"` // +optional + DockerVolumeMounts []corev1.VolumeMount `json:"dockerVolumeMounts,omitempty"` + // +optional Resources corev1.ResourceRequirements `json:"resources,omitempty"` // +optional VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index a0d49f3e..1368a0c5 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -595,6 +595,13 @@ func (in *RunnerSpec) DeepCopyInto(out *RunnerSpec) { } } in.DockerdContainerResources.DeepCopyInto(&out.DockerdContainerResources) + if in.DockerVolumeMounts != nil { + in, out := &in.DockerVolumeMounts, &out.DockerVolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } in.Resources.DeepCopyInto(&out.Resources) if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts diff --git a/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml b/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml index 9c2cba09..b6f2201a 100644 --- a/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml +++ b/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml @@ -436,6 +436,33 @@ spec: dockerMTU: format: int64 type: integer + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. This field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array dockerdContainerResources: description: ResourceRequirements describes the compute resource requirements. properties: diff --git a/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml b/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml index d3580df5..e7c7a843 100644 --- a/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml +++ b/charts/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml @@ -436,6 +436,33 @@ spec: dockerMTU: format: int64 type: integer + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. This field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array dockerdContainerResources: description: ResourceRequirements describes the compute resource requirements. properties: diff --git a/charts/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml b/charts/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml index fb53c769..f4def867 100644 --- a/charts/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml +++ b/charts/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml @@ -401,6 +401,33 @@ spec: dockerMTU: format: int64 type: integer + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. This field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array dockerdContainerResources: description: ResourceRequirements describes the compute resource requirements. properties: diff --git a/config/crd/bases/actions.summerwind.dev_runnerdeployments.yaml b/config/crd/bases/actions.summerwind.dev_runnerdeployments.yaml index 9c2cba09..b6f2201a 100644 --- a/config/crd/bases/actions.summerwind.dev_runnerdeployments.yaml +++ b/config/crd/bases/actions.summerwind.dev_runnerdeployments.yaml @@ -436,6 +436,33 @@ spec: dockerMTU: format: int64 type: integer + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. This field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array dockerdContainerResources: description: ResourceRequirements describes the compute resource requirements. properties: diff --git a/config/crd/bases/actions.summerwind.dev_runnerreplicasets.yaml b/config/crd/bases/actions.summerwind.dev_runnerreplicasets.yaml index d3580df5..e7c7a843 100644 --- a/config/crd/bases/actions.summerwind.dev_runnerreplicasets.yaml +++ b/config/crd/bases/actions.summerwind.dev_runnerreplicasets.yaml @@ -436,6 +436,33 @@ spec: dockerMTU: format: int64 type: integer + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. This field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array dockerdContainerResources: description: ResourceRequirements describes the compute resource requirements. properties: diff --git a/config/crd/bases/actions.summerwind.dev_runners.yaml b/config/crd/bases/actions.summerwind.dev_runners.yaml index fb53c769..f4def867 100644 --- a/config/crd/bases/actions.summerwind.dev_runners.yaml +++ b/config/crd/bases/actions.summerwind.dev_runners.yaml @@ -401,6 +401,33 @@ spec: dockerMTU: format: int64 type: integer + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. This field is beta in 1.15. + type: string + required: + - mountPath + - name + type: object + type: array dockerdContainerResources: description: ResourceRequirements describes the compute resource requirements. properties: diff --git a/controllers/runner_controller.go b/controllers/runner_controller.go index e79c7aa1..82b5af05 100644 --- a/controllers/runner_controller.go +++ b/controllers/runner_controller.go @@ -20,11 +20,12 @@ import ( "context" "errors" "fmt" + "strings" + "time" + gogithub "github.com/google/go-github/v33/github" "github.com/summerwind/actions-runner-controller/hash" "k8s.io/apimachinery/pkg/util/wait" - "strings" - "time" "github.com/go-logr/logr" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -700,23 +701,31 @@ func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) { Value: "/certs/client", }, }...) - pod.Spec.Containers = append(pod.Spec.Containers, corev1.Container{ - Name: "docker", - Image: r.DockerImage, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "work", - MountPath: workDir, - }, - { - Name: runnerVolumeName, - MountPath: runnerVolumeMountPath, - }, - { - Name: "certs-client", - MountPath: "/certs/client", - }, + + // 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/summerwind/actions-runner-controller/issues/435 for context. + dockerVolumeMounts := []corev1.VolumeMount{ + { + Name: "work", + MountPath: workDir, }, + { + Name: runnerVolumeName, + MountPath: runnerVolumeMountPath, + }, + { + Name: "certs-client", + MountPath: "/certs/client", + }, + } + if extraDockerVolumeMounts := runner.Spec.DockerVolumeMounts; extraDockerVolumeMounts != nil { + dockerVolumeMounts = append(dockerVolumeMounts, extraDockerVolumeMounts...) + } + + pod.Spec.Containers = append(pod.Spec.Containers, corev1.Container{ + Name: "docker", + Image: r.DockerImage, + VolumeMounts: dockerVolumeMounts, Env: []corev1.EnvVar{ { Name: "DOCKER_TLS_CERTDIR",