summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Shrewsbury <shrewsbury.dave@gmail.com>2016-06-23 17:14:59 -0400
committerJames Cammarata <jimi@sngx.net>2016-07-07 11:31:11 -0500
commitc8d68860079083ecf71da6d70b2dffceaaf54a6c (patch)
tree8369b92241a7142199221918a88cbe6fa47ac24c
parent9bcb552872b0352d02a3284e554c59806b1f8ec0 (diff)
downloadansible-modules-core-c8d68860079083ecf71da6d70b2dffceaaf54a6c.tar.gz
Use os.rename() in async_wrapper
Because the async_status module will read from the same file that the async_wrapper module is writing, it's possible that the file may not be fully synced during a read, causing spurious failures. Use a temp file to do an atomic operation on the file. We can't use atomic_move() here as that doesn't work properly under async. Also, let's not read concurrently from the same file the subprocess is writing to. Instead, capture stdout/stderr via PIPE and write to the file to avoid nasty races. (cherry picked from commit 4e239f6ce0d8ed96d734ef6ca75fa745c3925045)
-rw-r--r--utilities/logic/async_wrapper.py17
1 files changed, 12 insertions, 5 deletions
diff --git a/utilities/logic/async_wrapper.py b/utilities/logic/async_wrapper.py
index ecdaf28e..284838af 100644
--- a/utilities/logic/async_wrapper.py
+++ b/utilities/logic/async_wrapper.py
@@ -73,19 +73,23 @@ def daemonize_self():
def _run_module(wrapped_cmd, jid, job_path):
- jobfile = open(job_path, "w")
+ tmp_job_path = job_path + ".tmp"
+ jobfile = open(tmp_job_path, "w")
jobfile.write(json.dumps({ "started" : 1, "ansible_job_id" : jid }))
jobfile.close()
- jobfile = open(job_path, "w")
+ os.rename(tmp_job_path, job_path)
+ jobfile = open(tmp_job_path, "w")
result = {}
outdata = ''
try:
cmd = shlex.split(wrapped_cmd)
- script = subprocess.Popen(cmd, shell=False, stdin=None, stdout=jobfile, stderr=jobfile)
- script.communicate()
- outdata = file(job_path).read()
+ script = subprocess.Popen(cmd, shell=False, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (outdata, stderr) = script.communicate()
result = json.loads(outdata)
+ if stderr:
+ result['stderr'] = stderr
+ jobfile.write(json.dumps(result))
except (OSError, IOError), e:
result = {
@@ -95,6 +99,7 @@ def _run_module(wrapped_cmd, jid, job_path):
}
result['ansible_job_id'] = jid
jobfile.write(json.dumps(result))
+
except:
result = {
"failed" : 1,
@@ -104,7 +109,9 @@ def _run_module(wrapped_cmd, jid, job_path):
}
result['ansible_job_id'] = jid
jobfile.write(json.dumps(result))
+
jobfile.close()
+ os.rename(tmp_job_path, job_path)
####################