multi-role organization and re-use

That’s what I did already. master.yml is in a directory with a group_vars underneath and I call ansible-playbook from that directory. As a parameter I use “-i /someotherpath/hosts” and in that other path there is also a group_vars subdirectory. What happens is that the variables from the inventory get executed but not those from the master playbook. From your comment I understood that those from the master playbook should be executed if called from that directory, which I did. So where is the difference coming from?

also sprach Michael DeHaan <michael@ansibleworks.com> [2013.06.20.2224 +0200]:

Already supports relative paths.

Yes, it does. But there is something I don't quite understand. The
code does this to determine the path of the role directory:

  path = utils.path_dwim(self.basedir, os.path.join('roles', orig_path))

utils.path_dwim is a wrapper around os.path.abspath, so we can
expect an absolut path from this.

self.basedir is the directory containing the playbook.

orig_path is the name (or path) of the role.

If you set orig_path to an absolute path, then os.path.join just
returns that and drops 'roles', and utils.path_dwim also just
returns the path.

But if orig_path is a relative path, then 'roles/' is *always*
prepended.

Therefore, if you want to point to a role directory, you need to use
absolute paths (which isn't ideal); if you use a relative path, then
that is always relative to the roles/ subdirectory.

If you want to include a role that is in a subdirectory of the
playbook, e.g. 'foo/bar', then you need to use '..':

  ../foo/bar → basedir/roles/../foo/bar → basedir/foo/bar

This is a bit non-intuitive, at least to me.

Would you consider the following patch, which changes the origin for
the resolution of the relative path to the directory of the
playbook, which makes more sense to me.

Current users just keep on saying 'foo' to get at 'roles/foo'

But if you say e.g. './foo', then this means './foo', not
'/roles/foo':

--- a/lib/ansible/playbook/play.py
+++ b/lib/ansible/playbook/play.py
@@ -162,7 +162,13 @@ class Play(object):
             with_items = has_dict.get('with_items', None)
             when = has_dict.get('when', None)

- path = utils.path_dwim(self.basedir, os.path.join('roles', orig_path))
+ if orig_path.startswith("."):
+ # a leading dot makes roles be resolved relative to the
+ # playbook directory, not a subdirectory 'roles/'
+ path = utils.path_dwim(self.basedir, orig_path)
+ else:
+ path = utils.path_dwim(self.basedir, os.path.join('roles', orig_path))

Minor request – when specifying something “failed with an error”, please share the error. Otherwise it just confuses everyone.

In particular, this:

  • { role: {{ role_base_path }}/role1 }

That’s a YAML syntax error, because you have to quote the string “{{ role_base_path }}/role1” since YAML thinks an entry starting with “{” is going to be a hash.

“Would you consider the following patch, which changes the origin for
the resolution of the relative path to the directory of the
playbook, which makes more sense to me.”

Something like that.

I would think instead that if the role contained a path seperator it would look for it in both roles/foo and basedir, so no special syntax about “.” would be required.

I need to test things to see why that may or may not be operational.

Minor request -- when specifying something "failed with an error", please
share the error. Otherwise it just confuses everyone.

I think you are responding to me in another email in this thread.

The errors I saw for different role expressions were:

Playbook:

Thanks!

Right, vars are not loaded prior to loading in roles. You could probably pass this in with “-e role_base_dir=path” and it would evaluate.

Thanks for your help & persistence :slight_smile:

Right, vars are not loaded prior to loading in roles. You could probably
pass this in with "-e role_base_dir=path" and it would evaluate.

Same outcome:

$ cat site.yml

also sprach Michael DeHaan <michael@ansibleworks.com> [2013.06.22.1934 +0200]:

I would think instead that if the role contained a path seperator
it would look for it in both roles/foo and basedir, so no special
syntax about "." would be required.

While at it, would you consider the idea of a list of paths to be
looked up? I.e. a list that could be extended by the user using
ansible.cfg?