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: localvars:
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