fix: kubernetes namespace configuration precedence
Why
When spec.namespace is omitted, the operator currently falls back to the namespace of the Runner custom resource and always injects it as KUBERNETES_NAMESPACE into the runner manager pod.
KUBERNETES_NAMESPACE is consumed by GitLab Runner registration as the Kubernetes executor namespace. Registration environment values take precedence over values supplied by the configuration template, so this implicit fallback prevents a namespace configured in config.toml / TEMPLATE_CONFIG_FILE from taking effect.
The namespace containing the Runner resource and the namespace used for Kubernetes executor job pods are separate concerns. Omitting spec.namespace should therefore mean that the operator does not explicitly configure the executor namespace.
Closes #229 (closed)
Changes
- Remove the fallback from
spec.namespacetometadata.namespacewhen constructing runner environment variables. - Add
KUBERNETES_NAMESPACEonly whenspec.namespaceis explicitly configured. - Keep the existing behavior unchanged when
spec.namespacehas a value. - Update the existing namespace unit test to assert that
KUBERNETES_NAMESPACEis absent whenspec.namespaceis omitted.
Behavior
With an explicit namespace:
spec:
namespace: build-namespaceThe operator continues to set:
KUBERNETES_NAMESPACE=build-namespaceWhen spec.namespace is omitted, the operator no longer sets KUBERNETES_NAMESPACE. This leaves the Kubernetes executor namespace unset by the operator, allowing GitLab Runner's normal configuration/template precedence to apply, including a namespace configured through the custom runner configuration.
Why this approach
The fix is intentionally applied at the point where the operator introduces the conflicting value. It does not add special handling for custom configuration and does not change GitLab Runner's registration semantics.
Setting KUBERNETES_NAMESPACE to an empty string would still make the operator participate in Runner configuration and would depend on Runner's treatment of empty environment values. Omitting the variable when spec.namespace is unspecified preserves the distinction between an explicitly configured value and an unspecified value.
This also keeps spec.namespace authoritative when users opt into it: an explicitly configured value is still passed through registration and therefore retains precedence over the configuration template.
Scope
The change is limited to environment construction and its existing unit coverage. It does not change the Runner CRD, defaults, registration scripts, or configuration-template handling.
Testing
The existing TestGetEnvironmentVariables coverage now verifies both sides of the contract:
- explicit
spec.namespaceproducesKUBERNETES_NAMESPACEwith that value; - omitted
spec.namespacedoes not produceKUBERNETES_NAMESPACE.
The branch pipeline is also used to run the project's normal CI checks.