path_dwim assumes basedir is set

Hi,

I bumped into a small bug. Easily patched, but I’m not 100% sure what I did is the best way here.

Can be reproduced with this basic playbook

  • hosts: localhost
    gather_facts: false
    connection: local

vars:
my: “{{ lookup(‘password’,‘tmppwfile’) }}”
tasks:

  • debug: var=my

Which yields this traceback:

fatal: [localhost] => Traceback (most recent call last):
File “/home/serge/src/ansible/lib/ansible/runner/init.py”, line 426, in _executor
exec_rc = self._executor_internal(host, new_stdin)
File “/home/serge/src/ansible/lib/ansible/runner/init.py”, line 517, in _executor_internal
return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port, complex_args=complex_args)
File “/home/serge/src/ansible/lib/ansible/runner/init.py”, line 717, in _executor_internal_inner
result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
File “/home/serge/src/ansible/lib/ansible/runner/action_plugins/debug.py”, line 53, in run
results = template.template(None, “{{ %s }}” % args[‘var’], inject)
File “/home/serge/src/ansible/lib/ansible/utils/template.py”, line 319, in template
varname = template_from_string(basedir, varname, vars, fail_on_undefined)
File “/home/serge/src/ansible/lib/ansible/utils/template.py”, line 546, in template_from_string
res = jinja2.utils.concat(rf)
File “”, line 6, in root
File “/usr/lib/python2.7/dist-packages/jinja2/runtime.py”, line 153, in resolve
return self.parent[key]
File “/home/serge/src/ansible/lib/ansible/utils/template.py”, line 400, in getitem
return template(self.basedir, var, self.vars, fail_on_undefined=self.fail_on_undefined)
File “/home/serge/src/ansible/lib/ansible/utils/template.py”, line 319, in template
varname = template_from_string(basedir, varname, vars, fail_on_undefined)
File “/home/serge/src/ansible/lib/ansible/utils/template.py”, line 546, in template_from_string
res = jinja2.utils.concat(rf)
File “”, line 8, in root
File “/usr/lib/python2.7/dist-packages/jinja2/runtime.py”, line 193, in call
return __obj(*args, **kwargs)
File “/home/serge/src/ansible/lib/ansible/utils/template.py”, line 539, in my_lookup
return lookup(*args, basedir=basedir, **kwargs)
File “/home/serge/src/ansible/lib/ansible/utils/template.py”, line 89, in lookup
ran = instance.run(*args, inject=vars, **kwargs)
File “/home/serge/src/ansible/lib/ansible/runner/lookup_plugins/password.py”, line 79, in run
path = utils.path_dwim(self.basedir, relpath)
File “/home/serge/src/ansible/lib/ansible/utils/init.py”, line 253, in path_dwim
return os.path.abspath(os.path.join(basedir, given))
File “/usr/lib/python2.7/posixpath.py”, line 77, in join
elif path == ‘’ or path.endswith(‘/’):
AttributeError: ‘NoneType’ object has no attribute ‘endswith’

The cause and solution is believe in two places:

  • The debug plugin wit a var param calls a template function setting basedir explicit to None

  • The path_dwimd oes a os.path.join(basedir, given) without checking basedir is not None
    I’m not sure why the the debug plugin didn’t set a basedir here, whether that was an explicit choice or not.

Fixing either of those two items solves the bug. I feel though both fixes might both be implemented, to avoid this bug being repeated elsewhere, but not sure.

My patch containing both, is at https://github.com/sergevanginderachter/ansible/commit/1c43399ba79a5b44b9c2fcd25ce32dc326886da6
I’ll update it if necessary, and make a PR if it’s ok.

Posting this here as I’m a bit confused on the best practice here. E.g., this might also be solved, though in a less generic and not optimal fashion, by having the password lookup plugin check the basedir.

I think my question basically comes to "when would basedir not be (need to be) set or be set to None?

Thanks,

Serge

“whether that was an explicit choice or not.”

It’s not an explicit choice, just something that wasn’t encountered before.

Please send the PR along!

https://github.com/ansible/ansible/pull/5527