Prevent duplicate role insertion into roles: (#50552)
* Corner case in which import_role would add another instance of a role with the same signature into roles: when it already existed there. roles: - name: a tasks: - import_role: name=a would execute role 'a' 3 times instead of the intended 2 (x2 in roles: phase +1 in tasks:) * added tests
This commit is contained in:
parent
e89fb35843
commit
eca7c3c8c7
11 changed files with 64 additions and 0 deletions
2
changelogs/fragments/fix_ir_dupes.yml
Normal file
2
changelogs/fragments/fix_ir_dupes.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
bugfixes:
|
||||
- prevent import_role from inserting dupe into `roles:` execution when duplicate signature role already exists in the section.
|
|
@ -149,6 +149,9 @@ class Role(Base, Become, Conditional, Taggable):
|
|||
params['from_files'] = from_files
|
||||
if role_include.vars:
|
||||
params['vars'] = role_include.vars
|
||||
|
||||
params['from_include'] = from_include
|
||||
|
||||
hashed_params = hash_params(params)
|
||||
if role_include.role in play.ROLE_CACHE:
|
||||
for (entry, role_obj) in iteritems(play.ROLE_CACHE[role_include.role]):
|
||||
|
|
1
test/integration/targets/roles/aliases
Normal file
1
test/integration/targets/roles/aliases
Normal file
|
@ -0,0 +1 @@
|
|||
shippable/posix/group3
|
18
test/integration/targets/roles/allowed_dupes.yml
Normal file
18
test/integration/targets/roles/allowed_dupes.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
- name: test that import_role adds one (just one) execution of the role
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
tags: ['importrole']
|
||||
roles:
|
||||
- name: a
|
||||
tasks:
|
||||
- name: import role ignores dupe rule
|
||||
import_role: name=a
|
||||
|
||||
- name: test that include_role adds one (just one) execution of the role
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
tags: ['includerole']
|
||||
roles:
|
||||
- name: a
|
||||
tasks:
|
||||
- include_role: name=a
|
19
test/integration/targets/roles/no_dupes.yml
Normal file
19
test/integration/targets/roles/no_dupes.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
- name: play should only show 1 invocation of a, as dependencies in this play are deduped
|
||||
hosts: testhost
|
||||
gather_facts: false
|
||||
tags: [ 'inroles' ]
|
||||
roles:
|
||||
- role: a
|
||||
- role: b
|
||||
- role: c
|
||||
|
||||
- name: play should only show 1 invocation of a, as dependencies in this play are deduped even outside of roles
|
||||
hosts: testhost
|
||||
gather_facts: false
|
||||
tags: [ 'acrossroles' ]
|
||||
roles:
|
||||
- role: a
|
||||
- role: b
|
||||
tasks:
|
||||
- name: execute role c which depends on a
|
||||
import_role: name=c
|
1
test/integration/targets/roles/roles/a/tasks/main.yml
Normal file
1
test/integration/targets/roles/roles/a/tasks/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
- debug: msg=A
|
2
test/integration/targets/roles/roles/b/meta/main.yml
Normal file
2
test/integration/targets/roles/roles/b/meta/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
dependencies:
|
||||
- name: a
|
1
test/integration/targets/roles/roles/b/tasks/main.yml
Normal file
1
test/integration/targets/roles/roles/b/tasks/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
- debug: msg=B
|
2
test/integration/targets/roles/roles/c/meta/main.yml
Normal file
2
test/integration/targets/roles/roles/c/meta/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
dependencies:
|
||||
- name: a
|
1
test/integration/targets/roles/roles/c/tasks/main.yml
Normal file
1
test/integration/targets/roles/roles/c/tasks/main.yml
Normal file
|
@ -0,0 +1 @@
|
|||
- debug: msg=C
|
14
test/integration/targets/roles/runme.sh
Executable file
14
test/integration/targets/roles/runme.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eux
|
||||
|
||||
# test no dupes when dependencies in b and c point to a in roles:
|
||||
[ "$(ansible-playbook no_dupes.yml -i ../../inventory --tags inroles "$@" | grep -c '"msg": "A"')" = "1" ]
|
||||
[ "$(ansible-playbook no_dupes.yml -i ../../inventory --tags acrossroles "$@" | grep -c '"msg": "A"')" = "1" ]
|
||||
|
||||
# but still dupe across plays
|
||||
[ "$(ansible-playbook no_dupes.yml -i ../../inventory "$@" | grep -c '"msg": "A"')" = "2" ]
|
||||
|
||||
# include/import can execute another instance of role
|
||||
[ "$(ansible-playbook allowed_dupes.yml -i ../../inventory --tags importrole "$@" | grep -c '"msg": "A"')" = "2" ]
|
||||
[ "$(ansible-playbook allowed_dupes.yml -i ../../inventory --tags includerole "$@" | grep -c '"msg": "A"')" = "2" ]
|
Loading…
Reference in a new issue