Allow watching states to opt-in to mod_watch when normal run had changes#68960
Allow watching states to opt-in to mod_watch when normal run had changes#68960mitar wants to merge 3 commits intosaltstack:masterfrom
Conversation
| @@ -0,0 +1 @@ | |||
| Invoke ``mod_watch`` when a watched state reports changes even if the watching state's own normal run already produced unrelated changes, merging both results instead of silently dropping the watched-state trigger. | |||
There was a problem hiding this comment.
This change breaks backwards compatibility so should probably have some kind of option to trigger the behavior and not be enabled by default until a future release. I think this falls in line similar to a deprecation https://docs.saltproject.io/en/latest/topics/development/deprecations.html
There was a problem hiding this comment.
Do you have some suggestion what and where would be this flag? A top-level config flag?
|
oh hell no. This is NOT the change that should happen. the whole idea of mod_watch is that it runs the changes of a module once. this will give a way that it can do it twice. this is break a whole lot of things through out all of salt. this kind of change has extreme changes throughout ALL of salt. you don't wag the dog to wag the tail. |
|
This tries to fix the issue that just because some unrelated and uncontrollable change happens, watch does not trigger. It is not that salt states are badly defined. Documentation clearly states:
But what if "this good idea" is not possible? What is then the solution? The issue is that any more complex state (like container_running) can have some hidden changes you cannot really split. BTW, this change does not break any tests really. So I am not sure about "this is break a whole lot of things through out all of salt". |
This is the problem with the youth today. just because tests do not break does not mean it is the correct answer. changing the behavior of something that is used by the WAY more then your one use case. in a fundamental way. your own test proves why you shouldn't always trust that not breaking tests is the correct answer. you test one very limited way it is working. however i can do things with your change you are not accounting for. such as cmd.run. which is not indomitable. currently because it is always going to have a changes line it is not going to trigger the mod_watch. some people do not know this. so try using watch with cmd.run. and it sort of works. the mod_watch will never trigger for them. but the command will still always run once. however with your change that once becomes twice. and with cmd.run that can be a huge change in things going on. including damaging systems. |
|
Yes, I think we agree that it should be opt-in probably, even just for backwards compatibility sake. I also understand that this is maybe too lenient as you describe. Maybe there is some additional way to keep track what has run and prevent double running. But not running at all, just because something else has changed, I think this has more side effects than maybe it was initially planned. Is my understanding correct that this was done primarily to prevent double running? Is there really no other way to prevent double running? |
|
@bdrx312 @whytewolf I think I addressed both of your concerns. Now there is an opt-in mechanism for state to signal that mod watch should regardless because changes have not subsumed the mod watch action. In my local Salt version I for example modified docker_container state to set I think this addresses my issue and also allows for other states to implement this feature as suitable. |
|
In fact, this change also fixes the "surprising" behavior documented called out in documentation about Because surprising behavior leads to bugs, I think this fix to |
What does this PR do?
Adds an opt-in mechanism so a watching state whose normal run produced changes can still have its
mod_watchinvoked, when those changes do not subsume the work thatmod_watchwould do. The normal run's return may setforce_mod_watch: Trueto request this. The changes and comment frommod_watchare then merged into the normal run's result so neither set is lost, and the combinedresultis the AND of the two.The default behavior is unchanged: if the normal run reports changes and does not opt in,
mod_watchis still skipped, so non-idempotent watchers (such ascmd.run, whosemod_watchsimply re-invokes the main action) are not executed twice per state apply.The
status == "change"branch inState.call_chunk(salt/state.py)now reads:
The
force_mod_watchkey is popped from the return so it does not leak into the final serialized state result.What issues does this PR fix or reference?
Fixes #68958.
Previous Behavior
If the watching state's normal run produced any changes, Salt skipped calling
mod_watch, even when a watched state reported changes. The watched-state trigger was silently dropped. A common way this surfaces is withdocker_container.running: when adocker_network.presentit depends on gets recreated in the same highstate, the normal run ofdocker_container.runningperforms a network reconnect (reporting changes), which then preventedmod_watchfrom firing to force-replace the container for a watched config-file change. The state still appeared asChangedin the output, so the missing restart was invisible.There is not always a workaround like splitting
service.enabledandservice.runninginto separate states, as reported in #68958.New Behavior
A watching state may return
force_mod_watch: Truefrom its normal run to signal that its changes do not subsume whatmod_watchwould do. When that flag is set (andskip_watchis not set),mod_watchis invoked inaddition to the normal run, and the
changesandcommentfrommod_watchare merged into the normal run's result. The combinedresultisTrueonly if both succeeded.The previous default is preserved: when the normal run had changes and does not opt in,
mod_watchis skipped. When the normal run had no changes andskip_watchis not set,mod_watchis called and its return replaces the normal run's, exactly as before.Setting
force_mod_watchis only meaningful for state modules whosemod_watchperforms work orthogonal to the normal run. For example,docker_container.running'smod_watchforces a container rebuild that is not performed by a network-only reconcile. For non-idempotent watchers likecmd.run, the module should not opt in, and the default skip behavior continues to protect against double execution.Merge requirements satisfied?
force_mod_watchopt-in)Commits signed with GPG?
No