mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-25 12:12:53 +01:00
3a57e8d595
Closes #240.
78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
"""
|
|
control.py - Implements SHUTDOWN and REHASH functionality.
|
|
"""
|
|
import signal
|
|
import os
|
|
|
|
from pylinkirc import world, utils, conf, classes
|
|
from pylinkirc.log import log
|
|
|
|
def _shutdown(irc=None):
|
|
"""Shuts down the Pylink daemon."""
|
|
for name, plugin in world.plugins.items():
|
|
# Before closing connections, tell all plugins to shutdown cleanly first.
|
|
if hasattr(plugin, 'die'):
|
|
log.debug('coreplugin: Running die() on plugin %s due to shutdown.', name)
|
|
try:
|
|
plugin.die(irc)
|
|
except: # But don't allow it to crash the server.
|
|
log.exception('coreplugin: Error occurred in die() of plugin %s, skipping...', name)
|
|
|
|
for ircobj in world.networkobjects.values():
|
|
# Disconnect all our networks. Disable auto-connect first by setting
|
|
# the time to negative.
|
|
ircobj.serverdata['autoconnect'] = -1
|
|
ircobj.disconnect()
|
|
|
|
def sigterm_handler(_signo, _stack_frame):
|
|
"""Handles SIGTERM gracefully by shutting down the PyLink daemon."""
|
|
log.info("Shutting down on SIGTERM.")
|
|
_shutdown()
|
|
|
|
signal.signal(signal.SIGTERM, sigterm_handler)
|
|
|
|
def _rehash():
|
|
"""Rehashes the PyLink daemon."""
|
|
old_conf = conf.conf.copy()
|
|
fname = conf.fname
|
|
new_conf = conf.loadConf(fname, errors_fatal=False)
|
|
new_conf = conf.validateConf(new_conf)
|
|
conf.conf = new_conf
|
|
for network, ircobj in world.networkobjects.copy().items():
|
|
# Server was removed from the config file, disconnect them.
|
|
log.debug('rehash: checking if %r is in new conf still.', network)
|
|
if network not in new_conf['servers']:
|
|
log.debug('rehash: removing connection to %r (removed from config).', network)
|
|
# Disable autoconnect first.
|
|
ircobj.serverdata['autoconnect'] = -1
|
|
ircobj.disconnect()
|
|
del world.networkobjects[network]
|
|
else:
|
|
ircobj.conf = new_conf
|
|
ircobj.serverdata = new_conf['servers'][network]
|
|
ircobj.botdata = new_conf['bot']
|
|
|
|
# Clear the IRC object's channel loggers and replace them with
|
|
# new ones by re-running logSetup().
|
|
while ircobj.loghandlers:
|
|
log.removeHandler(ircobj.loghandlers.pop())
|
|
|
|
ircobj.logSetup()
|
|
|
|
# TODO: update file loggers here too.
|
|
|
|
for network, sdata in new_conf['servers'].items():
|
|
# New server was added. Connect them if not already connected.
|
|
if network not in world.networkobjects:
|
|
proto = utils.getProtocolModule(sdata['protocol'])
|
|
world.networkobjects[network] = classes.Irc(network, proto, new_conf)
|
|
|
|
if os.name == 'posix':
|
|
# Only register SIGHUP on *nix.
|
|
def sighup_handler(_signo, _stack_frame):
|
|
"""Handles SIGHUP by rehashing the PyLink daemon."""
|
|
log.info("SIGHUP received, reloading config.")
|
|
_rehash()
|
|
|
|
signal.signal(signal.SIGHUP, sighup_handler)
|