Exemple #1
0
 def hard_timeout_handler(self):
     now = datetime.datetime.now
     while True:
         if self.started:
             if (now() - self.started).total_seconds() > self.hard_timeout:
                 LOGGER.warning("Request (hard) Timeout => SIGKILL")
                 # Self-Kill
                 mfutil.kill_process_and_children(os.getpid())
         time.sleep(1)
def _main(args, remaining_args):
    p = subprocess.Popen(remaining_args)
    pid = p.pid
    for signum in (signal.SIGTERM, signal.SIGINT):
        signal.signal(signum,
                      functools.partial(on_signal,
                                        args.unix_socket, pid, args.signal,
                                        args.timeout))
    x = threading.Thread(target=socket_up_after,
                         args=(args.unix_socket, args.socket_up_after))
    x.daemon = True
    x.start()
    while True:
        try:
            if six.PY2:
                # emulate python3 subprocess python3 behaviour
                if p.poll() is None:
                    time.sleep(1)
                    raise TIMEOUT_EXCEPTION_CLASS
            else:
                p.wait(timeout=1)
            if SMART_SHUTDOWN:
                LOGGER.info("process: %i (smart) stopped" % pid)
            elif HARD_SHUTDOWN:
                pass
            else:
                LOGGER.warning("process: %i stopped for an unknown reason "
                               "=> let's shutdown the corresponding socket "
                               "before restart" % pid)
                socket_down(args.unix_socket, False, 10)
                # wait a little bit to be sure that all nginx workers
                # record that the socket is closed
                time.sleep(0.5)
            break
        except TIMEOUT_EXCEPTION_CLASS:
            pass
        except Exception:
            LOGGER.exception("Exception during process waiting => exiting")
            break
        if SIG_SHUTDOWN is not None and args.timeout_after_signal > 0:
            now = datetime.datetime.now()
            delta = now - SIG_SHUTDOWN
            if delta.total_seconds() > args.timeout_after_signal:
                LOGGER.warning("sending SIGKILL to %i and its children", pid)
                kill_process_and_children(pid)
    try:
        os.remove(args.unix_socket)
    except Exception:
        pass
def send_signal_when_no_connection(pid, unix_socket, sig, timeout):
    global SIG_SHUTDOWN, HARD_SHUTDOWN
    LOGGER.info("stopping new connections and waiting for no connection "
                "left on %s (timeout: %i seconds)" %
                (unix_socket, timeout))
    if socket_down(unix_socket, True, timeout):
        SIG_SHUTDOWN = datetime.datetime.now()
        if six.PY2:
            LOGGER.info("sending %i to %i", sig, pid)
        else:
            LOGGER.info("sending %s to %i",
                        signal.Signals(sig).name, pid)  # pylint: disable=E1101
        os.kill(pid, sig)
    else:
        HARD_SHUTDOWN = datetime.datetime.now()
        LOGGER.warning("sending SIGKILL to %i and its children", pid)
        kill_process_and_children(pid)
 def _kill(self, signal: int):
     if self.process is None:
         return
     if self.cmd.recursive_sigkill and signal == 9:
         self.logger.info("Sending signal %i to %i (and children)" %
                          (signal, self.process.pid))
         try:
             kill_process_and_children(self.process.pid)
         except Exception:
             self.logger.warning("can't recursively kill %i", exc_info=True)
     else:
         self.logger.info("Sending signal %i to %i" %
                          (signal, self.process.pid))
         try:
             os.kill(self.process.pid, signal)
         except ProcessLookupError:
             pass
         except Exception:
             self.logger.warning("can't kill %i", exc_info=True)
def on_signal(unix_socket, pid, signal, timeout, signum, frame):
    global SMART_SHUTDOWN, HARD_SHUTDOWN
    if signum == 15:
        if SMART_SHUTDOWN is not None:
            LOGGER.info("received SIGTERM but SMART_SHUTDOWN already in "
                        "progress => ignoring")
            return
        LOGGER.info("received SIGTERM => smart closing...")
        SMART_SHUTDOWN = datetime.datetime.now()
        x = threading.Thread(target=send_signal_when_no_connection,
                             args=(pid, unix_socket, signal, timeout))
        x.daemon = True
        x.start()
    elif signum == 2:
        if HARD_SHUTDOWN:
            return
        HARD_SHUTDOWN = datetime.datetime.now()
        LOGGER.warning("received SIGINT => (non smart) stopping...")
        LOGGER.warning("sending SIGKILL to %i and its children", pid)
        kill_process_and_children(pid)
    "the number of remaining processes"
argparser.add_argument("--silent", action="store_true", help=silent_doc)
args = argparser.parse_args()
processes_to_kill = get_processes_to_kill()
first_count = len(processes_to_kill)
for pid in processes_to_kill:
    if not args.silent:
        try:
            proc = psutil.Process(pid)
            LOG.info("killing remaining process (and children): "
                     "pid:%i, cmdline: %s" % (proc.pid,
                                              " ".join(proc.cmdline())))
        except Exception:
            # we can have some exceptions here is some edge cases
            pass
    kill_process_and_children(pid)

processes_to_kill = get_processes_to_kill()
second_count = len(processes_to_kill)
for pid in processes_to_kill:
    if not args.silent:
        try:
            proc = psutil.Process(pid)
            LOG.warning("remaining process not killed: "
                        "pid:%i, cmdline: %s" % (proc.pid,
                                                 " ".join(proc.cmdline())))
        except Exception:
            # we can have some exceptions here is some edge cases
            pass

if args.silent:
processes_to_kill = get_processes_to_kill()
first_count = len(processes_to_kill)
with MFProgress() as progress:
    t = progress.add_task("- Killing remainging processes (if any)...",
                          total=(first_count + 1))
    for pid in processes_to_kill:
        if args.debug:
            try:
                proc = psutil.Process(pid)
                LOG.info("killing remaining process (and children): "
                         "pid:%i, cmdline: %s" %
                         (proc.pid, " ".join(proc.cmdline())))
            except Exception:
                # we can have some exceptions here is some edge cases
                pass
        kill_process_and_children(pid)
        progress.update(t, advance=1)

    processes_to_kill = get_processes_to_kill()
    second_count = len(processes_to_kill)
    if second_count == 0:
        if first_count > 0:
            progress.complete_task_warning(t, "%i killed" % first_count)
        else:
            progress.complete_task(t)
    else:
        for pid in processes_to_kill:
            progress.complete_task_nok(t, "%i remaining" % second_count)
            if args.debug:
                try:
                    proc = psutil.Process(pid)
Exemple #8
0
def main():
    parser = argparse.ArgumentParser(description=DESCRIPTION)
    parser.add_argument('pid', type=int,
                        help='root process pid (to kill)')
    args = parser.parse_args()
    kill_process_and_children(args.pid)
Exemple #9
0
def main():
    parser = argparse.ArgumentParser(description=DESCRIPTION)
    parser.add_argument('pid', type=int, help='root process pid (to kill)')
    args = parser.parse_args()
    kill_process_and_children(args.pid)