Repository: ansible/ansible

Issue:
Problem with conditional role dependencies: conditions are overwritten
##### Issue Type:

Bug Report
##### Ansible Version:

ansible 1.6.1
##### Environment:

CentOS 6 + epel + ansible from epel-testing
##### Summary:

I have a problem with conditional roles and their conditional dependencies:

testcase.yml:

```

---
# playbook for all
- hosts: all
  roles:
    - role: a
      when: false
```

roles/a/meta/main.yml:

```

---
dependencies:
  - role: b
    when: true
```

roles/a/tasks/main.yml:

```
- debug: msg="Running role a"
```

roles/b/tasks/main.yml:

```
- debug: msg="Running role b"
```
##### Steps To Reproduce:

Use above example and run it.
##### Expected Results:

all roles skipped
##### Actual Results:

```
PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [localhost]

TASK: [b | debug msg="Running role b"] **************************************** 
ok: [localhost] => {
    "item": "", 
    "msg": "Running role b"
}

TASK: [a | debug msg="Running role a"] **************************************** 
skipping: [localhost]

PLAY RECAP ******************************************************************** 
localhost : ok=2    changed=0    unreachable=0    failed=0
```



Discussion:
More of a question about conditionals of role 1 not being inserted ahead of conditionals of role 2.

I agree, this should be fixed and we need an integration test for it.

Thanks for the heads up!


Resolving patch:
diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py
--- a/lib/ansible/playbook/play.py
+++ b/lib/ansible/playbook/play.py
@@ -294,26 +294,24 @@ def __merge_tags(var_obj):
                             else:
                                 self.included_roles.append(dep)
 
+                        def _merge_conditional(cur_conditionals, new_conditionals):
+                            if isinstance(new_conditionals, (basestring, bool)):
+                                cur_conditionals.append(new_conditionals)
+                            elif isinstance(new_conditionals, list):
+                                cur_conditionals.extend(new_conditionals)
+
                         # pass along conditionals from roles to dep roles
-                        if type(role) is dict:
-                            if 'when' in passed_vars:
-                                if 'when' in dep_vars:
-                                    tmpcond = []
-
-                                    if type(passed_vars['when']) is str:
-                                        tmpcond.append(passed_vars['when'])
-                                    elif type(passed_vars['when']) is list:
-                                        tmpcond += passed_vars['when']
-
-                                    if type(dep_vars['when']) is str:
-                                        tmpcond.append(dep_vars['when'])
-                                    elif type(dep_vars['when']) is list:
-                                        tmpcond += dep_vars['when']
-
-                                    if len(tmpcond) > 0:
-                                        dep_vars['when'] = tmpcond
-                                else:
-                                    dep_vars['when'] = passed_vars['when']
+                        passed_when = passed_vars.get('when')
+                        role_when = role_vars.get('when')
+                        dep_when = dep_vars.get('when')
+
+                        tmpcond = []
+                        _merge_conditional(tmpcond, passed_when)
+                        _merge_conditional(tmpcond, role_when)
+                        _merge_conditional(tmpcond, dep_when)
+
+                        if len(tmpcond) > 0:
+                            dep_vars['when'] = tmpcond
 
                         self._build_role_dependencies([dep], dep_stack, passed_vars=dep_vars, level=level+1)
                         dep_stack.append([dep,dep_path,dep_vars,dep_defaults_data])
@@ -565,7 +563,10 @@ def _load_tasks(self, tasks, vars=None, default_vars=None, sudo_vars=None,
                     task_vars = utils.combine_vars(task_vars, x['vars'])
 
                 if 'when' in x:
-                    included_additional_conditions.append(x['when'])
+                    if isinstance(x['when'], (basestring, bool)):
+                        included_additional_conditions.append(x['when'])
+                    elif isinstance(x['when'], list):
+                        included_additional_conditions.extend(x['when'])
 
                 new_role = None
                 if 'role_name' in x:


Test patch: