3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-27 21:19:31 +01:00
PyLink/coremods/control.py
2016-06-21 11:25:47 -07:00

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)