Skip to content

Use target minion id for pillar-render execution modules on the master#69752

Open
ggiesen wants to merge 2 commits into
saltstack:3006.xfrom
ggiesen:fix-58407-pillar-match-id
Open

Use target minion id for pillar-render execution modules on the master#69752
ggiesen wants to merge 2 commits into
saltstack:3006.xfrom
ggiesen:fix-58407-pillar-match-id

Conversation

@ggiesen

@ggiesen ggiesen commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Loads the execution modules used during pillar compilation with self.opts (which carries the target minion_id) instead of the raw incoming opts, so salt[...] calls in pillar templates resolve against the minion the pillar is being compiled for rather than the master's own id.

What issues does this PR fix or reference?

Fixes #58407

Previous Behavior

In Pillar.__init__, when file_client == "local" the execution-module loader was built from the raw incoming opts. On the master that branch is always taken (the master's file_client is local), and those opts carry the master's id. So salt['match.compound'] used from a pillar template matched against the master's id and returned the wrong result, while salt-call match.compound on the minion (where opts['id'] is the minion's own id) returned the correct one. The sibling non-local branch already used self.opts.

New Behavior

Both branches now load the modules from self.opts, which __gen_opts stamps with the target minion_id, so pillar-render execution modules resolve against the target minion. Masterless is unaffected (there opts['id'] already equals the minion_id, so the change is a no-op).

Behavior-change note for reviewers: execution modules invoked during master-side pillar rendering now observe the target minion's id (and the target saltenv/pillarenv carried by self.opts) rather than the master's raw opts. External pillars are unchanged -- they still deliberately run with the master's id (ext_pillar_opts["id"] = opts["id"]).

Merge requirements satisfied?

  • Docs - not applicable
  • Changelog - changelog/58407.fixed.md
  • Tests written/updated - tests/pytests/unit/test_pillar.py: master-side render loads modules with the target minion_id (pins the bug), and masterless keeps its own id (no-op)

Commits signed with GPG?

No

Pillar compilation loads execution modules (for salt[...] calls in pillar
templates) with the incoming opts when file_client is "local". On the
master that branch is always taken, and the incoming opts carry the
master's id, so salt["match.compound"] and friends matched against the
master rather than the minion the pillar was being compiled for (saltstack#58407).
Load them with self.opts, which __gen_opts stamps with the target
minion_id, matching the non-local branch. Masterless is unaffected
(opts["id"] already equals the minion_id there).

Fixes saltstack#58407
@ggiesen ggiesen requested a review from a team as a code owner July 10, 2026 08:03
@charzl charzl self-assigned this Jul 10, 2026
@dwoz dwoz added the test:full Run the full test suite label Jul 10, 2026
…ted example

The saltstack#58407 fix makes execution modules called during pillar rendering
resolve against the target minion, so the documented match.filter_by
example (which omits the minion_id argument) now correctly matches the
minion and gets the db role. The parametrized expectation still asserted
the pre-fix web* roles, which contradicted the fix and failed in CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants