From 88c87a35834f4947ca705e685baa11c10a805373 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 18 Dec 2018 11:28:24 -0500 Subject: [PATCH] added handlers_from (#49220) * added handlers_from fixes #46769 --- changelogs/fragments/from_handlers.yml | 2 + .../modules/utilities/logic/import_role.py | 5 +++ .../modules/utilities/logic/include_role.py | 5 +++ lib/ansible/playbook/role/__init__.py | 2 +- lib/ansible/playbook/role_include.py | 2 +- .../targets/handlers/from_handlers.yml | 41 +++++++++++++++++++ .../test_handlers_meta/handlers/alternate.yml | 12 ++++++ test/integration/targets/handlers/runme.sh | 5 +++ 8 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/from_handlers.yml create mode 100644 test/integration/targets/handlers/from_handlers.yml create mode 100644 test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml diff --git a/changelogs/fragments/from_handlers.yml b/changelogs/fragments/from_handlers.yml new file mode 100644 index 00000000000..7de752cb29a --- /dev/null +++ b/changelogs/fragments/from_handlers.yml @@ -0,0 +1,2 @@ +minor_changes: + - add from_handlers option to include_role/import_role diff --git a/lib/ansible/modules/utilities/logic/import_role.py b/lib/ansible/modules/utilities/logic/import_role.py index 148e7ad1543..7ca1bd01c82 100644 --- a/lib/ansible/modules/utilities/logic/import_role.py +++ b/lib/ansible/modules/utilities/logic/import_role.py @@ -48,6 +48,11 @@ options: - Overrides the role's metadata setting to allow using a role more than once with the same parameters. type: bool default: 'yes' + handlers_from: + description: + - File to load from a role's C(handlers/) directory. + default: main + version_added: '2.8' notes: - Handlers are made available to the whole play. - "Since Ansible 2.7: variables defined in C(vars) and C(defaults) for the role are exposed at playbook parsing time. diff --git a/lib/ansible/modules/utilities/logic/include_role.py b/lib/ansible/modules/utilities/logic/include_role.py index 107cd231a84..9f961b456cd 100644 --- a/lib/ansible/modules/utilities/logic/include_role.py +++ b/lib/ansible/modules/utilities/logic/include_role.py @@ -61,6 +61,11 @@ options: type: bool default: 'no' version_added: '2.7' + handlers_from: + description: + - File to load from a role's C(handlers/) directory. + default: main + version_added: '2.8' notes: - Handlers are made available to the whole play. - Before Ansible 2.4, as with C(include), this task could be static or dynamic, If static, it implied that it won't diff --git a/lib/ansible/playbook/role/__init__.py b/lib/ansible/playbook/role/__init__.py index 8475fecbfcf..b32e26b100f 100644 --- a/lib/ansible/playbook/role/__init__.py +++ b/lib/ansible/playbook/role/__init__.py @@ -230,7 +230,7 @@ class Role(Base, Become, Conditional, Taggable): raise AnsibleParserError("The tasks/main.yml file for role '%s' must contain a list of tasks" % self._role_name, obj=task_data, orig_exc=e) - handler_data = self._load_role_yaml('handlers') + handler_data = self._load_role_yaml('handlers', main=self._from_files.get('handlers')) if handler_data: try: self._handler_blocks = load_list_of_blocks(handler_data, play=self._play, role=self, use_handlers=True, loader=self._loader, diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py index c84342a2fc6..e63c4ac537e 100644 --- a/lib/ansible/playbook/role_include.py +++ b/lib/ansible/playbook/role_include.py @@ -41,7 +41,7 @@ class IncludeRole(TaskInclude): """ BASE = ('name', 'role') # directly assigned - FROM_ARGS = ('tasks_from', 'vars_from', 'defaults_from') # used to populate from dict in role + FROM_ARGS = ('tasks_from', 'vars_from', 'defaults_from', 'handlers_from') # used to populate from dict in role OTHER_ARGS = ('apply', 'public', 'allow_duplicates') # assigned to matching property VALID_ARGS = tuple(frozenset(BASE + FROM_ARGS + OTHER_ARGS)) # all valid args diff --git a/test/integration/targets/handlers/from_handlers.yml b/test/integration/targets/handlers/from_handlers.yml new file mode 100644 index 00000000000..d5a202c84e0 --- /dev/null +++ b/test/integration/targets/handlers/from_handlers.yml @@ -0,0 +1,41 @@ +- name: verify handlers_from on include_role + hosts: A + gather_facts: False + connection: local + tags: ['scenario1'] + tasks: + - name: test include_role + include_role: name=test_handlers_meta handlers_from=alternate.yml + + - name: force handler run + meta: flush_handlers + + - name: verify handlers ran + assert: + that: + - "'handler1_alt_called' in hostvars[inventory_hostname]" + - "'handler2_alt_called' in hostvars[inventory_hostname]" + tags: ['scenario1'] + + +- name: verify handlers_from on import_role + hosts: A + gather_facts: False + connection: local + tasks: + - name: set facts to false + set_fact: + handler1_alt_called: False + handler2_alt_called: False + + - import_role: name=test_handlers_meta handlers_from=alternate.yml + + - name: force handler run + meta: flush_handlers + + - name: verify handlers ran + assert: + that: + - handler1_alt_called|bool + - handler2_alt_called|bool + tags: ['scenario1'] diff --git a/test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml new file mode 100644 index 00000000000..9268ce513c0 --- /dev/null +++ b/test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml @@ -0,0 +1,12 @@ +- name: set_handler_fact_1 + set_fact: + handler1_called: True + handler1_alt_called: True + +- name: set_handler_fact_2 + set_fact: + handler2_called: True + handler2_alt_called: True + +- name: count_handler + shell: echo . >> {{ handler_countpath }} diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh index df544052a59..0076bc37885 100755 --- a/test/integration/targets/handlers/runme.sh +++ b/test/integration/targets/handlers/runme.sh @@ -2,7 +2,12 @@ set -eux +# simple handler test ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario1 + +# simple from_handlers test +ansible-playbook from_handlers.yml -i inventory.handlers -v "$@" --tags scenario1 + ansible-playbook test_listening_handlers.yml -i inventory.handlers -v "$@" [ "$(ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario2 -l A \