Repository: ansible/ansible

Issue:
Ansible hostvars[] directory seems to assume different path for host_vars with --limit is used
This bug report is a result investigating https://groups.google.com/forum/#!searchin/ansible-project/limit$20hostvars$20/ansible-project/ZZ12KPiOE2s/rfdotpnmKgAJ . 

It turns out that the host_vars/ directory must be relative to the inventory file _when the host is not included in --limit_. Ansible can define any such requirement, but note that it is inconsistent to be more liberal with the placement of the host_vars directory when a file is not excluded with --limit (i.e., if the host is included in the run, either the directory relative to the playbook can be used, or the directory relative to the inventory file). 

To reproduce, see the project in http://feliksik.nl/ansible-limit.tgz structure, which structure looks as follows (modify inventory to your environment, of course). 

```
.
├── host_vars
│   └── outlimit
├── inventory
├── playbook.yml
└── sub
    └── inventory -> ../inventory
```

There is the following calls possible: 
root1) ansible-playbook -i inventory playbook.yml --limit inlimit
root2) ansible-playbook -i inventory playbook.yml --limit inlimit,outlimit
sub1) ansible-playbook -i sub/inventory playbook.yml --limit inlimit
sub2) ansible-playbook -i sub/inventory playbook.yml --limit inlimit,outlimit

Expected behaviour: 
- if root2 works, then root1 should also work
- if sub2 works (i.e. it is legal for the host_vars directory to not be in the same directory as the inventory file), then sub1 should also work.

Actual behavior: 
- root1 works
- root2 works
- sub1 **fails**! 
- sub2 works



Discussion:
@feliksik with which version of Ansible are you seeing this behavior? If you're not running against devel already, could you also run this against that to see if the issue persists or if there are any other differences? The handling of paths have been somewhat cleaned up in the devel branch (2.0) so we want to make sure the problem hasn't already been addressed. Thanks!

This is 1.9.2.
@jimi-c I'd be happy to help investigate that, but it'll take me a few days to get to this. 

@feliksik no problem, just let us know.

Thanks!

I will not be able to work on this until October, as holiday kicks in. 
The only thing is that I need to install a dev version of Ansible. If anyone has it installed, it should cost you a few minutes to set up the ip address in your inventory and run the script as provided on http://feliksik.nl/ansible-limit.tgz 

Thank for you patience. I have checked, and it turns out the bug does not exist in current 2.0 dev. 

That means the problem exists only in the current 1.9 version. 


Resolving patch:
diff --git a/lib/ansible/inventory/__init__.py b/lib/ansible/inventory/__init__.py
--- a/lib/ansible/inventory/__init__.py
+++ b/lib/ansible/inventory/__init__.py
@@ -591,8 +591,13 @@ def set_playbook_basedir(self, dir):
             for group in self.groups:
                 group.vars = utils.combine_vars(group.vars, self.get_group_vars(group, new_pb_basedir=True))
             # get host vars from host_vars/ files
+            ### HACK: in 2.0 subset isn't a problem.  Never port this to 2.x
+            ### Fixes: https://github.com/ansible/ansible/issues/13557
+            old_subset =  self._subset
+            self._subset = None
             for host in self.get_hosts():
                 host.vars = utils.combine_vars(host.vars, self.get_host_vars(host, new_pb_basedir=True))
+            self._subset = old_subset
             # invalidate cache
             self._vars_per_host = {}
             self._vars_per_group = {}


Test patch: