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
4fe583e29b
commit
4e239f6ce0
1 changed files with 12 additions and 5 deletions
|
@ -72,19 +72,23 @@ def daemonize_self():
|
||||||
|
|
||||||
def _run_module(wrapped_cmd, jid, job_path):
|
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.write(json.dumps({ "started" : 1, "ansible_job_id" : jid }))
|
||||||
jobfile.close()
|
jobfile.close()
|
||||||
jobfile = open(job_path, "w")
|
os.rename(tmp_job_path, job_path)
|
||||||
|
jobfile = open(tmp_job_path, "w")
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
outdata = ''
|
outdata = ''
|
||||||
try:
|
try:
|
||||||
cmd = shlex.split(wrapped_cmd)
|
cmd = shlex.split(wrapped_cmd)
|
||||||
script = subprocess.Popen(cmd, shell=False, stdin=None, stdout=jobfile, stderr=jobfile)
|
script = subprocess.Popen(cmd, shell=False, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
script.communicate()
|
(outdata, stderr) = script.communicate()
|
||||||
outdata = file(job_path).read()
|
|
||||||
result = json.loads(outdata)
|
result = json.loads(outdata)
|
||||||
|
if stderr:
|
||||||
|
result['stderr'] = stderr
|
||||||
|
jobfile.write(json.dumps(result))
|
||||||
|
|
||||||
except (OSError, IOError):
|
except (OSError, IOError):
|
||||||
e = sys.exc_info()[1]
|
e = sys.exc_info()[1]
|
||||||
|
@ -95,6 +99,7 @@ def _run_module(wrapped_cmd, jid, job_path):
|
||||||
}
|
}
|
||||||
result['ansible_job_id'] = jid
|
result['ansible_job_id'] = jid
|
||||||
jobfile.write(json.dumps(result))
|
jobfile.write(json.dumps(result))
|
||||||
|
|
||||||
except:
|
except:
|
||||||
result = {
|
result = {
|
||||||
"failed" : 1,
|
"failed" : 1,
|
||||||
|
@ -104,7 +109,9 @@ def _run_module(wrapped_cmd, jid, job_path):
|
||||||
}
|
}
|
||||||
result['ansible_job_id'] = jid
|
result['ansible_job_id'] = jid
|
||||||
jobfile.write(json.dumps(result))
|
jobfile.write(json.dumps(result))
|
||||||
|
|
||||||
jobfile.close()
|
jobfile.close()
|
||||||
|
os.rename(tmp_job_path, job_path)
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
Loading…
Reference in a new issue