Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ steps:

To give steps access to the Kubernetes API via service account, take a look at [RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)

### Workspace volume

`workspaceVolume` controls whether the default workspace volume is mounted into a service Pod. It only affects service
containers and does not disable explicitly configured service volumes.

If unset, the default workspace volume is mounted.

```yaml
services:
postgres:
image: postgres:16
backend_options:
kubernetes:
workspaceVolume: false
```

### Node selector

`nodeSelector` specifies the labels which are used to select the node on which the step will be executed.
Expand Down
1 change: 1 addition & 0 deletions pipeline/backend/kubernetes/backend_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type BackendOptions struct {
Affinity *kube_core_v1.Affinity `mapstructure:"affinity"`
SecurityContext *SecurityContext `mapstructure:"securityContext"`
Secrets []SecretRef `mapstructure:"secrets"`
WorkspaceVolume *bool `mapstructure:"workspaceVolume"`
}

// Resources defines two maps for kubernetes resource definitions.
Expand Down
2 changes: 2 additions & 0 deletions pipeline/backend/kubernetes/backend_options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func Test_parseBackendOptions(t *testing.T) {
"kubernetes": map[string]any{
"nodeSelector": map[string]string{"storage": "ssd"},
"serviceAccountName": "wp-svc-acc",
"workspaceVolume": false,
"labels": map[string]string{"app": "test"},
"annotations": map[string]string{"apps.kubernetes.io/pod-index": "0"},
"tolerations": []map[string]any{
Expand Down Expand Up @@ -107,6 +108,7 @@ func Test_parseBackendOptions(t *testing.T) {
want: BackendOptions{
NodeSelector: map[string]string{"storage": "ssd"},
ServiceAccountName: "wp-svc-acc",
WorkspaceVolume: newBool(false),
Labels: map[string]string{"app": "test"},
Annotations: map[string]string{"apps.kubernetes.io/pod-index": "0"},
Tolerations: []Toleration{{Key: "net-port", Value: "100Mbit", Effect: TaintEffectNoSchedule}},
Expand Down
25 changes: 23 additions & 2 deletions pipeline/backend/kubernetes/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func podSpec(step *types.Step, config *config, options BackendOptions, nsp nativ
spec.Tolerations = tolerations(config.PodTolerations)
}

spec.Volumes, err = pvcVolumes(step.Volumes)
spec.Volumes, err = pvcVolumes(podVolumes(step, options))
if err != nil {
return spec, err
}
Expand Down Expand Up @@ -278,7 +278,7 @@ func podContainer(step *types.Step, podName, goos string, options BackendOptions
return container, err
}

container.VolumeMounts, err = volumeMounts(step.Volumes)
container.VolumeMounts, err = volumeMounts(podVolumes(step, options))
if err != nil {
return container, err
}
Expand Down Expand Up @@ -388,6 +388,27 @@ func pvcVolumes(volumes []string) ([]kube_core_v1.Volume, error) {
return vols, nil
}

func podVolumes(step *types.Step, options BackendOptions) []string {
if !isService(step) || useWorkspaceVolume(options) {
return step.Volumes
}

volumes := make([]string, 0, len(step.Volumes))
for _, volume := range step.Volumes {
if volumeMountPath(volume) != step.WorkspaceBase {
volumes = append(volumes, volume)
}
}
return volumes
}

func useWorkspaceVolume(options BackendOptions) bool {
if options.WorkspaceVolume != nil {
return *options.WorkspaceVolume
}
return true
}

func pvcVolume(name string) kube_core_v1.Volume {
pvcSource := kube_core_v1.PersistentVolumeClaimVolumeSource{
ClaimName: name,
Expand Down
38 changes: 38 additions & 0 deletions pipeline/backend/kubernetes/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,44 @@ func TestTinyPod(t *testing.T) {
ja.Assertf(string(podJSON), expected)
}

func TestServiceWorkspaceVolume(t *testing.T) {
useWorkspaceVolume := true
disableWorkspaceVolume := false
step := &types.Step{
Name: "postgres",
Image: "postgres:16",
UUID: "01he8bebctabr3kgk0qj36d2me-0",
Type: types.StepTypeService,
WorkingDir: "/woodpecker/src",
WorkspaceBase: "/woodpecker",
Environment: map[string]string{},
Volumes: []string{"workspace:/woodpecker", "cache:/cache"},
}

pod, err := mkPod(step, &config{Namespace: "woodpecker"}, "wp-svc-postgres", "linux/amd64", BackendOptions{}, taskUUID)
assert.NoError(t, err)
assert.Len(t, pod.Spec.Volumes, 2)
assert.Equal(t, "workspace", pod.Spec.Volumes[0].Name)
assert.Equal(t, "/woodpecker", pod.Spec.Containers[0].VolumeMounts[0].MountPath)
assert.Equal(t, "cache", pod.Spec.Volumes[1].Name)
assert.Equal(t, "/cache", pod.Spec.Containers[0].VolumeMounts[1].MountPath)

pod, err = mkPod(step, &config{Namespace: "woodpecker"}, "wp-svc-postgres", "linux/amd64", BackendOptions{WorkspaceVolume: &disableWorkspaceVolume}, taskUUID)
assert.NoError(t, err)
assert.Len(t, pod.Spec.Volumes, 1)
assert.Equal(t, "cache", pod.Spec.Volumes[0].Name)
assert.Len(t, pod.Spec.Containers[0].VolumeMounts, 1)
assert.Equal(t, "/cache", pod.Spec.Containers[0].VolumeMounts[0].MountPath)

pod, err = mkPod(step, &config{Namespace: "woodpecker"}, "wp-svc-postgres", "linux/amd64", BackendOptions{WorkspaceVolume: &useWorkspaceVolume}, taskUUID)
assert.NoError(t, err)
assert.Len(t, pod.Spec.Volumes, 2)
assert.Equal(t, "workspace", pod.Spec.Volumes[0].Name)
assert.Equal(t, "/woodpecker", pod.Spec.Containers[0].VolumeMounts[0].MountPath)
assert.Equal(t, "cache", pod.Spec.Volumes[1].Name)
assert.Equal(t, "/cache", pod.Spec.Containers[0].VolumeMounts[1].MountPath)
}

func TestFullPod(t *testing.T) {
const expected = `
{
Expand Down