From affb66416f05d7c366a80ef3ce9eec02e165b3f1 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Wed, 25 Feb 2015 11:26:07 -0800 Subject: [PATCH] Port fix for #10300 to v2 --- v2/ansible/plugins/action/template.py | 32 ++++++++++++++++++++++----- v2/ansible/plugins/shell/sh.py | 7 ++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/v2/ansible/plugins/action/template.py b/v2/ansible/plugins/action/template.py index 56cd5bbcd0..372c07544d 100644 --- a/v2/ansible/plugins/action/template.py +++ b/v2/ansible/plugins/action/template.py @@ -26,6 +26,27 @@ class ActionModule(ActionBase): TRANSFERS_FILES = True + + + def get_checksum(self, tmp, dest, try_directory=False, source=None): + remote_checksum = self._remote_checksum(tmp, dest) + + if remote_checksum in ('0', '2', '3', '4'): + # Note: 1 means the file is not present which is fine; template + # will create it. 3 means directory was specified instead of file + if try_directory and remote_checksum == '3' and source: + base = os.path.basename(source) + dest = os.path.join(dest, base) + remote_checksum = self.get_checksum(tmp, dest, try_directory=False) + if remote_checksum not in ('0', '2', '3', '4'): + return remote_checksum + + result = dict(failed=True, msg="failed to checksum remote file." + " Checksum error code: %s" % remote_checksum) + return result + + return remote_checksum + def run(self, tmp=None, task_vars=dict()): ''' handler for template operations ''' @@ -84,12 +105,11 @@ class ActionModule(ActionBase): except Exception, e: return dict(failed=True, msg=type(e).__name__ + ": " + str(e)) - local_checksum = checksum_s(resultant) - remote_checksum = self._remote_checksum(tmp, dest) - - if remote_checksum in ('0', '2', '3', '4'): - # Note: 1 means the file is not present which is fine; template will create it - return dict(failed=True, msg="failed to checksum remote file. Checksum error code: %s" % remote_checksum) + local_checksum = utils.checksum_s(resultant) + remote_checksum = self.get_checksum(tmp, dest, not directory_prepended, source=source) + if isinstance(remote_checksum, dict): + # Error from remote_checksum is a dict. Valid return is a str + return remote_checksum if local_checksum != remote_checksum: # if showing diffs, we need to get the remote value diff --git a/v2/ansible/plugins/shell/sh.py b/v2/ansible/plugins/shell/sh.py index d8f1efeb12..fc4063c204 100644 --- a/v2/ansible/plugins/shell/sh.py +++ b/v2/ansible/plugins/shell/sh.py @@ -96,6 +96,13 @@ class ShellModule(object): # 0. This logic is added to the end of the cmd at the bottom of this # function. + # Return codes: + # checksum: success! + # 0: Unknown error + # 1: Remote file does not exist + # 2: No read permissions on the file + # 3: File is a directory + # 4: No python interpreter test = "rc=flag; [ -r \'%(p)s\' ] || rc=2; [ -f \'%(p)s\' ] || rc=1; [ -d \'%(p)s\' ] && rc=3; %(i)s -V 2>/dev/null || rc=4; [ x\"$rc\" != \"xflag\" ] && echo \"${rc}\"\' %(p)s\' && exit 0" % dict(p=path, i=python_interp) csums = [ "(%s -c 'import hashlib; BLOCKSIZE = 65536; hasher = hashlib.sha1();\nafile = open(\"%s\", \"rb\")\nbuf = afile.read(BLOCKSIZE)\nwhile len(buf) > 0:\n\thasher.update(buf)\n\tbuf = afile.read(BLOCKSIZE)\nafile.close()\nprint(hasher.hexdigest())' 2>/dev/null)" % (python_interp, path), # Python > 2.4 (including python3)