Fix bug with include-level vars and sudo_user.

If a variable was provided for an include, in either of these ways:

    ---
    - hosts: all
      tasks:
      - include: included.yml param=www-data
      - include: included.yml
        vars:
          param: www-data

and then that param was used as the value of sudo_user in the included
tasks:

    ---
    - name: do something as a parameterized sudo_user
      command: whoami
      sudo: yes
      sudo_user: $param

you would receive a "failed to parse: usage: sudo" error back and the
command would not execute.

This seemed to be due to a missing call to template.template somewhere,
because the final value being passed through ssh was still `$param`.
After some digging, the issue seems to instead have been a problem with
providing the wrong context to the template for expansion. Inside the
`Task` logic, it was passing `play.vars` as the context, where
`module_vars` seemed more appropriate. After replacing it, my test case
above ran without issue. There was a comment above suggesting that the
template call might be unnecessary, but removing it made the original
error return, since it is not getting escaped later down the line. I
removed the comment since it was inaccurate.

I tried to actually incorporate my test case above into the test suite
as a regression test, but was unable to figure out how to structure it.
The existing test infrastructure seemed to only be testing for correct
number of counts in things (ok vs. changed, etc.), without regard for
whether the content generated by the command is correct. If there is an
example of a test similar to this one (where I would want to check the
JSON generated to make sure sudo_user had been converted), please let me
know and I will be happy to submit an additional patch.
This commit is contained in:
Kent Frazier 2013-05-22 23:28:17 -05:00
parent 8f3b2b281f
commit 4c6583bd00

View file

@ -115,9 +115,7 @@ class Task(object):
self.args = ds.get('args', {})
if self.sudo:
# this extra template call shouldn't be needed due to play template
# TODO: verify that this is true
self.sudo_user = template.template(play.basedir, ds.get('sudo_user', play.sudo_user), play.vars)
self.sudo_user = template.template(play.basedir, ds.get('sudo_user', play.sudo_user), module_vars)
self.sudo_pass = ds.get('sudo_pass', play.playbook.sudo_pass)
else:
self.sudo_user = None