fix: do not set container WorkingDir on Kubernetes job pods#1
Closed
ppaslan wants to merge 12 commits intoeleboucher:mainfrom
Closed
fix: do not set container WorkingDir on Kubernetes job pods#1ppaslan wants to merge 12 commits intoeleboucher:mainfrom
ppaslan wants to merge 12 commits intoeleboucher:mainfrom
Conversation
Setting WorkingDir on the container spec causes the container runtime (containerd) to create the full workdir path as root (UID 0) before the container process starts. When the pod runs as a non-root user via securityContext.runAsUser, those root-owned directories are not writable, causing checkout to fail with "Permission denied" on git init. The WorkingDir assignment is unnecessary: all kubectl exec calls already handle the working directory explicitly via a `sh -c 'cd "$0" && exec "$@"'` wrapper, and the startK8sEnvironment setup creates the workdir path via exec inside the running container as the correct user. Removing this line allows non-root job pods to create and own their own workdir, enabling securityContext.runAsUser to work correctly.
run: steps without an explicit working-directory: pass an empty workdir to Exec(), causing CWD to be / after the container WorkingDir removal. Fall back to p.input.WorkingDir so run: steps execute in the repository checkout directory, matching standard GitHub Actions behaviour.
Author
|
@eleboucher |
There was a problem hiding this comment.
Pull request overview
This PR expands runner backend support to better handle non-Docker execution modes (notably Kubernetes), addressing permission issues that arise when Kubernetes containers run as non-root users and the runtime pre-creates WorkingDir paths as root-owned directories.
Changes:
- Extend label parsing/routing to support
k8spodand generic “plugin” schemes, and propagate these into platform selection. - Add Kubernetes backend configuration (namespace, kubeconfig, poll timeout), plumb it through runner config, and introduce a Kubernetes pod execution environment.
- Introduce a plugin backend mechanism (v1 remote gRPC + v2 go-plugin-launched binary) and integrate it into job startup/execution logic.
Reviewed changes
Copilot reviewed 47 out of 48 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| internal/pkg/labels/labels_test.go | Adds coverage for plugin-scheme parsing and platform picking. |
| internal/pkg/labels/labels_k8s_test.go | Adds tests for k8spod parsing/stringification and docker-requirement behavior. |
| internal/pkg/labels/labels.go | Adds k8spod scheme and allows plugin schemes to flow into PickPlatform. |
| internal/pkg/config/config_test.go | Updates config tests for new Kubernetes + plugin config fields and defaults. |
| internal/pkg/config/config.go | Adds Kubernetes and plugin configuration models plus YAML deserialization. |
| internal/app/run/runner_test.go | Adds tests for extracting Kubernetes podspec label mappings. |
| internal/app/run/runner.go | Plumbs Kubernetes/plugin config into act runner config; adds k8s podspec + plugin config builders. |
| go.mod | Adds dependencies for Kubernetes client functionality and go-plugin/gRPC plumbing. |
| go.sum | Updates module checksums for new dependencies. |
| examples/kubernetes/native/runner.yaml | Adds example runner configuration for the Kubernetes native backend. |
| examples/kubernetes/native/runner-rbac.yaml | Adds RBAC example required for creating/exec’ing pods. |
| examples/kubernetes/native/runner-deploy.yaml | Adds deployment + ConfigMap example bundling runner config and podspecs. |
| examples/kubernetes/native/podspec-dind.yaml | Adds example podspec for Docker-in-Docker workflows in K8s. |
| examples/kubernetes/native/podspec-default.yaml | Adds default podspec template for K8s backend usage. |
| act/runner/step_docker.go | Prevents docker:// step actions when backend doesn’t support Docker actions. |
| act/runner/runner.go | Extends runner config with Kubernetes + plugin settings. |
| act/runner/run_context_test.go | Updates service port mapping expectations and adds IsK8sEnv tests. |
| act/runner/run_context.go | Adds K8s and plugin environment startup paths; adjusts networking/toolcache behavior. |
| act/runner/job_executor.go | Network cleanup now respects backends that manage their own networking. |
| act/runner/action.go | Blocks Docker-based actions when backend doesn’t support Docker actions; adjusts networking mode selection. |
| act/plugin/v2client_test.go | Adds tests for v2 plugin client lifecycle/copy/invalid binary behavior. |
| act/plugin/v2client.go | Adds go-plugin based client for launching plugin binaries. |
| act/plugin/testplugin/server_test.go | Adds comprehensive tests for the test plugin backend server implementation. |
| act/plugin/testplugin/server.go | Implements a local test plugin backend server (gRPC). |
| act/plugin/testplugin/cmd/main.go | Adds a test plugin binary entrypoint for go-plugin handshake/serve. |
| act/plugin/proto/v1/plugin_grpc.pb.go | Adds generated gRPC bindings for backend plugin protocol. |
| act/plugin/proto/v1/plugin.proto | Defines backend plugin protocol and capabilities. |
| act/plugin/handshake.go | Adds go-plugin handshake config and plugin name constant. |
| act/plugin/grpc_plugin.go | Bridges go-plugin to the backend gRPC service implementation. |
| act/plugin/client.go | Adds v1 client for connecting to a running backend plugin server. |
| act/plugin/adapter_test.go | Adds extensive tests for the plugin adapter environment implementation. |
| act/plugin/adapter.go | Implements ExecutionsEnvironment adapter backed by the plugin gRPC protocol. |
| act/container/parse_env_file_test.go | Updates tests to use exported ParseEnvFile. |
| act/container/parse_env_file.go | Exports ParseEnvFile for reuse across backends. |
| act/container/linux_container_environment_extensions_test.go | Adds tests for new backend identity methods. |
| act/container/linux_container_environment_extensions.go | Adds backend identity/capability methods and toolcache setter. |
| act/container/kubernetes_stub.go | Adds stubbed Kubernetes backend when compiled without Kubernetes support. |
| act/container/kubernetes_run_test.go | Adds extensive unit tests for K8s pod environment behavior. |
| act/container/kubernetes_run.go | Implements Kubernetes pod execution environment (create/start/exec/copy/watch/cleanup). |
| act/container/kubernetes_job.go | Adds Kubernetes constants and constructor for K8sPod. |
| act/container/kubernetes_client.go | Adds cached Kubernetes client initialization and kubeconfig resolution. |
| act/container/host_environment_test.go | Adds tests for new backend identity behavior (host vs lxc). |
| act/container/host_environment.go | Migrates to new backend identity/capability methods; updates env parsing call. |
| act/container/executions_environment.go | Extends ExecutionsEnvironment interface with backend identity/capability flags and adds ServiceAdder. |
| act/container/docker_run.go | Adapts exposed ports/port bindings to new container input types. |
| act/container/container_types.go | Changes exposed port/port binding types to backend-agnostic structures. |
| .forgejo/workflows/build-images.yml | Adds a workflow to build and push container images. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Owner
Sorry i didn't received notification for this, good catch i will merge it on my forge |
Owner
|
Merged |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Setting WorkingDir on the container spec causes the container runtime (containerd) to create the full workdir path as root (UID 0) before the container process starts. When the pod runs as a non-root user via securityContext.runAsUser, those root-owned directories are not writable, causing checkout to fail with "Permission denied" on git init.
The WorkingDir assignment is unnecessary: all kubectl exec calls already handle the working directory explicitly via a
sh -c 'cd "$0" && exec "$@"'wrapper, and the startK8sEnvironment setup creates the workdir path via exec inside the running container as the correct user.Removing this line allows non-root job pods to create and own their own workdir, enabling securityContext.runAsUser to work correctly.