def exec_process(arg_class, arg_cmd, arg_fout=None, arg_ferr=None, arg_timeout=None, arg_kill=False, arg_set_process=None): #def exec_process( arg_class, arg_cmd, arg_fout = None, arg_ferr = None, arg_timeout = None, arg_kill_all = True ): my_process_cmd = arg_cmd Msg.dbg(my_process_cmd) my_fout, my_ferr = SysUtils.open_output(arg_fout, arg_ferr) my_result = None my_stdout = None my_stderr = None Msg.user( "SysUtils.exec_process( ... , arg_set_process: %s" % (str(bool(arg_set_process is not None))), "SYS-UTILS") Msg.flush() try: from common.datetime_utils import DateTime my_process = subprocess.Popen(my_process_cmd, stdout=my_fout, stderr=my_ferr, shell=True) my_start_time = DateTime.Time() my_pid = my_process.pid if arg_timeout is None or not SysUtils.is_numeric(arg_timeout): Msg.user("Exec PID[NONE]: %s" % (str(my_pid))) my_result = my_process.communicate() Msg.user("Done PID[NONE]: %s" % (str(my_pid))) else: Msg.user("Timeout: %s" % (str(arg_timeout))) try: my_pgid = os.getpgid(my_pid) my_parent_pgid = os.getpgid(0) # use callback to save an instance of the process to allow if arg_set_process is not None: arg_set_process(my_process) # Msg.dbg( "Exec Cmd: %s" % ( str( arg_cmd ))) # Msg.dbg( "PID: %s, PGID: %s, P-PGID: %s, Timeout: %s" % ( str( my_pid ), str( my_pgid ), str( my_parent_pgid ), str(arg_timeout))) # Msg.flush() my_result = my_process.communicate(timeout=arg_timeout) #my_pgid = os.getpgid(my_pid) # Msg.user( "Done PID: %s, PGID: %s, Timeout: %s" % ( str( my_pid ), str( my_pgid ), str(arg_timeout))) except TimeoutExpired: try: # Msg.user( "Timeout occurred ...." ) my_parent_pgid = os.getpgid(0) my_pgid = os.getpgid(my_pid) # os.setpgid( os.getpid(), os.getpid()) # on timeout kill the spawned process and all related sub-processes if arg_kill: # Msg.dbg( "Killing Everything ..." ) # os.killpg( os.getpgid( my_pid ), signal.SIGTERM ) os.killpg(os.getpgid(my_pid), signal.SIGKILL) # Trigger Shutdown of spawned processes else: Msg.error_trace() Msg.err("Process Did Not Execute Properly: %s" % (my_process_cmd)) # my_process.kill() os.kill(my_pid, signal.SIGTERM) except OSError as arg_ex: # Msg.dbg( "Spawned Killing encountered OS Error ... " ) Msg.error(str(arg_ex)) finally: # Msg.dbg( "Timeout Occurred ... " ) my_result = my_process.communicate() Msg.flush() return (my_process.returncode, None, "Process Timeout Occurred", my_start_time, my_start_time) except Exception as arg_ex: Msg.err(str(arg_ex)) Msg.error_trace() except: Msg.error_trace() finally: Msg.user("[1] SysUtils::exec_process") # Msg.user( "SysUtils.exec_process[10]", "test" ) pass my_end_time = DateTime.Time() # Msg.dbg( "SysUtils.exec_process, my_result: %s" % ( str( my_result ))) # Msg.dbg( "Return Code: %d" % ( my_process.returncode )) if my_result[0] is not None: my_stdout = my_result[0].decode("utf-8") if my_result[1] is not None: my_stderr = my_result[1].decode("utf-8") return (my_process.returncode, my_stdout, my_stderr, my_start_time, my_end_time) finally: if not (my_fout == PIPE or my_fout.closed): my_fout.close() if not (my_ferr == PIPE or my_ferr.closed): my_ferr.close() return (SysUtils.PROCESS_UNABLE_TO_SPAWN, None, "Unable to Spawn Process ....", 0, None, None)
def exec_process( cls, arg_cmd, arg_fout=None, arg_ferr=None, arg_timeout=None, arg_kill=False, arg_set_process=None, ): my_process_cmd = arg_cmd Msg.dbg(my_process_cmd) my_fout, my_ferr = SysUtils.open_output(arg_fout, arg_ferr) my_result = None my_stdout = None my_stderr = None Msg.user( "SysUtils.exec_process( ... , arg_set_process: %s" % (str(bool(arg_set_process is not None))), "SYS-UTILS", ) Msg.flush() try: from common.datetime_utils import DateTime my_process = subprocess.Popen(shlex.split(my_process_cmd), stdout=my_fout, stderr=my_ferr) my_start_time = DateTime.Time() my_pid = my_process.pid if arg_timeout is None or not SysUtils.is_numeric(arg_timeout): Msg.user("Exec PID[NONE]: %s" % (str(my_pid))) my_result = my_process.communicate() Msg.user("Done PID[NONE]: %s" % (str(my_pid))) else: Msg.user("Timeout: %s" % (str(arg_timeout))) try: my_pgid = os.getpgid(my_pid) my_parent_pgid = os.getpgid(0) # use callback to save an instance of the process to allow if arg_set_process is not None: arg_set_process(my_process) my_result = my_process.communicate(timeout=arg_timeout) except subprocess.TimeoutExpired: try: Msg.err( "Timeout after %d seconds, terminating process: %s" % (arg_timeout, my_process_cmd)) my_parent_pgid = os.getpgid(0) my_pgid = os.getpgid(my_pid) # os.setpgid( os.getpid(), os.getpid()) # on timeout kill the spawned process and all related # sub-processes if arg_kill: # Msg.dbg( "Killing Everything ..." ) os.killpg(os.getpgid(my_pid), signal.SIGKILL) # Trigger Shutdown of spawned processes else: Msg.error_trace() # my_process.kill() os.kill(my_pid, signal.SIGTERM) except OSError as arg_ex: # Msg.dbg( "Spawned Killing encountered OS Error." ) Msg.error(str(arg_ex)) finally: # Msg.dbg( "Timeout Occurred ... " ) my_result = my_process.communicate() Msg.flush() return ( my_process.returncode, None, "Process Timeout Occurred", my_start_time, my_start_time, SysUtils.PROCESS_TIMEOUT, ) except Exception as arg_ex: Msg.err(str(arg_ex)) Msg.error_trace() except BaseException: Msg.error_trace() finally: Msg.user("[1] SysUtils::exec_process") my_end_time = DateTime.Time() if my_result[0] is not None: my_stdout = my_result[0].decode("utf-8") if my_result[1] is not None: my_stderr = my_result[1].decode("utf-8") return ( my_process.returncode, my_stdout, my_stderr, my_start_time, my_end_time, SysUtils.NORMAL, ) finally: if not (my_fout == subprocess.PIPE or my_fout.closed): my_fout.close() if not (my_ferr == subprocess.PIPE or my_ferr.closed): my_ferr.close() return ( 0, None, "Unable to Spawn Process ....", 0, None, None, SysUtils.PROCESS_UNABLE_TO_SPAWN, )