fix: initialize self.tok on sub-proxies to prevent AttributeError [fj4WqyCCw3C5ShR1RfB7MoBPTpkRrBFYP1uT35g3MvT] - #70073
fix: initialize self.tok on sub-proxies to prevent AttributeError [fj4WqyCCw3C5ShR1RfB7MoBPTpkRrBFYP1uT35g3MvT]#70073waterWang wants to merge 1 commit into
Conversation
Sub-proxies are constructed via ProxyMinion(proxyopts) directly in subproxy_post_master_init and never run connect_master, so self.tok is never set by the usual master-connection path. Any event path that references self.tok (e.g. _fire_master_prepare, _register_resources, _mine_send) raises AttributeError. Setting tok=None is safe because the channel layer's _package_load regenerates the token via self.auth.gen_token(b"salt") on every send, overwriting whatever value was in the load dict. Fixes saltstack#70071
twangboy
left a comment
There was a problem hiding this comment.
Let's make this against the 3008.x branch. Also, this needs a test and a changelog.
|
@twangboy already asked for this to target 3008.x with a test and a changelog back in August; this comment is not meant to relitigate that, it adds the reproduction and root-cause detail behind it, plus a suggested alternative to the current fix. I reproduced this independently on a 4-sub-proxy deltaproxy (salt 3008.2, Confirming the cause, and narrowing the trigger The
The captured traceback is: So the real consequence is narrower but more serious than "sub-proxies cannot fire events": sub-proxy resources are never registered with the master. Everything earlier in Worth noting for the issue text: I verified that pillar refresh, The PR body describes a test that is not in the diff, and there is no changelog The body says "added assertion that
The reasoning that the channel regenerates the token is correct as far as it goes: But that makes the attribute merely present, not correct, and it only holds for that one path. A suggested alternative Set a real token the same way the normal connection path does. self.deltaproxy_objs[minion_id].req_channel = (
salt.channel.client.AsyncReqChannel.factory(
sub_proxy_data["proxy_opts"], io_loop=self.io_loop
)
)
# Mirror what connect_master() does for a normal minion.
_ch = self.deltaproxy_objs[minion_id].req_channel
if getattr(_ch, "auth", None) is not None:
self.deltaproxy_objs[minion_id].tok = _ch.auth.gen_token(b"salt")That applies at both Separately, and independent of which fix is chosen, Branch Per the guidance announced on the Salt community call, bug fixes should target 3008.x and new features target That also matches where the failure actually lives: the path I reproduced, |
|
@ggiesen Would you like to open a more comprehensive fix against 3008.x? Then we'll close this one. |
|
Heads up @waterWang -- I have opened #70228 against Your diagnosis here was correct and I have credited it in that PR. The differences are that it derives a real token from the sub-proxy's On No objection at all if you would rather take it from here -- happy to close mine in favour of an updated #70073. |
|
Closing in favor of #70228 |
What does this PR do?
Fixes #70071 — deltaproxy sub-proxies raise
AttributeError: 'ProxyMinion' object has no attribute 'tok'when dispatching events.Why?
Sub-proxies are constructed via
ProxyMinion(proxyopts)directly insubproxy_post_master_initand never runconnect_master, soself.tokis never set by the usual master-connection path. Any code path that referencesself.tok(e.g._fire_master_prepare,_register_resources,_mine_send) raisesAttributeError.Fix
Set
_proxy_minion.tok = Noneafter construction insubproxy_post_master_init. This is safe because the channel layer's_package_loadregenerates the token viaself.auth.gen_token(b"salt")on every send, overwriting whatever value was in the load dict.Tests
test_subproxy_post_master_init_packs_per_minion_grainsalready exercises the sub-proxy creation path; added assertion that_proxy_minion.tokis set (not AttributeError).New behavior
Sub-proxies can now fire events to the master without raising
AttributeError.