From bc41f46fece6838ee240739e15affe9d7ddbdf14 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 15 Feb 2016 12:08:07 -0500 Subject: [PATCH] pushed non-atomic to option of last resort try to copy into place first --- lib/ansible/module_utils/basic.py | 41 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 8d87511ae49..df591444d99 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -1737,24 +1737,7 @@ class AnsibleModule(object): os.rename(src, dest) except (IOError, OSError): e = get_exception() - # sadly there are some situations where we cannot ensure atomicity, but only if - # the user insists and we get the appropriate error we update the file unsafely - if unsafe_writes and e.errno == errno.EBUSY: - #TODO: issue warning that this is an unsafe operation, but doing it cause user insists - try: - try: - out_dest = open(dest, 'wb') - in_src = open(src, 'rb') - shutil.copyfileobj(in_src, out_dest) - finally: # assuring closed files in 2.4 compatible way - if out_dest: - out_dest.close() - if in_src: - in_src.close() - except (shutil.Error, OSError, IOError): - e = get_exception() - self.fail_json(msg='Could not write data to file (%s) from (%s): %s' % (dest, src, e)) - elif e.errno not in [errno.EPERM, errno.EXDEV, errno.EACCES, errno.ETXTBSY]: + if e.errno not in [errno.EPERM, errno.EXDEV, errno.EACCES, errno.ETXTBSY]: # only try workarounds for errno 18 (cross device), 1 (not permitted), 13 (permission denied) # and 26 (text file busy) which happens on vagrant synced folders and other 'exotic' non posix file systems self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, e)) @@ -1789,8 +1772,28 @@ class AnsibleModule(object): os.rename(tmp_dest.name, dest) except (shutil.Error, OSError, IOError): e = get_exception() + # sadly there are some situations where we cannot ensure atomicity, but only if + # the user insists and we get the appropriate error we update the file unsafely + if unsafe_writes and e.errno == errno.EBUSY: + #TODO: issue warning that this is an unsafe operation, but doing it cause user insists + try: + try: + out_dest = open(dest, 'wb') + in_src = open(src, 'rb') + shutil.copyfileobj(in_src, out_dest) + finally: # assuring closed files in 2.4 compatible way + if out_dest: + out_dest.close() + if in_src: + in_src.close() + except (shutil.Error, OSError, IOError): + e = get_exception() + self.fail_json(msg='Could not write data to file (%s) from (%s): %s' % (dest, src, e)) + + else: + self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, e)) + self.cleanup(tmp_dest.name) - self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, e)) if creating: # make sure the file has the correct permissions