Last handler with same name wins for listen too (#81358)

Fixes #49371
Fixes #81013
pull/81518/head
Martin Krizek 10 months ago committed by GitHub
parent bd3ffbe109
commit 0cba3b7504
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- handlers - the ``listen`` keyword can affect only one handler with the same name, the last one defined as it is a case with the ``notify`` keyword (https://github.com/ansible/ansible/issues/81013)

@ -509,8 +509,11 @@ class StrategyBase:
def search_handlers_by_notification(self, notification: str, iterator: PlayIterator) -> t.Generator[Handler, None, None]:
templar = Templar(None)
handlers = [h for b in reversed(iterator._play.handlers) for h in b.block]
# iterate in reversed order since last handler loaded with the same name wins
for handler in (h for b in reversed(iterator._play.handlers) for h in b.block if h.name):
for handler in handlers:
if not handler.name:
continue
if not handler.cached_name:
if templar.is_template(handler.name):
templar.available_variables = self._variable_manager.get_vars(
@ -548,7 +551,8 @@ class StrategyBase:
break
templar.available_variables = {}
for handler in (h for b in iterator._play.handlers for h in b.block):
seen = []
for handler in handlers:
if listeners := handler.listen:
if notification in handler.get_validated_value(
'listen',
@ -556,6 +560,9 @@ class StrategyBase:
listeners,
templar,
):
if handler.name and handler.name in seen:
continue
seen.append(handler.name)
yield handler
@debug_closure

@ -0,0 +1,4 @@
- name: role_handler
debug:
msg: "a handler from a role"
listen: role_handler

@ -0,0 +1,3 @@
- name: a task from role1
command: echo
notify: role_handler

@ -0,0 +1,3 @@
- name: a task from role2
command: echo
notify: role_handler

@ -187,3 +187,6 @@ grep out.txt -e "ERROR! Using a block as a handler is not supported."
ansible-playbook test_include_role_handler_once.yml -i inventory.handlers "$@" 2>&1 | tee out.txt
[ "$(grep out.txt -ce 'handler ran')" = "1" ]
ansible-playbook test_listen_role_dedup.yml "$@" 2>&1 | tee out.txt
[ "$(grep out.txt -ce 'a handler from a role')" = "1" ]

@ -0,0 +1,5 @@
- hosts: localhost
gather_facts: false
roles:
- test_listen_role_dedup_role1
- test_listen_role_dedup_role2
Loading…
Cancel
Save