I use different ansible canonical project directories to separate out devops from platform from deployment variables.
Ansible affords gluing things together quite nicely using the
roles_path:
in .ansible.cfg
However, I also use a vars_plugin/deploy_vars.py to manage my deployment variables in a hierarchical way. My plugin works fine if hosts, site.yml and vars_plugins are all in the same directory. But it fails if they are separate.
My commandline looks like
[ansible_deploy_vars ] ansible-playbook -i …/ansible_platform/inventory …/ansible_platform/site.yml
and my vars_plugins is symlinked like so.
[ansible_deploy_vars ] ls -al …/ansible_platform
vars_plugins → …/…/ansible_deploy_vars/vars_plugins
The problem is here:
def basedir(self):
""" if inventory came from a file, what's the directory? """
if not self.is_file():
return None
dname = os.path.dirname(self.host_list.rstrip('/'))
if dname is None or dname == '' or dname == '.':
cwd = os.getcwd()
return os.path.abspath(cwd)
return os.path.abspath(dname)
I believe the purpose of basedir is to get the ansible project root dir (typical directory containing group_vars, vars_plugins etc) given a path to an inventory file. But it does not handle dynamic inventory or directories correctly. As is,
[ansible_deploy_vars ] ansible-playbook -i ../ansible_platform/inventory ../ansible_platform/site.yml
vs the following with a trailing '/' follows a different code path which seems wrong.
[ansible_deploy_vars ] ansible-playbook -i ../ansible_platform/inventory/ ../ansible_platform/site.yml
Simply adding an rstrip('/') solves all my problems.
Would this be considered for a PR?
diff --git a/lib/ansible/inventory/init.py b/lib/ansible/inventory/init.py
index 2048046…41c8f6a 100644
— a/lib/ansible/inventory/init.py
+++ b/lib/ansible/inventory/init.py
@@ -562,7 +563,7 @@ class Inventory(object):
“”" if inventory came from a file, what’s the directory? “”"
if not self.is_file():
return None
- dname = os.path.dirname(self.host_list)
- dname = os.path.dirname(self.host_list.rstrip(‘/’))
if dname is None or dname == ‘’ or dname == ‘.’:
cwd = os.getcwd()
return os.path.abspath(cwd)