Kubernetes: allow custom image when precreating workingDir as nonroot (#6771)

Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
nati737
2026-06-26 19:14:59 +02:00
committed by GitHub
co-authored by 6543
parent 41181ab401
commit 75801db7df
5 changed files with 27 additions and 10 deletions
@@ -625,3 +625,12 @@ Secret names to pull images from private repositories. See, how to [Pull an Imag
- Default: none, which will use the default priority class configured in Kubernetes
Which [Kubernetes PriorityClass](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/priority-class-v1/) to assign to created job pods.
---
### BACKEND_K8S_PERMISSION_INIT_IMAGE
- Name: `WOODPECKER_BACKEND_K8S_PERMISSION_INIT_IMAGE`
- Default: 'busybox:stable-musl'
Container image used for the workspace permission init container, which is used to create the workspace directory and ensure correct permissions when running steps as non-root users.
+6
View File
@@ -134,4 +134,10 @@ var Flags = []cli.Flag{
Usage: "seconds Woodpecker waits for pods to stop gracefully before forcefully killing them",
Value: 20,
},
&cli.StringFlag{
Sources: cli.EnvVars("WOODPECKER_BACKEND_K8S_PERMISSION_INIT_IMAGE"),
Name: "backend-k8s-permission-init-image",
Usage: "image used by the workspace permission init container",
Value: "busybox:stable-musl",
},
}
@@ -78,6 +78,7 @@ type config struct {
NativeSecretsAllowFromStep bool
PriorityClassName string
StopTimeout int64
PermissionInitImage string
}
func (c *config) GetNamespace(orgID int64) string {
@@ -125,6 +126,7 @@ func configFromCliContext(ctx context.Context) (*config, error) {
},
NativeSecretsAllowFromStep: c.Bool("backend-k8s-allow-native-secrets"),
StopTimeout: c.Int64("backend-k8s-stop-timeout"),
PermissionInitImage: c.String("backend-k8s-permission-init-image"),
}
// Unmarshal label and annotation settings here to ensure they're valid on startup
if labels := c.String("backend-k8s-pod-labels"); labels != "" {
+8 -9
View File
@@ -34,12 +34,11 @@ import (
const (
// StepLabelLegacy is the legacy label name from before the introduction of the woodpecker-ci.org namespace.
// This will be removed in the future.
StepLabelLegacy = "step"
StepLabel = "woodpecker-ci.org/step"
TaskUUIDLabel = "woodpecker-ci.org/task-uuid"
podPrefix = "wp-"
defaultFSGroup int64 = 1000
initContainerImage = "busybox:stable-musl"
StepLabelLegacy = "step"
StepLabel = "woodpecker-ci.org/step"
TaskUUIDLabel = "woodpecker-ci.org/task-uuid"
podPrefix = "wp-"
defaultFSGroup int64 = 1000
)
func mkPod(step *types.Step, config *config, podName, goos string, options BackendOptions, taskUUID string) (*kube_core_v1.Pod, error) {
@@ -67,7 +66,7 @@ func mkPod(step *types.Step, config *config, podName, goos string, options Backe
}
spec.Containers = append(spec.Containers, container)
initContainer := podInitContainer(&spec, &container)
initContainer := podInitContainer(config, &spec, &container)
if initContainer != nil {
spec.InitContainers = append(spec.InitContainers, *initContainer)
}
@@ -294,7 +293,7 @@ func podContainer(step *types.Step, podName, goos string, options BackendOptions
// podInitContainer determines whether an init container is required to prepare the
// main step container's working directory with the correct permissions.
// If it is required, it returns the init container spec, otherwise it returns an empty container spec.
func podInitContainer(podSpec *kube_core_v1.PodSpec, container *kube_core_v1.Container) *kube_core_v1.Container {
func podInitContainer(config *config, podSpec *kube_core_v1.PodSpec, container *kube_core_v1.Container) *kube_core_v1.Container {
// if pod is running as root, we don't need an init container to precreate the workingDir
// since kubelet already precreates it (as root:root)
if podSpec.SecurityContext == nil ||
@@ -320,7 +319,7 @@ func podInitContainer(podSpec *kube_core_v1.PodSpec, container *kube_core_v1.Con
return &kube_core_v1.Container{
Name: "init-" + container.Name,
Image: initContainerImage,
Image: config.PermissionInitImage,
ImagePullPolicy: kube_core_v1.PullAlways,
Args: []string{"mkdir", "-p", container.WorkingDir},
SecurityContext: &kube_core_v1.SecurityContext{
+2 -1
View File
@@ -1405,7 +1405,8 @@ func TestInitContainer(t *testing.T) {
WorkingDir: "/woodpecker/src/github.com/woodpecker-ci/woodpecker",
Volumes: []string{"workspace:/woodpecker/src", "other:/other"},
}, &config{
Namespace: "woodpecker",
Namespace: "woodpecker",
PermissionInitImage: "busybox:stable-musl",
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
SecurityContext: &SecurityContext{
RunAsNonRoot: newBool(true),