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.
This commit is contained in:
parent
f9cb5ecc3c
commit
88122e0f72
1 changed files with 12 additions and 5 deletions
|
@ -72,19 +72,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 = sys.exc_info()[1]
|
||||
|
@ -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)
|
||||
|
||||
|
||||
####################
|
||||
|
|
Loading…
Reference in a new issue