You've already forked woodpecker
mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-06-03 16:35:37 +02:00
Allow disabling service workspace volumes in k8s (#6644)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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{
|
||||
@@ -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}},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = `
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user