Repository: ansible/ansible

Issue:
ansible 2.1.1.0-rc1: exitcode == 0 when fatal in include
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

```
2.1.1.0
```
##### CONFIGURATION

<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
##### OS / ENVIRONMENT

<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->

N/A
##### SUMMARY

<!--- Explain the problem briefly -->

ansible release candiate for version 2.1.1.0 does not exit with exitcode != 0, when a failure occurs within an include. This breaks my toolchain for automatic testing!
##### STEPS TO REPRODUCE

<!---
For bugs, show exactly how to reproduce the problem.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->

``` yaml

---
# foo.yml
- hosts: localhost
  connection: local
  gather_facts: False
  tasks:
    - include: bar.yml

---
# bar.yml
- fail:
    msg: foo
```

<!--- You can also paste gist.github.com links for larger files -->
##### EXPECTED RESULTS

<!--- What did you expect to happen when running the steps above? -->

```
ansible-playbook foo.yml; echo exitcode=$?
 [WARNING]: Host file not found: /etc/ansible/hosts

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [localhost] ***************************************************************

TASK [include] *****************************************************************
included: /Users/oberger/code/as/asitcm/asit-base/tests/foobar/bar.yml for localhost

TASK [fail] ********************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "foo"}
    to retry, use: --limit @foo.retry

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1   

exitcode=2
```
##### ACTUAL RESULTS

<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->

```
ansible-playbook foo.yml; echo exitcode=$?
 [WARNING]: Host file not found: /etc/ansible/hosts

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [localhost] ***************************************************************

TASK [fail] ********************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "foo"}
 [WARNING]: Could not create retry file 'foo.retry'.         [Errno 2] No such file or directory: ''


PLAY RECAP *********************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1   

exitcode=0
```



Discussion:
+1


Resolving patch:
diff --git a/lib/ansible/executor/play_iterator.py b/lib/ansible/executor/play_iterator.py
--- a/lib/ansible/executor/play_iterator.py
+++ b/lib/ansible/executor/play_iterator.py
@@ -469,7 +469,7 @@ def mark_host_failed(self, host):
         self._host_states[host.name] = s
 
     def get_failed_hosts(self):
-        return dict((host, True) for (host, state) in iteritems(self._host_states) if state.run_state == self.ITERATING_COMPLETE and state.fail_state != self.FAILED_NONE)
+        return dict((host, True) for (host, state) in iteritems(self._host_states) if self._check_failed_state(state))
 
     def _check_failed_state(self, state):
         if state is None:


Test patch: