def _no_processes(self, ignore_service_state=False): if not (ignore_service_state or self._services_started): return # do not react during system initialization self._all_killed = True if not self._killing_system: if not self.detect_exit: return if self._family: ss = self._family.get_scheduled_services() if ss: warn( "system will remain active since there are scheduled services: " + ", ".join(s.name for s in ss)) return # Passed all checks, now kill system self.notify.stopping() debug("Final termination phase.") self._services_started = False if self._kill_future and not self._kill_future.cancelled(): self._kill_future.cancel() self.activate(self._final_system_stop())
def _no_processes(self, ignore_service_state = False): if not (ignore_service_state or self._services_started): return # do not react during system initialization self._all_killed = True if not self._killing_system: if not self.detect_exit: return if self._family: ss = self._family.get_scheduled_services() if ss: warn("system will remain active since there are scheduled services: " + ", ".join(s.name for s in ss)) return # Passed all checks, now kill system self.notify.stopping() debug("Final termination phase.") self._services_started = False if self._kill_future and not self._kill_future.cancelled(): self._kill_future.cancel() self.activate(self._final_system_stop())
def terminate(self): proc = self._proc otherpid = self.pid if proc: if otherpid == proc.pid: otherpid = None if proc.returncode is None: if self.service.kill_signal is not None: # explicitly check service self.logdebug("using {0} to terminate {1}", get_signal_name(self.kill_signal), self.name) proc.send_signal(self.kill_signal) else: proc.terminate() if otherpid: self.logdebug("using {0} to terminate {1}", get_signal_name(self.kill_signal), self.name) try: os.kill(otherpid, self.kill_signal) except Exception as ex: warn("{0} could not be killed using PID={1}: ".format( ex, otherpid)) self._pid = None
def startup_done(): if options['--ignore-failures']: warn("ignoring failures on all service startups due to --ignore-failures") if options['--disable-services'] and services: warn("services will not be configured due to --disable-services") extra_services = None if cmd: cmdsvc = ServiceConfig.createConfig(config=config, name="CONSOLE", exec_args=[cmd] + options['<args>'], uid=user, kill_signal=("SIGHUP" if tty else None), setpgrp=not tty, exit_kills=kill_switch, service_groups="IDLE", ignore_failures=not options['--task'], stderr='inherit', stdout='inherit') extra_services = [cmdsvc] yield from tlp.run_services(extra_services, disable_others = options['--disable-services']) tlp.signal_ready()
def run_services(self, extra_services, disable_others=False): "Run all services." # First, determine our overall configuration for the services environment. services = self._config.get_services() if extra_services: services = services.deepcopy() if disable_others: for s in services.values(): s.enabled = False for s in extra_services: services.add(s) family = self._family = SubProcessFamily(self, services) tried_any = False errno = None try: tried_any = yield from family.run() except asyncio.CancelledError: pass finally: self._services_started = True if self.detect_exit: if not tried_any: warn( "No service startups attempted (all disabled?) - exiting due to 'detect_exit=true'" ) self.kill_system() else: self._watcher.check_processes()
def run_services(self, extra_services, disable_others = False): "Run all services." # First, determine our overall configuration for the services environment. services = self._config.get_services() if extra_services: services = services.deepcopy() if disable_others: for s in services.values(): s.enabled = False for s in extra_services: services.add(s) family = self._family = SubProcessFamily(self, services) tried_any = False errno = None try: tried_any = yield from family.run() except asyncio.CancelledError: pass finally: self._services_started = True if self.detect_exit: if not tried_any: warn("No service startups attempted (all disabled?) - exiting due to 'detect_exit=true'") self.kill_system() else: self._watcher.check_processes()
def startup_done(): if options['--ignore-failures']: warn("ignoring failures on all service startups due to --ignore-failures") if options['--disable-services'] and services: warn("services will not be configured due to --disable-services") extra_services = None if cmd: cmdsvc = ServiceConfig.createConfig(config=config, name="CONSOLE", exec_args=[cmd] + options['<args>'], uid=user, kill_signal=("SIGHUP" if tty else None), setpgrp=not tty, exit_kills=kill_switch, service_groups="IDLE", ignore_failures=not options['--task'], stderr='inherit', stdout='inherit') extra_services = [cmdsvc] yield from tlp.run_services(extra_services, disable_others = options['--disable-services']) tlp.signal_ready()
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)
def kill_system(self, errno = None, force = False): """ Systematically shuts down the system. With the 'force' argument set to true, does so even if a kill is already in progress. """ if force: self._services_started = True elif self._killing_system: return if self._exitcode is None and errno is not None: self._exitcode = 1 # default exit for an error self.notify.error(errno) warn("Request made to kill system." + ((force and " (forced)") or "")) self._killing_system = True self._kill_future = asyncio.async(self._kill_system_co())
def kill_system(self, errno=None, force=False): """ Systematically shuts down the system. With the 'force' argument set to true, does so even if a kill is already in progress. """ if force: self._services_started = True elif self._killing_system: return if self._exitcode is None and errno != 0: self._exitcode = 1 # default exit for an error self.notify.error(errno) warn("Request made to kill system." + ((force and " (forced)") or "")) self._killing_system = True self._kill_future = asyncio.ensure_future(self._kill_system_co())
def do_startup_pause(self): """ Wait a short time just to see if the process errors out immediately. This avoids a retry loop and catches any immediate failures now. Can be used by process implementations if needed. """ if not self.startup_pause: return try: result = yield from self.timed_wait(self.startup_pause) except asyncio.TimeoutError: result = None if result is not None and not result.normal_exit: if self.ignore_failures: warn("{0} (ignored) failure on start-up with result '{1}'".format(self.name, result)) else: raise ChProcessError("{0} failed on start-up with result '{1}'".format(self.name, result), resultcode = result)
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)
def do_startup_pause(self): """ Wait a short time just to see if the process errors out immediately. This avoids a retry loop and catches any immediate failures now. Can be used by process implementations if needed. """ if not self.startup_pause: return try: result = yield from self.timed_wait(self.startup_pause) except asyncio.TimeoutError: result = None if result is not None and not result.normal_exit: if self.ignore_failures: warn("{0} (ignored) failure on start-up with result '{1}'". format(self.name, result)) else: raise ChProcessError( "{0} failed on start-up with result '{1}'".format( self.name, result), resultcode=result)
def terminate(self): proc = self._proc otherpid = self.pid if proc: if otherpid == proc.pid: otherpid = None if proc.returncode is None: if self.service.kill_signal is not None: # explicitly check service self.logdebug("using {0} to terminate {1}", get_signal_name(self.kill_signal), self.name) proc.send_signal(self.kill_signal) else: proc.terminate() if otherpid: self.logdebug("using {0} to terminate {1}", get_signal_name(self.kill_signal), self.name) try: os.kill(otherpid, self.kill_signal) except Exception as ex: warn("{0} could not be killed using PID={1}: ".format(ex, otherpid)) self._pid = None
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)
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)
def logwarn(self, *args, **kwargs): warn(*args, facility=self.syslog_facility, **kwargs)
def logwarn(self, *args, **kwargs): warn(*args, facility=self.syslog_facility, **kwargs)