[Bug]: mine.update clear=True raises UnboundLocalError on the master and stores nothing

未关闭 适合新手
#70,622 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 3 天内回复

@cestercian 已经在做这个了。

开始于 2026年11月1日。

  • #70633 来自 @cestercian —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
74/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python
领域
backend

调研方向

该缺陷位于 salt/daemons/masterapi.py 中的 RemoteFuncs._mine():data 只在不使用 clear 的路径上赋值,但最后的 self.cache.store 调用始终使用它。请阅读该函数以及缓存读取和写入调用,然后用 salt-call mine.update clear=True 复现,并检查 salt-run cache.mine。完成标准是:clear 能删除过期条目且不出现 UnboundLocalError,clear=False 仍然合并数据,并且针对 _mine 的单元测试覆盖两条路径。

由索引模型根据 Issue 内容生成。

描述

What happened?

RemoteFuncs._mine() only assigns data when clear is false, but always stores data:

https://github.com/saltstack/salt/blob/a98db5df8f42d50f21276b88ccc3136ee70a482a/salt/daemons/masterapi.py#L737-L744

So every _mine request with clear: True (only mine.update clear=True sends one; mine.send and the __mine_interval schedule use the default clear=False) fails on the master with:

[salt.master      :3541][ERROR   ] Error in function _mine:
Traceback (most recent call last):
  File ".../salt/master.py", line 3535, in run_func
    ret = getattr(self, func)(load)
  File ".../salt/master.py", line 3646, in _sync_mine
    return self.masterapi._mine(load, skip_verify=False)
  File ".../salt/daemons/masterapi.py", line 744, in _mine
    self.cache.store(cbank, ckey, data)
UnboundLocalError: cannot access local variable 'data' where it is not associated with a value

(local variable 'data' referenced before assignment on Python 3.10.) Nothing is written, so the old mine entries stay, including ones for functions no longer in mine_functions, and the new data is dropped too. The minion doesn't notice: mine.update returns True once the _minion_mine event is fired, and Minion._mine_send()'s reply from the master is ignored.

This came in with #55760. 5525864060 stored new_data but had a new_ddata typo in the merge branch, and f1e8079486 fixed the typo by changing the store to self.cache.store(cbank, ckey, data), which isn't bound when clearing. Before that (63d8246a5c) the clear path stored load["data"]. Both commits are first in v3000.0rc1, so every release since 3000 has this.

To reproduce, master with default settings (minion_data_cache: True), minion with:

mine_functions:
  test.ping: []
  test.arg:
    - hello
salt-call mine.send stale mine_function=test.echo text=old
salt-call mine.update clear=True
salt-run cache.mine tgt=<minion id>

Expected: only test.arg and test.ping left, since clear is documented as "Specifies whether updating will clear the existing values (True), or whether it will update them (False)". Actual: stale is still there, salt-call returns True and the master logs the traceback above. salt <minion id> mine.update clear=True does the same, and salt <minion id> mine.get <minion id> stale still returns old. salt-run mine.update <minion id> clear=True doesn't hit it, but only because the runner hands clear to LocalClient.cmd() rather than to the function, so the minion runs a plain mine.update (separate bug).

Proposed fix, which is what 5525864060 was going for:

             if not load.get("clear", False):
                 data = self.cache.fetch(cbank, ckey)
                 if isinstance(data, dict):
                     data.update(new_data)
-            self.cache.store(cbank, ckey, data)
+                    new_data = data
+            self.cache.store(cbank, ckey, new_data)
         return True

With that applied to the 3008.x master the steps above leave only test.arg and test.ping and nothing is logged; clear=False still merges. There's no test for RemoteFuncs._mine today. I can send a PR against 3008.x with a unit test.

Type of salt install

other (please specify in bug details)

Major version

3006.x, 3007.x, 3008.x

What supported OS are you seeing the problem on? Can select multiple. (If bug appears on an unsupported OS, please open a GitHub Discussion instead)

rockylinux-10

salt --versions-report output
Not a package install: reproduced with salt-master and salt-minion run from
source exports of 3008.x (a98db5df8f, Python 3.14.8), 3007.x (3ee458139d,
Python 3.12.15) and 3006.x (888f452db2, Python 3.11.16) on Rocky Linux 10.2.
Same result on all three; the traceback ends at masterapi.py line 744, 743
and 729 respectively.

RemoteFuncs._mine is identical on 3008.x and master (b78fd91bfe); 3006.x and
3007.x only differ from it in the cache bank/key names.
主要语言
Python
星标
15.8k
派生
5.6k
平均合并
5 天 9 小时
30 天内合并 PR
99

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

saltstack/salt 的其他 Issue

查看 saltstack/salt 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。