Make async wrapper kill the process it supervises.

It wasn't killing the job at all before.
Indentation was 3 spaces.
reviewable/pr18780/r1
Jeroen Hoekx 13 years ago committed by Michael DeHaan
parent 31f6cd6408
commit 5045841719

@ -128,52 +128,68 @@ def _run_command(wrapped_cmd, jid, log_path):
# immediately exit this process, leaving an orphaned process
# running which immediately forks a supervisory timing process
pid = os.fork()
if pid != 0:
# the parent indicates the job has started
# print "RETURNING SUCCESS IN PARENT"
print json.dumps({ "started" : 1, "ansible_job_id" : jid, "results_file" : log_path })
sys.stdout.flush()
# we need to not return immmediately such that the launched command has an attempt
# to initialize PRIOR to ansible trying to clean up the launch directory (and argsfile)
# this probably could be done with some IPC later. Modules should always read
# the argsfile at the very first start of their execution anyway
time.sleep(1)
sys.exit(0)
else:
# the kid manages the job
# WARNING: the following call may be total overkill
daemonize_self()
# we are now daemonized in this other fork but still
# want to create a supervisory process
#print "DAEMONIZED KID MAKING MORE KIDS"
sub_pid = os.fork()
if sub_pid == 0:
#print "RUNNING IN KID A"
_run_command(cmd, jid, log_path)
#print "KID A COMPLETE"
sys.stdout.flush()
sys.exit(0)
else:
#print "WATCHING IN KID B"
remaining = int(time_limit)
if os.path.exists("/proc/%s" % sub_pid):
#print "STILL RUNNING"
time.sleep(1)
remaining = remaining - 1
else:
#print "DONE IN KID B"
sys.stdout.flush()
sys.exit(0)
if remaining == 0:
#print "SLAYING IN KID B"
os.kill(sub_pid, signals.SIGKILL)
sys.stdout.flush()
sys.exit(1)
sys.stdout.flush()
sys.exit(0)
#import logging
#import logging.handlers
#logger = logging.getLogger("ansible_async")
#logger.setLevel(logging.WARNING)
#logger.addHandler( logging.handlers.SysLogHandler("/dev/log") )
def debug(msg):
#logger.warning(msg)
pass
try:
pid = os.fork()
if pid:
# Notify the overlord that the async process started
# we need to not return immmediately such that the launched command has an attempt
# to initialize PRIOR to ansible trying to clean up the launch directory (and argsfile)
# this probably could be done with some IPC later. Modules should always read
# the argsfile at the very first start of their execution anyway
time.sleep(1)
debug("Return async_wrapper task started.")
print json.dumps({ "started" : 1, "ansible_job_id" : jid, "results_file" : log_path })
sys.stdout.flush()
sys.exit(0)
else:
# The actual wrapper process
# Daemonize, so we keep on running
daemonize_self()
# we are now daemonized, create a supervisory process
debug("Starting module and watcher")
sub_pid = os.fork()
if sub_pid:
# the parent stops the process after the time limit
remaining = int(time_limit)
# set the child process group id to kill all children
os.setpgid(sub_pid, sub_pid)
debug("Start watching %s (%s)"%(sub_pid, remaining))
time.sleep(5)
while os.waitpid(sub_pid, os.WNOHANG) == (0, 0):
debug("%s still running (%s)"%(sub_pid, remaining))
time.sleep(5)
remaining = remaining - 5
if remaining == 0:
debug("Now killing %s"%(sub_pid))
os.killpg(sub_pid, signal.SIGKILL)
debug("Sent kill to group %s"%sub_pid)
time.sleep(1)
sys.exit(0)
debug("Done in kid B.")
os._exit(0)
else:
# the child process runs the actual module
debug("Start module (%s)"%os.getpid())
_run_command(cmd, jid, log_path)
debug("Module complete (%s)"%os.getpid())
sys.exit(0)
except Exception, err:
debug("error: %s"%(err))
raise err

Loading…
Cancel
Save