Пример #1
0
    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)
Пример #2
0
    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,
        )