Skip to content

fix(deploy): run kubectl plugins only through kubectl - #409

Merged
alexey-igrychev merged 2 commits into
deckhouse:2from
yalosev:fix/deploy/kubectl-plugin-lookup-v2
Oct 7, 2026
Merged

alexey-igrychev merged 2 commits into
deckhouse:2from
yalosev:fix/deploy/kubectl-plugin-lookup-v2

Conversation

@yalosev

@yalosev yalosev commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Backport of #408 to 2. With kubectl-argo-rollouts on PATH, werf kubectl argo rollouts get rollout demo now runs the plugin with get rollout demo. Commands outside werf kubectl no longer execute kubectl plugins while constructing the command tree.

What

  • Standalone plugin lookup removes the kubectl command prefix and preserves plugin arguments.
  • With WERF_SELF_INVOCATION_COMMAND=dk, the embedding invocation d8 dk kubectl argo rollouts get runs kubectl-argo-rollouts get; commands outside that path do not trigger lookup.
  • Built-in kubectl commands retain precedence over plugins.
  • The bundled kubectl v0.29.3 retains exact plugin lookup under create: werf kubectl create hello can run kubectl-create-hello, but create hello demo looks for kubectl-create-hello-demo instead of passing demo to the shorter plugin name.

Why

Kubectl expects the binary name followed by its own command arguments, but werf passed its entire argument vector. The extra command prefix prevented intended plugin lookup, while eager command construction could execute a plugin for an unrelated werf command.

…n other commands

`werf kubectl` passed the whole werf argv to kubectl's plugin lookup.
kubectl builds the plugin name from every word after the binary, so the
lookup searched PATH for kubectl-kubectl-<name> and `werf kubectl argo
rollouts` never found kubectl-argo-rollouts. The lookup also runs while
the command tree is built, on every werf invocation, so `werf <name>`
executed a kubectl-<name> binary from PATH instead of the werf command.

Pass the lookup only the arguments after the kubectl command path,
including the WERF_SELF_INVOCATION_COMMAND prefix of an embedding binary
such as `d8 dk kubectl`. Any other command passes no arguments, which
disables the lookup.

Signed-off-by: Yuriy Losev <yuriy.losev@flant.com>
Exercise NewCmd in subprocesses with isolated plugin executables so reverting its argument wiring fails regression tests. Preserve the v2 kubectl exact-name lookup for create plugins and keep test helpers consistent with repository conventions.

Signed-off-by: Aleksei Igrychev <aleksei.igrychev@palark.com>
@alexey-igrychev alexey-igrychev changed the title fix(deploy): find kubectl plugins in werf kubectl and ignore them in other commands fix(deploy): run kubectl plugins only through kubectl Oct 7, 2026
@alexey-igrychev

Copy link
Copy Markdown
Collaborator

Review and verification at c14808b:

  • Added subprocess coverage through the production NewCmd constructor, with isolated PATH and the v2 plugin-subcommand feature gate reset to its default. All 18 kubectl cases pass.
  • Verified mutation sensitivity: bypassing argument normalization at the production call site fails 5 cases; returning the raw argument vector from the helper fails 14. Restoring the implementation passes the suite after each mutation.
  • task build, full task lint:golangci-lint:go, and full task test:unit pass (73 suites). Go formatters pass.
  • Scoped config and ci-env integration tests pass (7 + 4 cases), using the built binary.
  • Actual CLI execution confirms ordinary and embedded-prefix plugin dispatch, rejection of unrelated root commands, and the bundled kubectl v0.29.3 exact-match behavior under create.
  • Independent challenge review found no remaining actionable findings after the test fixes.

Limitations: full task format/task lint cannot complete their Docker-based Prettier step because the local Docker daemon is unavailable. The selected Docker build e2e also fails for that missing daemon; it is not reported as passing. Windows execution and the real embedding application were not exercised. External CI/environment blockers are excluded from merge gating at the maintainer's explicit request.

@alexey-igrychev
alexey-igrychev merged commit dd6d573 into deckhouse:2 Oct 7, 2026
2 checks passed
alexey-igrychev added a commit that referenced this pull request Oct 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[2.81.3-dk.1](v2.81.1-dk.1...v2.81.3-dk.1)
(2026-10-08)


### Bug Fixes

* **build, stages:** make from:scratch images usable by buildah builds
([werf#8025](https://github.com/deckhouse/delivery-kit/issues/8025))
([cbd1157](cbd1157))
* **build:** prevent intermittent Buildah initialization failures
([werf#8039](https://github.com/deckhouse/delivery-kit/issues/8039))
([5ba0d9d](5ba0d9d))
* **build:** stop rejecting initialized nested submodules
([werf#8037](https://github.com/deckhouse/delivery-kit/issues/8037))
([d139887](d139887))
* **deploy:** preserve kubectl env defaults and command syntax
([werf#8035](https://github.com/deckhouse/delivery-kit/issues/8035))
([cca9f53](cca9f53))
* **deploy:** run kubectl plugins only through kubectl
([#409](#409))
([dd6d573](dd6d573))
* **deploy:** run kubectl plugins only through kubectl
([werf#8031](https://github.com/deckhouse/delivery-kit/issues/8031))
([b860ae9](b860ae9))
* **giterminism:** preserve user worktrees in dev mode
([werf#8043](https://github.com/deckhouse/delivery-kit/issues/8043))
([dc4360b](dc4360b))
* **host-cleanup:** reclaim abandoned tmp data from older releases
([werf#8029](https://github.com/deckhouse/delivery-kit/issues/8029))
([dfc2aed](dfc2aed))


### Miscellaneous Chores

* **release:** force release 2.81.3-dk.1
([0f8f56d](0f8f56d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants