Implémentation d'un gestionnaire d'événements sommaire.

This commit is contained in:
Pierre-Elliott Bécue 2015-03-10 16:41:15 +01:00
parent 6c97d6998f
commit 201377528c
12 changed files with 411 additions and 239 deletions

View file

@ -8,7 +8,8 @@
#
# Author : Pierre-Elliott Bécue <becue@crans.org>
# License : GPLv3
# Date : 29/04/2014
# Date : 10/03/2015
"""Main program for trigger library"""
import argparse
import cPickle
@ -24,21 +25,21 @@ from gestion.trigger.host import trigger_service
import cranslib.clogger as clogger
import cmb
hostname = socket.gethostname().split(".")[0]
logger = clogger.CLogger("trigger", "trigger", trigger_config.log_level, trigger_config.debug)
HOSTNAME = socket.gethostname().split(".")[0]
LOGGER = clogger.CLogger("trigger", "trigger", trigger_config.log_level, trigger_config.debug)
# Ce bloc contient le peu de "magie" de la librairie, on utilise les services listés dans config/trigger.py
# comme référence. Pour éviter toute redondance, la commande importe donc les services utiles suivant cette
# config. Leur import ne sert pas directemet, il permet juste de peupler la TriggerFactory contenue dans
# config. Leur import ne sert pas directement, il permet juste de peupler la TriggerFactory contenue dans
# gestion/trigger/host.py.
# Il faut donc bien importer ces fichiers, mais ils ne sont pas utilisés directement ensuite.
import importlib
services = {}
for config_service in trigger_config.services[hostname]:
SERVICES = {}
for config_service in trigger_config.services[HOSTNAME]:
try:
services[config_service] = importlib.import_module("gestion.trigger.services.%s" % (config_service,))
SERVICES[config_service] = importlib.import_module("gestion.trigger.services.%s" % (config_service,))
except Exception as e:
logger.critical("Fatal : import of %s failed, see following traceback. %s", config_service, traceback.format_exc())
LOGGER.critical("Fatal : import of %s failed, see following traceback. %s", config_service, traceback.format_exc())
class EvenementListener(cmb.AsynchronousConsumer):
"""
@ -64,18 +65,20 @@ class EvenementListener(cmb.AsynchronousConsumer):
#origin = properties.app_id
#message_id = properties.message_id
body = cPickle.loads(body)
logger.info('Received message # %s from %s: %s',
LOGGER.info('Received message # %s from %s: %s',
basic_deliver.delivery_tag, properties.app_id, body)
# On tente d'invoquer le trigger attendu, à l'aide de la méthode trigger
# about contient le nom de la fonction à appeler, body lui est filé en argument.
try:
if about in trigger_config.services[hostname]:
trigger_service(about)(body)
if about in trigger_config.services[HOSTNAME]:
trigger_service(about)(*body)
else:
raise AttributeError
except AttributeError:
logger.warning('No suitable trigger found for message # %s from %s: %s on host %s. Discarding it.',
basic_deliver.delivery_tag, properties.app_id, body, hostname)
LOGGER.warning('No suitable trigger found for message # %s from %s: %s on host %s. Discarding it.',
basic_deliver.delivery_tag, properties.app_id, body, HOSTNAME)
self.acknowledge_message(basic_deliver.delivery_tag)
def run(self):
@ -83,54 +86,56 @@ class EvenementListener(cmb.AsynchronousConsumer):
starting the IOLoop to block and allow the SelectConnection to operate.
"""
logger.info("""Crans Message Broker
LOGGER.info("""Crans Message Broker
+--------------------------------------------+
| Welcome on Trigger |
+--------------------------------------------+""")
self._connection = self.connect()
for service in trigger_config.services[hostname]:
self.add_queue("trigger-%s-%s" % (hostname, service), "trigger.%s" % (service,))
for service in trigger_config.services[HOSTNAME]:
self.add_queue("trigger-%s-%s" % (HOSTNAME, service), "trigger.%s" % (service,))
self._connection.ioloop.start()
def daemonize():
"""Runs the script in "background"."""
trigger_password = secrets.get('rabbitmq_trigger_password')
credentials = pika.PlainCredentials(trigger_config.user, trigger_password)
listener = EvenementListener(url=trigger_config.master, exchange_name="trigger", exchange_type="topic", port=trigger_config.port, credentials=credentials, ssl=trigger_config.ssl)
try:
listener.run()
except KeyboardInterrupt:
logger.warning("Caught SIGINT, will now go for shutdown.")
LOGGER.warning("Caught SIGINT, will now go for shutdown.")
listener.stop()
if __name__ == '__main__':
# We use a parser to capture all possible arguments designed for one host
parser = argparse.ArgumentParser(description="Initier une régénération de services.", add_help=False)
parser.add_argument('-a', '--all', help="Régénération complète des services sur l'hôte %s." % (hostname,), action="store_true")
parser.add_argument('-d', '--daemon', help="Écouter sur civet en arrière plan.", action="store_true")
parser.add_argument('-h', '--help', help="Affiche ce message et quitte.", action="store_true")
PARSER = argparse.ArgumentParser(description="Initier une régénération de services.", add_help=False)
PARSER.add_argument('-a', '--all', help="Régénération complète des services sur l'hôte %s." % (HOSTNAME,), action="store_true")
PARSER.add_argument('-d', '--daemon', help="Écouter en arrière plan.", action="store_true")
PARSER.add_argument('-h', '--help', help="Affiche ce message et quitte.", action="store_true")
# For each service supposingly managed by host, generate one parser option
# Deuxième petit morceau "magique" du code.
for arg_service in trigger_config.services[hostname]:
parser.add_argument('--%s' % (arg_service,), help="Force la régénération du service %s." % (arg_service,), action="store_true")
args = parser.parse_args()
for arg_service in trigger_config.services[HOSTNAME]:
PARSER.add_argument('--%s' % (arg_service,), help="Force la régénération du service %s." % (arg_service,), action="store_true")
ARGS = PARSER.parse_args()
if args.help:
parser.print_help()
if ARGS.help:
PARSER.print_help()
sys.exit(0)
elif args.all:
elif ARGS.all:
# Regenerates all services availables, don't crash on nonexistant ones
for host_service in trigger_config.services[hostname]:
for host_service in trigger_config.services[HOSTNAME]:
try:
print affichage.style(" (Ré)Génération du service %s" % (host_service,), "cyan")
trigger_service(host_service)(True)
except AttributeError:
print "No suitable trigger handle found for service %s on host %s" % (host_service, hostname)
elif args.daemon:
print "No suitable trigger handle found for service %s on host %s" % (host_service, HOSTNAME)
elif ARGS.daemon:
# Daemonize the trigger app, in order to listen and execute commands from civet.
daemonize()
else:
# If not all and not daemon, try all services one by one.
for arg_service in trigger_config.services[hostname]:
if getattr(args, arg_service, False) == True:
for arg_service in trigger_config.services[HOSTNAME]:
if getattr(ARGS, arg_service, False) == True:
print affichage.style(" (Ré)Génération du service %s" % (arg_service,), "cyan")
trigger_service(arg_service)(True)