diff --git a/changelogs/fragments/75165-fix-role-dep-chain.yaml b/changelogs/fragments/75165-fix-role-dep-chain.yaml new file mode 100644 index 00000000000..c52c0111e0e --- /dev/null +++ b/changelogs/fragments/75165-fix-role-dep-chain.yaml @@ -0,0 +1,4 @@ +bugfixes: + - include_role - Only inherit from role parents in the current task dependency chain (https://github.com/ansible/ansible/issues/39543). + - include_role - Inherit from role parents beyond a depth of 3 (https://github.com/ansible/ansible/issues/47023). + - include_role - Inherit from role parents in the order of the task dependency chain. diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py index c6227031ca7..9b493d9df96 100644 --- a/lib/ansible/playbook/role_include.py +++ b/lib/ansible/playbook/role_include.py @@ -100,11 +100,7 @@ class IncludeRole(TaskInclude): # compile role with parent roles as dependencies to ensure they inherit # variables - if not self._parent_role: - dep_chain = [] - else: - dep_chain = list(self._parent_role._parents) - dep_chain.append(self._parent_role) + dep_chain = self.get_dep_chain() or [] p_block = self.build_parent_block() diff --git a/test/integration/targets/roles/39543.yml b/test/integration/targets/roles/39543.yml new file mode 100644 index 00000000000..94e9e6c9f4c --- /dev/null +++ b/test/integration/targets/roles/39543.yml @@ -0,0 +1,7 @@ +--- +- hosts: all + gather_facts: no + roles: + - 39543_role1 + - role: 39543_role3 + when: false diff --git a/test/integration/targets/roles/47023.yml b/test/integration/targets/roles/47023.yml new file mode 100644 index 00000000000..6b41b52f52e --- /dev/null +++ b/test/integration/targets/roles/47023.yml @@ -0,0 +1,5 @@ +--- +- hosts: all + gather_facts: no + tasks: + - include_role: name=47023_role1 diff --git a/test/integration/targets/roles/roles/39543_role1/tasks/main.yml b/test/integration/targets/roles/roles/39543_role1/tasks/main.yml new file mode 100644 index 00000000000..67c50ebedb7 --- /dev/null +++ b/test/integration/targets/roles/roles/39543_role1/tasks/main.yml @@ -0,0 +1,5 @@ +- debug: + msg: 'role1' + +- include_role: + name: 39543_role2 diff --git a/test/integration/targets/roles/roles/39543_role2/tasks/main.yml b/test/integration/targets/roles/roles/39543_role2/tasks/main.yml new file mode 100644 index 00000000000..4870224356d --- /dev/null +++ b/test/integration/targets/roles/roles/39543_role2/tasks/main.yml @@ -0,0 +1,2 @@ +- debug: + msg: 'role2' diff --git a/test/integration/targets/roles/roles/39543_role3/meta/main.yml b/test/integration/targets/roles/roles/39543_role3/meta/main.yml new file mode 100644 index 00000000000..3980a3e5fc6 --- /dev/null +++ b/test/integration/targets/roles/roles/39543_role3/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - 39543_role1 diff --git a/test/integration/targets/roles/roles/39543_role3/tasks/main.yml b/test/integration/targets/roles/roles/39543_role3/tasks/main.yml new file mode 100644 index 00000000000..550f9972bc3 --- /dev/null +++ b/test/integration/targets/roles/roles/39543_role3/tasks/main.yml @@ -0,0 +1,2 @@ +- debug: + msg: 'role3' diff --git a/test/integration/targets/roles/roles/47023_role1/defaults/main.yml b/test/integration/targets/roles/roles/47023_role1/defaults/main.yml new file mode 100644 index 00000000000..166caa33b30 --- /dev/null +++ b/test/integration/targets/roles/roles/47023_role1/defaults/main.yml @@ -0,0 +1 @@ +my_default: defined diff --git a/test/integration/targets/roles/roles/47023_role1/tasks/main.yml b/test/integration/targets/roles/roles/47023_role1/tasks/main.yml new file mode 100644 index 00000000000..9c408ba2edd --- /dev/null +++ b/test/integration/targets/roles/roles/47023_role1/tasks/main.yml @@ -0,0 +1 @@ +- include_role: name=47023_role2 diff --git a/test/integration/targets/roles/roles/47023_role1/vars/main.yml b/test/integration/targets/roles/roles/47023_role1/vars/main.yml new file mode 100644 index 00000000000..bfda56b9b80 --- /dev/null +++ b/test/integration/targets/roles/roles/47023_role1/vars/main.yml @@ -0,0 +1 @@ +my_var: defined diff --git a/test/integration/targets/roles/roles/47023_role2/tasks/main.yml b/test/integration/targets/roles/roles/47023_role2/tasks/main.yml new file mode 100644 index 00000000000..4544215f84a --- /dev/null +++ b/test/integration/targets/roles/roles/47023_role2/tasks/main.yml @@ -0,0 +1 @@ +- include_role: name=47023_role3 diff --git a/test/integration/targets/roles/roles/47023_role3/tasks/main.yml b/test/integration/targets/roles/roles/47023_role3/tasks/main.yml new file mode 100644 index 00000000000..9479fe3f3d8 --- /dev/null +++ b/test/integration/targets/roles/roles/47023_role3/tasks/main.yml @@ -0,0 +1 @@ +- include_role: name=47023_role4 diff --git a/test/integration/targets/roles/roles/47023_role4/tasks/main.yml b/test/integration/targets/roles/roles/47023_role4/tasks/main.yml new file mode 100644 index 00000000000..64c96e97dd6 --- /dev/null +++ b/test/integration/targets/roles/roles/47023_role4/tasks/main.yml @@ -0,0 +1,5 @@ +- debug: + msg: "Var is {{ my_var | default('undefined') }}" + +- debug: + msg: "Default is {{ my_default | default('undefined') }}" diff --git a/test/integration/targets/roles/runme.sh b/test/integration/targets/roles/runme.sh index 5f11c1fca61..edc13e0a6bb 100755 --- a/test/integration/targets/roles/runme.sh +++ b/test/integration/targets/roles/runme.sh @@ -17,3 +17,14 @@ set -eux # ensure role data is merged correctly ansible-playbook data_integrity.yml -i ../../inventory "$@" + + +# ensure role vars are inherited correctly +ANSIBLE_PRIVATE_ROLE_VARS=True ansible-playbook 39543.yml -i ../../inventory "$@" | tee out.txt +test "$(grep '"msg": "role1"' -c out.txt)" = "1" +test "$(grep '"msg": "role2"' -c out.txt)" = "1" +test "$(grep '"msg": "role3"' -c out.txt)" = "0" + + +# test nested includes get parent roles greater than a depth of 3 +[ "$(ansible-playbook 47023.yml -i ../../inventory "$@" | grep '\<\(Default\|Var\)\>' | grep -c 'is defined')" = "2" ]