diff --git a/lib/ansible/callbacks.py b/lib/ansible/callbacks.py index abf3abdc295..706bcad261b 100644 --- a/lib/ansible/callbacks.py +++ b/lib/ansible/callbacks.py @@ -219,7 +219,8 @@ class DefaultRunnerCallbacks(object): call_callback_module('runner_on_async_failed', host, res, jid) def on_file_diff(self, host, before_string, after_string): - call_callback_module('runner_on_file_diff', before_string, after_string) + if before_string and after_string: + call_callback_module('runner_on_file_diff', before_string, after_string) ######################################################################## @@ -286,9 +287,10 @@ class CliRunnerCallbacks(DefaultRunnerCallbacks): utils.write_tree_file(self.options.tree, host, utils.jsonify(result2,format=True)) def on_file_diff(self, host, before_string, after_string): - if self.options.diff: - print utils.get_diff(before_string, after_string) - super(CliRunnerCallbacks, self).on_file_diff(host, before_string, after_string) + if before_string and after_string: + if self.options.diff: + print utils.get_diff(before_string, after_string) + super(CliRunnerCallbacks, self).on_file_diff(host, before_string, after_string) ######################################################################## @@ -422,8 +424,9 @@ class PlaybookRunnerCallbacks(DefaultRunnerCallbacks): super(PlaybookRunnerCallbacks, self).on_async_failed(host,res,jid) def on_file_diff(self, host, before_string, after_string): - print utils.get_diff(before_string, after_string) - super(PlaybookRunnerCallbacks, self).on_file_diff(host, before_string, after_string) + if before_string and after_string: + print utils.get_diff(before_string, after_string) + super(PlaybookRunnerCallbacks, self).on_file_diff(host, before_string, after_string) ######################################################################## diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 588ec13cf17..b7e4760615a 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -449,6 +449,8 @@ class Runner(object): ignore_errors = self.module_vars.get('ignore_errors', False) self.callbacks.on_failed(host, data, ignore_errors) else: + if self.diff: + self.callbacks.on_file_diff(conn.host, result.before_diff_value, result.after_diff_value) self.callbacks.on_ok(host, data) return result diff --git a/lib/ansible/runner/action_plugins/template.py b/lib/ansible/runner/action_plugins/template.py index e714bad5312..0569d2099c7 100644 --- a/lib/ansible/runner/action_plugins/template.py +++ b/lib/ansible/runner/action_plugins/template.py @@ -83,15 +83,19 @@ class ActionModule(object): # if showing diffs, we need to get the remote value dest_contents = None + if self.runner.diff: # using persist_files to keep the temp directory around to avoid needing to grab another dest_result = self.runner._execute_module(conn, tmp, 'slurp', "path=%s" % dest, inject=inject, persist_files=True) - dest_contents = dest_result.result['content'] - if dest_result.result['encoding'] == 'base64': - dest_contents = base64.b64decode(dest_contents) + if 'content' in dest_result.result: + dest_contents = dest_result.result['content'] + if dest_result.result['encoding'] == 'base64': + dest_contents = base64.b64decode(dest_contents) + else: + raise Exception("unknown encoding, failed: %s" % dest_result.result) else: - raise Exception("unknown encoding, failed: %s" % dest_result.result) - + dest_result = '' + xfered = self.runner._transfer_str(conn, tmp, 'source', resultant) # fix file permissions when the copy is done as a different user @@ -102,13 +106,11 @@ class ActionModule(object): module_args = "%s src=%s dest=%s" % (module_args, xfered, dest) if self.runner.check: - if self.runner.diff: - self.runner.callbacks.on_file_diff(conn.host, dest_contents, resultant) - return ReturnData(conn=conn, comm_ok=True, result=dict(changed=True)) + return ReturnData(conn=conn, comm_ok=True, result=dict(changed=True), before_diff_value=dest_contents, after_diff_value=resultant) else: res = self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject) - if self.runner.diff: - self.runner.callbacks.on_file_diff(conn.host, dest_contents, resultant) + res.before_diff_value = dest_contents + res.after_diff_value = resultant return res else: return ReturnData(conn=conn, comm_ok=True, result=dict(changed=False)) diff --git a/lib/ansible/runner/return_data.py b/lib/ansible/runner/return_data.py index 0dca40a3125..2f34c39bd21 100644 --- a/lib/ansible/runner/return_data.py +++ b/lib/ansible/runner/return_data.py @@ -20,9 +20,10 @@ from ansible import utils class ReturnData(object): ''' internal return class for runner execute methods, not part of public API signature ''' - __slots__ = [ 'result', 'comm_ok', 'host' ] + __slots__ = [ 'result', 'comm_ok', 'host', 'before_diff_value', 'after_diff_value' ] - def __init__(self, conn=None, host=None, result=None, comm_ok=True): + def __init__(self, conn=None, host=None, result=None, + comm_ok=True, before_diff_value=None, after_diff_value=None): # which host is this ReturnData about? if conn is not None: @@ -38,6 +39,11 @@ class ReturnData(object): self.result = result self.comm_ok = comm_ok + # if these values are set and used with --diff we can show + # changes made to particular files + self.before_diff_value = before_diff_value + self.after_diff_value = after_diff_value + if type(self.result) in [ str, unicode ]: self.result = utils.parse_json(self.result)