From c07dd077678ae8c1a129bf3ee8661c0fcff2b654 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Mon, 22 Jul 2013 08:25:35 -0400 Subject: [PATCH] Add raw copy support (raw=yes), tweak tempfile error message string. --- lib/ansible/runner/__init__.py | 11 +++++---- lib/ansible/runner/action_plugins/copy.py | 27 ++++++++++++++++++++--- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 72423574579..b890d141fcb 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -728,12 +728,15 @@ class Runner(object): cmd += ' && echo %s' % basetmp result = self._low_level_exec_command(conn, cmd, None, sudoable=False) + + # error handling on this seems a little aggressive? if result['rc'] != 0: - raise errors.AnsibleError('could not create temporary directory, SSH exited with result %d' % result['rc']) + raise errors.AnsibleError('could not create temporary directory, SSH (%s) exited with result %d' % (cmd, result['rc'])) + rc = utils.last_non_blank_line(result['stdout']).strip() + '/' - # Catch any other failure conditions here; files should never be - # written directly to /. - if rc == '/': + # Catch failure conditions, files should never be + # written to locations in /. + if rc.startswith('/'): raise errors.AnsibleError('failed to resolve remote temporary directory from %s: `%s` returned empty string' % (basetmp, cmd)) return rc diff --git a/lib/ansible/runner/action_plugins/copy.py b/lib/ansible/runner/action_plugins/copy.py index 21db6f6c0e8..f5466cf8e2d 100644 --- a/lib/ansible/runner/action_plugins/copy.py +++ b/lib/ansible/runner/action_plugins/copy.py @@ -42,6 +42,7 @@ class ActionModule(object): source = options.get('src', None) content = options.get('content', None) dest = options.get('dest', None) + raw = utils.boolean(options.get('raw', 'no')) force = utils.boolean(options.get('force', 'yes')) if (source is None and content is None and not 'first_available_file' in inject) or dest is None: @@ -113,7 +114,7 @@ class ActionModule(object): exec_rc = None if local_md5 != remote_md5: - if self.runner.diff: + if self.runner.diff and not raw: diff = self._get_diff_data(conn, tmp, inject, dest, source) else: diff = {} @@ -123,16 +124,29 @@ class ActionModule(object): os.remove(tmp_content) return ReturnData(conn=conn, result=dict(changed=True), diff=diff) + # transfer the file to a remote tmp location tmp_src = tmp + 'source' - conn.put_file(source, tmp_src) + + if not raw: + conn.put_file(source, tmp_src) + else: + conn.put_file(source, dest) + if content is not None: os.remove(tmp_content) + # fix file permissions when the copy is done as a different user - if self.runner.sudo and self.runner.sudo_user != 'root': + if self.runner.sudo and self.runner.sudo_user != 'root' and not raw: self.runner._low_level_exec_command(conn, "chmod a+r %s" % tmp_src, tmp) + if raw: + return ReturnData(conn=conn, result=dict(dest=dest, changed=True)) + # run the copy module + if 'raw' in module_args: + # don't send down raw=no + module_args.pop('raw') module_args = "%s src=%s original_basename=%s" % (module_args, pipes.quote(tmp_src), pipes.quote(os.path.basename(source))) return self.runner._execute_module(conn, tmp, 'copy', module_args, inject=inject, complex_args=complex_args) @@ -142,7 +156,14 @@ class ActionModule(object): if content is not None: os.remove(tmp_content) + + if raw: + return ReturnData(conn=conn, result=dict(dest=dest, changed=False)) + tmp_src = tmp + os.path.basename(source) + if 'raw' in module_args: + # don't send down raw=no + module_args.pop('raw') module_args = "%s src=%s" % (module_args, pipes.quote(tmp_src)) if self.runner.check: module_args = "%s CHECKMODE=True" % module_args