コード例 #1
0
ファイル: process_manager.py プロジェクト: farukc/chaperone
 def _system_started(self, startup, future=None):
     if future and not future.cancelled() and future.exception():
         self._system_coro_check(future)
         return
     info(self.version + ", ready.")
     if startup:
         future = self.activate(startup)
         future.add_done_callback(self._system_coro_check)
コード例 #2
0
 def _system_started(self, startup, future=None):
     if future and not future.cancelled() and future.exception():
         self._system_coro_check(future)
         return
     info(self.version + ", ready.")
     if startup:
         future = self.activate(startup)
         future.add_done_callback(self._system_coro_check)
コード例 #3
0
ファイル: watcher.py プロジェクト: yutiansut/chaperone
    def __exit__(self, a, b, c):
        with self._lock:
            self._forks -= 1

            if self._forks or not self._zombies:
                return

            collateral_victims = str(self._zombies)
            self._zombies.clear()

        info("Caught subprocesses termination from unknown pids: %s",
             collateral_victims)
コード例 #4
0
ファイル: watcher.py プロジェクト: CivilPol/chaperone
    def __exit__(self, a, b, c):
        with self._lock:
            self._forks -= 1

            if self._forks or not self._zombies:
                return

            collateral_victims = str(self._zombies)
            self._zombies.clear()

        info(
            "Caught subprocesses termination from unknown pids: %s",
            collateral_victims)
コード例 #5
0
    def _kill_system_co(self):

        self.notify.stopping()

        self._cancel_pending()

        # Tell the family it's been nice.  It's unlikely we won't have a process family, but
        # it's optional, so we should handle the situation.

        wait_done = False  # indicates if shutdown_timeout has expired

        if self._family:
            for f in self._family.values():
                yield from f.final_stop()
            # let normal shutdown happen
            if self._watcher.number_of_waiters > 0 and self._shutdown_timeout:
                debug(
                    "still have {0} waiting, sleeping for shutdown_timeout={1}"
                    .format(self._watcher.number_of_waiters,
                            self._shutdown_timeout))
                yield from asyncio.sleep(self._shutdown_timeout)
                wait_done = True

        try:
            os.kill(-1, signal.SIGTERM)  # first try a sig term
            if self.send_sighup:
                os.kill(-1, signal.SIGHUP)
        except ProcessLookupError:
            debug(
                "No processes remain when attempting to kill system, just stop."
            )
            self._no_processes(True)
            return

        if wait_done:  # give a short wait just so the signals fire
            yield from asyncio.sleep(1)  # these processes are unknowns
        else:
            yield from asyncio.sleep(self._shutdown_timeout)

        if self._all_killed:
            return

        info("Some processes remain after {0}secs.  Forcing kill".format(
            self._shutdown_timeout))

        try:
            os.kill(-1, signal.SIGKILL)
        except ProcessLookupError:
            debug("No processes when attempting to force quit")
            self._no_processes(True)
            return
コード例 #6
0
ファイル: subproc.py プロジェクト: CivilPol/chaperone
def _process_logger(stream, kind, service):
    name = service.name.replace('.service', '')
    while True:
        data = yield from stream.readline()
        if not data:
            return
        line = data.decode('ascii', 'ignore').rstrip()
        if not line:
            continue            # ignore blank lines in stdout/stderr
        if kind == 'stderr':
            # we map to warning because stderr output is "to be considered" and not strictly
            # erroneous
            warn(line, program=name, pid=service.pid, facility=syslog_info.LOG_DAEMON)
        else:
            info(line, program=name, pid=service.pid, facility=syslog_info.LOG_DAEMON)
コード例 #7
0
ファイル: commands.py プロジェクト: CivilPol/chaperone
    def do_exec(self, opts, controller):
        delay = opts['<delay>']

        if delay is None or delay.lower() == "now":
            delay = 0.1
            message = "Shutting down now"
        else:
            try:
                delay = float(delay)
            except ValueError:
                return "Specified delay is not a valid decimal number: " + str(delay)
            message = "Shutting down in {0} seconds".format(delay)

        info("requested shutdown scheduled to occur in {0} seconds".format(delay))
        asyncio.get_event_loop().call_later(delay, controller.kill_system)

        return message
コード例 #8
0
ファイル: process_manager.py プロジェクト: farukc/chaperone
    def _kill_system_co(self):

        self.notify.stopping()

        self._cancel_pending()

        # Tell the family it's been nice.  It's unlikely we won't have a process family, but
        # it's optional, so we should handle the situation.

        wait_done = False       # indicates if shutdown_timeout has expired

        if self._family:
            for f in self._family.values():
                yield from f.final_stop()
            # let normal shutdown happen
            if self._watcher.number_of_waiters > 0 and self._shutdown_timeout:
                debug("still have {0} waiting, sleeping for shutdown_timeout={1}".format(self._watcher.number_of_waiters, self._shutdown_timeout))
                yield from asyncio.sleep(self._shutdown_timeout)
                wait_done = True

        try:
            os.kill(-1, signal.SIGTERM) # first try a sig term
            if self.send_sighup:
                os.kill(-1, signal.SIGHUP)
        except ProcessLookupError:
            debug("No processes remain when attempting to kill system, just stop.")
            self._no_processes(True)
            return

        if wait_done:                   # give a short wait just so the signals fire
            yield from asyncio.sleep(1) # these processes are unknowns
        else:
            yield from asyncio.sleep(self._shutdown_timeout)
            
        if self._all_killed:
            return

        info("Some processes remain after {0}secs.  Forcing kill".format(self._shutdown_timeout))

        try:
            os.kill(-1, signal.SIGKILL)
        except ProcessLookupError:
            debug("No processes when attempting to force quit")
            self._no_processes(True)
            return
コード例 #9
0
    def do_exec(self, opts, controller):
        delay = opts['<delay>']

        if delay is None or delay.lower() == "now":
            delay = 0.1
            message = "Shutting down now"
        else:
            try:
                delay = float(delay)
            except ValueError:
                return "Specified delay is not a valid decimal number: " + str(
                    delay)
            message = "Shutting down in {0} seconds".format(delay)

        info("requested shutdown scheduled to occur in {0} seconds".format(
            delay))
        asyncio.get_event_loop().call_later(delay, controller.kill_system)

        return message
コード例 #10
0
def _process_logger(stream, kind, service):
    name = service.name.replace('.service', '')
    while True:
        data = yield from stream.readline()
        if not data:
            return
        line = data.decode('ascii', 'ignore').rstrip()
        if not line:
            continue  # ignore blank lines in stdout/stderr
        if kind == 'stderr':
            # we map to warning because stderr output is "to be considered" and not strictly
            # erroneous
            warn(line,
                 program=name,
                 pid=service.pid,
                 facility=syslog_info.LOG_DAEMON)
        else:
            info(line,
                 program=name,
                 pid=service.pid,
                 facility=syslog_info.LOG_DAEMON)
コード例 #11
0
ファイル: watcher.py プロジェクト: CivilPol/chaperone
    def _do_waitpid_all(self):
        # Because of signal coalescing, we must keep calling waitpid() as
        # long as we're able to reap a child.
        while True:
            try:
                pid, status = os.waitpid(-1, os.WNOHANG)
                debug("REAP pid={0},status={1}".format(pid,status))
            except ChildProcessError:
                # No more child processes exist.
                if self._had_children:
                    debug("no child processes present")
                    self.events.onNoProcesses()
                return
            else:
                self._had_children = True
                if pid == 0:
                    # A child process is still alive.
                    return

                returncode = ProcStatus(status)

            with self._lock:
                try:
                    callback, args = self._callbacks.pop(pid)
                except KeyError:
                    # unknown child
                    if self._forks:
                        # It may not be registered yet.
                        self._zombies[pid] = returncode
                        continue
                    callback = None

            if callback is None:
                info(
                    "Caught subprocess termination from unknown pid: "
                    "%d -> %d", pid, returncode)
            else:
                callback(pid, returncode, *args)
コード例 #12
0
ファイル: watcher.py プロジェクト: yutiansut/chaperone
    def _do_waitpid_all(self):
        # Because of signal coalescing, we must keep calling waitpid() as
        # long as we're able to reap a child.
        while True:
            try:
                pid, status = os.waitpid(-1, os.WNOHANG)
                debug("REAP pid={0},status={1}".format(pid, status))
            except ChildProcessError:
                # No more child processes exist.
                if self._had_children:
                    debug("no child processes present")
                    self.events.onNoProcesses()
                return
            else:
                self._had_children = True
                if pid == 0:
                    # A child process is still alive.
                    return

                returncode = ProcStatus(status)

            with self._lock:
                try:
                    callback, args = self._callbacks.pop(pid)
                except KeyError:
                    # unknown child
                    if self._forks:
                        # It may not be registered yet.
                        self._zombies[pid] = returncode
                        continue
                    callback = None

            if callback is None:
                info(
                    "Caught subprocess termination from unknown pid: "
                    "%d -> %d", pid, returncode)
            else:
                callback(pid, returncode, *args)
コード例 #13
0
ファイル: process_manager.py プロジェクト: farukc/chaperone
    def _start_system_services(self):

        self._notify_enabled = yield from self.notify.connect()

        self._syslog = SyslogServer()
        self._syslog.configure(self._config, self._minimum_syslog_level)

        try:
            yield from self._syslog.run()
        except PermissionError as ex:
            self._syslog = None
            warn("syslog service cannot be started: {0}", ex)
        else:
            self._syslog.capture_python_logging()
            info("Switching all chaperone logging to /dev/log")

        self._command = CommandServer(self)

        try:
            yield from self._command.run()
        except PermissionError as ex:
            self._command = None
            warn("command service cannot be started: {0}", ex)
コード例 #14
0
    def force_log_level(self, level=None):
        """
        Specifies the *minimum* logging level that will be applied to all syslog entries.
        This is primarily useful for debugging, where you want to override any limitations
        imposed on log file entries.

        As a (convenient) side-effect, if the level is DEBUG, then debug features of both
        asyncio as well as chaperone will be enabled.

        If level is not provided, then returns the current setting.
        """
        if level is None:
            return self._minimum_syslog_level

        levid = syslog_info.PRIORITY_DICT.get(level.lower(), None)
        if not levid:
            raise Exception("Not a valid log level: {0}".format(level))
        set_log_level(levid)
        self._minimum_syslog_level = levid
        self.debug = (levid == syslog_info.LOG_DEBUG)
        if self._syslog:
            self._syslog.reset_minimum_priority(levid)
        info("Forcing all log output to '{0}' or greater", level)
コード例 #15
0
ファイル: process_manager.py プロジェクト: farukc/chaperone
    def force_log_level(self, level = None):
        """
        Specifies the *minimum* logging level that will be applied to all syslog entries.
        This is primarily useful for debugging, where you want to override any limitations
        imposed on log file entries.

        As a (convenient) side-effect, if the level is DEBUG, then debug features of both
        asyncio as well as chaperone will be enabled.

        If level is not provided, then returns the current setting.
        """
        if level is None:
            return self._minimum_syslog_level

        levid = syslog_info.PRIORITY_DICT.get(level.lower(), None)
        if not levid:
            raise Exception("Not a valid log level: {0}".format(level))
        set_log_level(levid)
        self._minimum_syslog_level = levid
        self.debug = (levid == syslog_info.LOG_DEBUG)
        if self._syslog:
            self._syslog.reset_minimum_priority(levid)
        info("Forcing all log output to '{0}' or greater", level)
コード例 #16
0
    def _start_system_services(self):

        self._notify_enabled = yield from self.notify.connect()

        self._syslog = SyslogServer()
        self._syslog.configure(self._config, self._minimum_syslog_level)

        try:
            yield from self._syslog.run()
        except PermissionError as ex:
            self._syslog = None
            warn("syslog service cannot be started: {0}", ex)
        else:
            self._syslog.capture_python_logging()
            info("Switching all chaperone logging to /dev/log")

        self._command = CommandServer(self)

        try:
            yield from self._command.run()
        except PermissionError as ex:
            self._command = None
            warn("command service cannot be started: {0}", ex)
コード例 #17
0
ファイル: subproc.py プロジェクト: CivilPol/chaperone
 def loginfo(self, *args, **kwargs):
     info(*args, facility=self.syslog_facility, **kwargs)
コード例 #18
0
 def loginfo(self, *args, **kwargs):
     info(*args, facility=self.syslog_facility, **kwargs)