Document how Kubernetes overwrite allow lists match values
What does this MR do?
Documents how the Kubernetes executor's *_overwrite_allowed settings match the value a job requests, and adds a test that pins it. The runner's behaviour does not change.
Four commits:
- Pin how Kubernetes overwrite allow lists match values:
TestOverwritesAllowedPatternMatchinginexecutors/kubernetes/overwrites_test.go, sixteen cases throughcreateOverwrites. An unanchored expression matches anywhere in the value, an anchored one refuses a partial match and accepts a whole one, and the label, annotation, node selector and toleration settings are matched against the whole variable value, key included. - Document how overwrite allow lists match values: in
docs/executors/kubernetes/_index.md, the settings table says that each setting is a Go regular expression that matches any part of the value unless it is anchored with^and$, and that labels, annotations and node selectors are matched askey=value. It gains the missing rows fornode_selector_overwrite_allowedandnode_tolerations_overwrite_allowed. A new section, "Regular expressions in overwrite settings", explains the matching with examples, each of the six overwrite sections that take a regular expression links to it, and the restrictive examples are anchored. The flag descriptions incommon/config.gosay the same, and the service account and pod annotations ones now name the right variables. - Link the overwrite expressions section instead of repeating it: applies the five suggestions from the documentation review. The steps to overwrite pod tolerations, pod labels, pod annotations and the node selector, and the namespace section, now link to the new section instead of repeating how the expressions match.
- Reword the backslash note and drop a restated matching rule: applies the two suggestions from the second review. The sentence on expressions that contain a backslash now opens with the condition, and the service account section no longer restates how the expression matches before its anchored example.
Why was this MR needed?
#40156 (closed) has the details. The runner accepts a value when MatchString finds the expression anywhere in it, and for the map overwrites it checks the whole key=value string, but the page did not say so, and its examples (ci-.* after "To use only designated namespaces", kubernetes.io/arch=.* to allow "overwrite of the architecture") read as if the expression had to match the whole value, which only an anchored expression does.
The new text also says what anchoring does not do: ^ci-.*$ still allows every namespace whose name starts with ci-, so where only specific namespaces should be used it points to listing their names or to namespace_per_job.
The anchored node selector example is a TOML literal string, '^kubernetes\.io/arch=.*$', because in a basic string the TOML library the runner uses refuses \. as an invalid escape. I checked that by decoding every *_overwrite_allowed line in the page's code blocks into common.Config.
This MR leaves the code as it is, because matching the whole value would change what existing configurations accept. #40168 (closed) proposes doing it behind a feature flag that keeps the current behaviour as the default. gitlab!263433 (merged) proposes anchoring the service account example in the Buildah rootless tutorial.
What's the best way to test this MR?
go test ./executors/kubernetes/ -count=1 -v -run 'TestOverwritesAllowedPatternMatching'The test pins existing behaviour, so it passes on main (6ce74c08) as well as on this branch. To check that it catches a change, I ran it against two modified copies of overwrites.go: with the expression anchored in overwriteRegexCheck, the four unanchored cases fail, and with the map overwrites checking only the key, seven cases fail. With the anchored copy the rest of the package's unit tests still pass, so no other test pinned the matching.
I also ran go build ./..., go test -race ./executors/kubernetes/, go vet of the package with and without -tags 'integration kubernetes', and make lint in the runner-linters:2.12.2-go1.26.5 image the go:lint job uses (0 issues.), with Go 1.26.5. For the docs, I ran the commands make lint-docs VALE_MIN_ALERT_LEVEL=error runs (Vale, markdownlint-cli2, lychee with fragments) in the image the docs:lint markdown job uses, all clean. Vale at its default level reports nothing on the lines this MR adds, and one alert fewer on the page than before.
Test output (excerpt)
On this branch, five of the sixteen passing cases:
--- PASS: TestOverwritesAllowedPatternMatching (0.00s)
--- PASS: TestOverwritesAllowedPatternMatching/namespace_pattern_matches_anywhere_in_the_value (0.00s)
--- PASS: TestOverwritesAllowedPatternMatching/anchored_namespace_pattern_refuses_a_value_it_matches_only_in_part (0.00s)
--- PASS: TestOverwritesAllowedPatternMatching/node_selector_pattern_matches_anywhere_in_key=value (0.00s)
--- PASS: TestOverwritesAllowedPatternMatching/pod_label_pattern_is_matched_against_key=value,_not_the_key_alone (0.00s)
--- PASS: TestOverwritesAllowedPatternMatching/node_toleration_pattern_is_matched_against_key=value:effect (0.00s)
ok gitlab.com/gitlab-org/gitlab-runner/executors/kubernetes 0.019sWith regexp.Compile("^(?:" + regex + ")$") in overwriteRegexCheck, the four cases that fail:
--- FAIL: TestOverwritesAllowedPatternMatching/namespace_pattern_matches_anywhere_in_the_value (0.00s)
--- FAIL: TestOverwritesAllowedPatternMatching/service_account_pattern_matches_anywhere_in_the_value (0.00s)
--- FAIL: TestOverwritesAllowedPatternMatching/node_selector_pattern_matches_anywhere_in_key=value (0.00s)
--- FAIL: TestOverwritesAllowedPatternMatching/pod_annotation_pattern_can_match_in_the_value_part (0.00s)Environment: Linux amd64, golang:1.26.5 (the version in go.mod).
What are the relevant issue numbers?
Closes #40156 (closed)