def command_restart(opts): """Restart a running Sopel instance. :param opts: parsed arguments :type opts: :class:`argparse.Namespace` """ # Get Configuration try: settings = utils.load_settings(opts) except config.ConfigurationNotFound as error: tools.stderr('Configuration "%s" not found' % error.filename) return ERR_CODE if settings.core.not_configured: tools.stderr('Sopel is not configured, can\'t stop') return ERR_CODE # Configure logging logger.setup_logging(settings) # Get Sopel's PID filename = get_pid_filename(settings, settings.core.pid_dir) pid = get_running_pid(filename) if pid is None or not tools.check_pid(pid): tools.stderr('Sopel is not running!') return ERR_CODE tools.stderr('Asking Sopel to restart') if hasattr(signal, 'SIGUSR2'): os.kill(pid, signal.SIGUSR2) else: # Windows will not generate SIGILL itself # https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal os.kill(pid, signal.SIGILL)
def setup_logging(self): logger.setup_logging(self.settings) base_level = self.settings.core.logging_level or 'INFO' base_format = self.settings.core.logging_format base_datefmt = self.settings.core.logging_datefmt # configure channel logging if required by configuration if self.settings.core.logging_channel: channel_level = self.settings.core.logging_channel_level or base_level channel_format = self.settings.core.logging_channel_format or base_format channel_datefmt = self.settings.core.logging_channel_datefmt or base_datefmt channel_params = {} if channel_format: channel_params['fmt'] = channel_format if channel_datefmt: channel_params['datefmt'] = channel_datefmt formatter = logger.ChannelOutputFormatter(**channel_params) handler = logger.IrcLoggingHandler(self, channel_level) handler.setFormatter(formatter) # set channel handler to `sopel` logger LOGGER = logging.getLogger('sopel') LOGGER.addHandler(handler)
def command_stop(opts): """Stop a running Sopel instance""" # Get Configuration try: settings = utils.load_settings(opts) except config.ConfigurationNotFound as error: tools.stderr('Configuration "%s" not found' % error.filename) return ERR_CODE if settings.core.not_configured: tools.stderr('Sopel is not configured, can\'t stop') return ERR_CODE # Configure logging logger.setup_logging(settings) # Get Sopel's PID filename = get_pid_filename(opts, settings.core.pid_dir) pid = get_running_pid(filename) if pid is None or not tools.check_pid(pid): tools.stderr('Sopel is not running!') return ERR_CODE # Stop Sopel if opts.kill: tools.stderr('Killing the Sopel') os.kill(pid, signal.SIGKILL) return tools.stderr('Signaling Sopel to stop gracefully') if hasattr(signal, 'SIGUSR1'): os.kill(pid, signal.SIGUSR1) else: # Windows will not generate SIGTERM itself # https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/signal os.kill(pid, signal.SIGTERM)
def run(config, pid_file, daemon=False): delay = 20 # Inject ca_certs from config to web for SSL validation of web requests if not config.core.ca_certs: tools.stderr( 'Could not open CA certificates file. SSL will not work properly!') def signal_handler(sig, frame): if sig == signal.SIGUSR1 or sig == signal.SIGTERM or sig == signal.SIGINT: tools.stderr('Got quit signal, shutting down.') p.quit('Closing') elif sig == signal.SIGUSR2 or sig == signal.SIGILL: tools.stderr('Got restart signal.') p.restart('Restarting') # Define empty variable `p` for bot p = None while True: if p and p.hasquit: # Check if `hasquit` was set for bot during disconnected phase break try: p = bot.Sopel(config, daemon=daemon) if hasattr(signal, 'SIGUSR1'): signal.signal(signal.SIGUSR1, signal_handler) if hasattr(signal, 'SIGTERM'): signal.signal(signal.SIGTERM, signal_handler) if hasattr(signal, 'SIGINT'): signal.signal(signal.SIGINT, signal_handler) if hasattr(signal, 'SIGUSR2'): signal.signal(signal.SIGUSR2, signal_handler) if hasattr(signal, 'SIGILL'): signal.signal(signal.SIGILL, signal_handler) logger.setup_logging(p) p.run(config.core.host, int(config.core.port)) except KeyboardInterrupt: break except Exception: # TODO: Be specific trace = traceback.format_exc() try: tools.stderr(trace) except Exception: # TODO: Be specific pass logfile = open(os.path.join(config.core.logdir, 'exceptions.log'), 'a') logfile.write('Critical exception in core') logfile.write(trace) logfile.write('----------------------------------------\n\n') logfile.close() # TODO: This should be handled by command_start # All we should need here is a return value, but replacing the # os._exit() call below (at the end) broke ^C. # This one is much harder to test, so until that one's sorted it # isn't worth the risk of trying to remove this one. os.unlink(pid_file) os._exit(1) if not isinstance(delay, int): break if p.wantsrestart: return -1 if p.hasquit: break tools.stderr('Warning: Disconnected. Reconnecting in %s seconds...' % delay) time.sleep(delay) # TODO: This should be handled by command_start # All we should need here is a return value, but making this # a return makes Sopel hang on ^C after it says "Closed!" os.unlink(pid_file) os._exit(0)
def setup_logging(self): logger.setup_logging(self)
def run(settings, pid_file, daemon=False): delay = 20 # Inject ca_certs from config to web for SSL validation of web requests if not settings.core.ca_certs: tools.stderr( 'Could not open CA certificates file. SSL will not work properly!') def signal_handler(sig, frame): if sig == signal.SIGUSR1 or sig == signal.SIGTERM or sig == signal.SIGINT: tools.stderr('Got quit signal, shutting down.') p.quit('Closing') elif sig == signal.SIGUSR2 or sig == signal.SIGILL: tools.stderr('Got restart signal.') p.restart('Restarting') # Define empty variable `p` for bot p = None while True: if p and p.hasquit: # Check if `hasquit` was set for bot during disconnected phase break try: p = bot.Sopel(settings, daemon=daemon) if hasattr(signal, 'SIGUSR1'): signal.signal(signal.SIGUSR1, signal_handler) if hasattr(signal, 'SIGTERM'): signal.signal(signal.SIGTERM, signal_handler) if hasattr(signal, 'SIGINT'): signal.signal(signal.SIGINT, signal_handler) if hasattr(signal, 'SIGUSR2'): signal.signal(signal.SIGUSR2, signal_handler) if hasattr(signal, 'SIGILL'): signal.signal(signal.SIGILL, signal_handler) logger.setup_logging(p) p.run(settings.core.host, int(settings.core.port)) except KeyboardInterrupt: break except Exception: # TODO: Be specific trace = traceback.format_exc() try: tools.stderr(trace) except Exception: # TODO: Be specific pass logfile = open(os.path.join(settings.core.logdir, 'exceptions.log'), 'a') logfile.write('Critical exception in core') logfile.write(trace) logfile.write('----------------------------------------\n\n') logfile.close() # TODO: This should be handled by command_start # All we should need here is a return value, but replacing the # os._exit() call below (at the end) broke ^C. # This one is much harder to test, so until that one's sorted it # isn't worth the risk of trying to remove this one. os.unlink(pid_file) os._exit(1) if not isinstance(delay, int): break if p.wantsrestart: return -1 if p.hasquit: break tools.stderr( 'Warning: Disconnected. Reconnecting in %s seconds...' % delay) time.sleep(delay) # TODO: This should be handled by command_start # All we should need here is a return value, but making this # a return makes Sopel hang on ^C after it says "Closed!" os.unlink(pid_file) os._exit(0)