Added "debug: var=variableName" capability.

This commit is contained in:
Michael DeHaan 2013-10-14 21:01:38 -04:00
parent 84ff24d92c
commit e131de4de0
5 changed files with 44 additions and 13 deletions

View file

@ -16,6 +16,7 @@ Highlighted new features:
* The roles search path is now configurable in ansible.cfg. 'roles_path' in the config setting. * The roles search path is now configurable in ansible.cfg. 'roles_path' in the config setting.
* Includes with parameters can now be done like roles for consistency: - { include: song.yml, year:1984, song:'jump' } * Includes with parameters can now be done like roles for consistency: - { include: song.yml, year:1984, song:'jump' }
* The name of each role is now shown before each task if roles are being used * The name of each role is now shown before each task if roles are being used
* Adds a "var=" option to the debug module for debugging variable data. "debug: var=hostvars['hostname']" and "debug: var=foo" are all valid syntax.
New modules and plugins: New modules and plugins:

View file

@ -484,7 +484,7 @@ class PlaybookRunnerCallbacks(DefaultRunnerCallbacks):
host_result2 = host_result.copy() host_result2 = host_result.copy()
host_result2.pop('invocation', None) host_result2.pop('invocation', None)
verbose_always = host_result2.pop('verbose_always', None) verbose_always = host_result2.pop('verbose_always', False)
changed = host_result.get('changed', False) changed = host_result.get('changed', False)
ok_or_changed = 'ok' ok_or_changed = 'ok'
if changed: if changed:
@ -493,7 +493,7 @@ class PlaybookRunnerCallbacks(DefaultRunnerCallbacks):
# show verbose output for non-setup module results if --verbose is used # show verbose output for non-setup module results if --verbose is used
msg = '' msg = ''
if (not self.verbose or host_result2.get("verbose_override",None) is not if (not self.verbose or host_result2.get("verbose_override",None) is not
None) and verbose_always is None: None) and not verbose_always:
if item: if item:
msg = "%s: [%s] => (item=%s)" % (ok_or_changed, host, item) msg = "%s: [%s] => (item=%s)" % (ok_or_changed, host, item)
else: else:
@ -502,10 +502,10 @@ class PlaybookRunnerCallbacks(DefaultRunnerCallbacks):
else: else:
# verbose ... # verbose ...
if item: if item:
msg = "%s: [%s] => (item=%s) => %s" % (ok_or_changed, host, item, utils.jsonify(host_result2)) msg = "%s: [%s] => (item=%s) => %s" % (ok_or_changed, host, item, utils.jsonify(host_result2, format=verbose_always))
else: else:
if 'ansible_job_id' not in host_result or 'finished' in host_result2: if 'ansible_job_id' not in host_result or 'finished' in host_result2:
msg = "%s: [%s] => %s" % (ok_or_changed, host, utils.jsonify(host_result2)) msg = "%s: [%s] => %s" % (ok_or_changed, host, utils.jsonify(host_result2, format=verbose_always))
if msg != '': if msg != '':
if not changed: if not changed:

View file

@ -38,13 +38,21 @@ class ActionModule(object):
kv = utils.parse_kv(module_args) kv = utils.parse_kv(module_args)
args.update(kv) args.update(kv)
if not 'msg' in args:
if not 'msg' in args and not 'var' in args:
args['msg'] = 'Hello world!' args['msg'] = 'Hello world!'
if 'fail' in args and utils.boolean(args['fail']): result = {}
result = dict(failed=True, msg=args['msg']) if 'msg' in args:
else: if 'fail' in args and utils.boolean(args['fail']):
result = dict(msg=args['msg']) result = dict(failed=True, msg=args['msg'])
else:
result = dict(msg=args['msg'])
elif 'var' in args:
(intermediate, exception) = utils.safe_eval(args['var'], inject, include_exceptions=True, template_call=True)
if exception is not None:
intermediate = "failed to evaluate: %s" % str(exception)
result[args['var']] = intermediate
# force flag to make debug output module always verbose # force flag to make debug output module always verbose
result['verbose_always'] = True result['verbose_always'] = True

View file

@ -896,16 +896,20 @@ def is_list_of_strings(items):
return False return False
return True return True
def safe_eval(str): def safe_eval(str, locals=None, include_exceptions=False, template_call=False):
''' '''
this is intended for allowing things like: this is intended for allowing things like:
with_items: {{ a_list_variable }} with_items: a_list_variable
where Jinja2 would return a string where Jinja2 would return a string
but we do not want to allow it to call functions (outside of Jinja2, where but we do not want to allow it to call functions (outside of Jinja2, where
the env is constrained) the env is constrained)
''' '''
# FIXME: is there a more native way to do this? # FIXME: is there a more native way to do this?
if template_call:
# for the debug module in Ansible, allow debug of the form foo.bar.baz versus Python dictionary form
str = template.template(None, "{{ %s }}" % str, locals)
def is_set(var): def is_set(var):
return not var.startswith("$") and not '{{' in var return not var.startswith("$") and not '{{' in var
@ -922,8 +926,18 @@ def safe_eval(str):
if re.search(r'import \w+', str): if re.search(r'import \w+', str):
return str return str
try: try:
return eval(str) result = None
if not locals:
result = eval(str)
else:
result = eval(str, None, locals)
if include_exceptions:
return (result, None)
else:
return result
except Exception, e: except Exception, e:
if include_exceptions:
return (str, e)
return str return str

View file

@ -35,7 +35,10 @@ options:
message. message.
required: false required: false
default: "Hello world!" default: "Hello world!"
author: Dag Wieers var:
description:
- A variable name to debug. Mutually exclusive with the 'msg' option.
author: Dag Wieers, Michael DeHaan
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -44,4 +47,9 @@ EXAMPLES = '''
- debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}" - debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}"
when: ansible_default_ipv4.gateway is defined when: ansible_default_ipv4.gateway is defined
- shell: /usr/bin/uptime
register: result
- debug: var=result
''' '''