[Bug]: Minion skips own job when target id equals a managed resource id
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 15.7k
- Forks
- 5.6k
- Avg merge
- 2d 44m
- Merged PRs (30d)
- 80
Description
What happened?
When a publication uses a bare-id glob target that matches one of the minion's managed resource ids, Minion._is_pure_resource_target() returns True and _target_load() sets minion_is_target = False (for non-merge functions). The managing minion still accepts the job so it can run the resource path, but it does not execute the function as itself.
That is wrong when the bare id is also the minion's own id (minion_id == resource_id == tgt). In that collision case the minion job is silently dropped and only the resource job runs.
Expected behavior: when tgt equals both the minion id and a managed resource id, the minion should execute both:
- the normal minion job, and
- the resource job
(as already happens for merge functions like state.apply, where minion_is_target is forced true when resource_targets is non-empty).
Actual behavior: for ordinary functions (test.ping, grains.item, saltutil.refresh_resources, etc.) only the resource path runs. Returns look like they came from the targeted id, but they are resource-loader results (or "not supported for resource type …"), not the minion's own modules/grains.
Where
salt/minion.py:
_is_pure_resource_target()— bare-id glob branch returnsTruewhenevertgtappears inopts["resources"], with no check againstopts["id"]_target_load()— uses that verdict to clearminion_is_targetunless the function is in_MERGE_RESOURCE_FUNS
salt/cli/caller.py reuses the same helpers for salt-call -r, so the same collision semantics apply there.
Minimal reproduction
Minion config / pillar such that:
id: appliance-01
# opts["resources"] after discovery/registration:
resources:
ops:
- appliance-01
Then:
salt 'appliance-01' test.ping
salt 'appliance-01' grains.item id fqdn
salt 'appliance-01' saltutil.refresh_resources
Observed with current 3008.1 code:
| function | resource_targets |
minion_is_target |
|---|---|---|
test.ping |
[{id: appliance-01, type: ops}] |
False |
grains.item |
same | False |
saltutil.refresh_resources |
same | False |
state.apply |
same | True (merge fun) |
Only state.apply runs on the minion itself. The others run only as the resource.
Suggested fix direction
In _is_pure_resource_target, do not treat a bare-id glob as pure-resource when tgt == self.opts["id"]. That keeps resource_targets populated (so the resource job still runs) while allowing _target_load to set minion_is_target = True, yielding both executions.
Why this matters
Any deployment where a resource is keyed with the same id as its managing minion cannot reliably target that minion by id for non-merge functions. Housekeeping that is not listed in _NO_RESOURCE_FUNS (for example saltutil.refresh_resources) is swallowed by the resource path, which makes the collision self-reinforcing: the minion cannot refresh/re-key itself via the obvious target.
Type of salt install
- other (please specify in bug details) — Salt 3008.1 onedir / official packaging with Salt Resources enabled
Major version
- 3008.x (Resources feature; not listed in the issue form dropdown yet)
What supported OS are you seeing the problem on?
- photon-5
- (logic is OS-independent; reproduced against
salt/minion.pyon the 3008.1 line)
salt --versions-report output
Salt Version:
Salt: 3008.1
(Exact versions-report from the affected minion can be attached if needed; the defect is in shared minion target-routing code on the 3008.x Resources path.)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in salt/minion.py with _is_pure_resource_target() and _target_load(), then compare the behavior with salt/cli/caller.py, which reuses the helpers. Reproduce the collision using the appliance-01 resource configuration and the listed salt commands; done means the minion executes both its normal job and the resource job for ordinary functions while preserving state.apply behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- infrastructure
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100