Describe the bug
AESFuncs._register_resources in salt/master.py writes resource grains into the
resource_grains cache bank when minion_data_cache is enabled, but it never fires a
minion_data_cache_events notification on the Salt event bus.
The _pillar handler — which writes ordinary minion grains — does fire such a
notification:
# salt/master.py – AESFuncs._pillar (existing, correct behaviour)
if self.opts.get("minion_data_cache", False):
self.masterapi.cache.store("grains", load["id"], load["grains"])
if self.opts.get("minion_data_cache_events") is True:
self.event.fire_event(
{"Minion data cache refresh": load["id"]},
tagify(load["id"], "refresh", "minion"),
)
_register_resources mirrors the same cache-write pattern but omits the event entirely:
# salt/master.py – AESFuncs._register_resources (missing notification)
if self.opts.get("minion_data_cache", False):
# ... cache.store(RESOURCE_GRAINS_BANK, srn, gdict) ...
# ← no fire_event here
return True
Impact
Any downstream consumer that subscribes to cache-refresh events on the Salt event bus
(e.g. external cache managers, SSE/RaaS sseape master modules that watch
salt/minion/*/refresh/minion to sync minion grains externally) receives no signal
when a minion's resource inventory changes via _register_resources.
Resources therefore never propagate to external caches automatically. They only appear
if the consumer polls the master directly or if a manual refresh is forced.
This breaks the symmetry users expect: resource grains should behave identically to
minion grains with respect to the event bus.
Expected behaviour
When minion_data_cache: True and minion_data_cache_events: True, after a minion
sends a cmd: _register_resources payload, the master should fire an event at tag:
salt/minion/<minion_id>/refresh/resource
with payload {"Resource cache refresh": "<minion_id>"}.
Proposed fix
Add the parallel fire_event call inside the minion_data_cache block in
AESFuncs._register_resources, after the grains are written to the cache bank:
if self.opts.get("minion_data_cache", False):
resource_grains = load.get("resource_grains") or {}
try:
# ... existing cache flush/store logic (unchanged) ...
except Exception as exc:
log.warning(
"Failed to persist resource_grains for minion '%s': %s",
load["id"], exc,
)
# Mirror the notification that _pillar fires for ordinary minion grains.
if self.opts.get("minion_data_cache_events") is True:
self.event.fire_event(
{"Resource cache refresh": load["id"]},
tagify(load["id"], "refresh", "resource"),
)
return True
Steps to reproduce
- Configure master with
minion_data_cache: True and minion_data_cache_events: True.
- Start a minion that reports resources (e.g. run
salt <minion> saltutil.refresh_resources).
- Subscribe to
salt/minion/*/refresh/resource on the event bus — no event arrives.
- Subscribe to
salt/minion/*/refresh/minion — events arrive correctly for grain refreshes.
Versions
- Salt: 3008.0 /
declarative-resources feature branch
- Platform: Linux (Photon 5 / Kubernetes pod)
- Requesting backport to 3008.x
Describe the bug
AESFuncs._register_resourcesinsalt/master.pywrites resource grains into theresource_grainscache bank whenminion_data_cacheis enabled, but it never fires aminion_data_cache_eventsnotification on the Salt event bus.The
_pillarhandler — which writes ordinary minion grains — does fire such anotification:
_register_resourcesmirrors the same cache-write pattern but omits the event entirely:Impact
Any downstream consumer that subscribes to cache-refresh events on the Salt event bus
(e.g. external cache managers, SSE/RaaS
sseapemaster modules that watchsalt/minion/*/refresh/minionto sync minion grains externally) receives no signalwhen a minion's resource inventory changes via
_register_resources.Resources therefore never propagate to external caches automatically. They only appear
if the consumer polls the master directly or if a manual refresh is forced.
This breaks the symmetry users expect: resource grains should behave identically to
minion grains with respect to the event bus.
Expected behaviour
When
minion_data_cache: Trueandminion_data_cache_events: True, after a minionsends a
cmd: _register_resourcespayload, the master should fire an event at tag:with payload
{"Resource cache refresh": "<minion_id>"}.Proposed fix
Add the parallel
fire_eventcall inside theminion_data_cacheblock inAESFuncs._register_resources, after the grains are written to the cache bank:Steps to reproduce
minion_data_cache: Trueandminion_data_cache_events: True.salt <minion> saltutil.refresh_resources).salt/minion/*/refresh/resourceon the event bus — no event arrives.salt/minion/*/refresh/minion— events arrive correctly for grain refreshes.Versions
declarative-resourcesfeature branch