From 2d5b4ef4d03aefe1ca17ace925b5c7dbe48deb82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Fri, 18 Nov 2016 18:49:02 +0100 Subject: [PATCH] Add test for spare daemons --- alignak/daemon.py | 8 +- alignak/daemons/arbiterdaemon.py | 86 +++++++++++-------- alignak/daemons/brokerdaemon.py | 5 +- alignak/dispatcher.py | 34 +++++--- alignak/http/arbiter_interface.py | 5 ++ alignak/objects/config.py | 71 +++++++++------ alignak/util.py | 51 +++++++---- test/alignak_test.py | 2 +- .../arbiter/daemons/broker-spare.cfg | 2 +- .../arbiter/daemons/poller-spare.cfg | 2 +- .../arbiter/daemons/receiver-spare.cfg | 2 +- .../arbiter/daemons/scheduler-spare.cfg | 2 +- .../daemons/arbiter.ini | 4 +- test/test_launch_daemons_spare.py | 63 ++++++-------- 14 files changed, 201 insertions(+), 136 deletions(-) diff --git a/alignak/daemon.py b/alignak/daemon.py index c2030716e..e75d6174c 100644 --- a/alignak/daemon.py +++ b/alignak/daemon.py @@ -224,8 +224,12 @@ class Daemon(object): BoolProp(default=False), 'daemon_enabled': BoolProp(default=True), - 'spare': - BoolProp(default=False), + # Todo: spare is not present currently in the daemon.ini file + # 'spare': + # BoolProp(default=False), + # Todo: missing daemon.ini port parameter! + 'port': + IntegerProp(default=0), 'max_queue_size': IntegerProp(default=0), 'daemon_thread_pool_size': diff --git a/alignak/daemons/arbiterdaemon.py b/alignak/daemons/arbiterdaemon.py index cf45dc864..0dd38b084 100644 --- a/alignak/daemons/arbiterdaemon.py +++ b/alignak/daemons/arbiterdaemon.py @@ -99,7 +99,7 @@ class Arbiter(Daemon): # pylint: disable=R0902 }) def __init__(self, config_file, monitoring_files, is_daemon, do_replace, verify_only, debug, - debug_file, config_name, analyse=None): + debug_file, arbiter_name, analyse=None): super(Arbiter, self).__init__('arbiter', config_file, is_daemon, do_replace, debug, debug_file) @@ -107,7 +107,7 @@ def __init__(self, config_file, monitoring_files, is_daemon, do_replace, verify_ self.config_files = monitoring_files self.verify_only = verify_only self.analyse = analyse - self.config_name = config_name + self.arbiter_name = arbiter_name self.broks = {} self.is_master = False @@ -254,9 +254,11 @@ def load_monitoring_config_file(self): # pylint: disable=R0915 self.conf.early_arbiter_linking() - # Search which Arbiterlink I am + # Search which arbiter I am in the arbiters list for arb in self.conf.arbiters: - if arb.get_name() in ['Default-Arbiter', self.config_name]: + if arb.get_name() in ['Default-Arbiter', self.arbiter_name]: + logger.info("Found myself in the configuration: %s", arb.get_name()) + # Arbiter is master one arb.need_conf = False self.myself = arb self.is_master = not self.myself.spare @@ -276,6 +278,8 @@ def load_monitoring_config_file(self): # pylint: disable=R0915 # Set myself as alive ;) self.myself.alive = True else: # not me + # Arbiter is not me! + logger.info("Found another arbiter in the configuration: %s", arb.get_name()) arb.need_conf = True if not self.myself: @@ -283,7 +287,7 @@ def load_monitoring_config_file(self): # pylint: disable=R0915 "To solve this, please change the arbiter_name parameter in " "the arbiter configuration file (certainly arbiter-master.cfg) " "with the value '%s'." - " Thanks." % (self.config_name, socket.gethostname())) + " Thanks." % (self.arbiter_name, socket.gethostname())) # Ok it's time to load the module manager now! self.load_modules_manager() @@ -410,7 +414,7 @@ def load_monitoring_config_file(self): # pylint: disable=R0915 self.conf.show_errors() sys.exit(0) - if self.analyse: + if self.analyse: # pragma: no cover, not used currently (see #607) self.launch_analyse() sys.exit(0) @@ -420,18 +424,18 @@ def load_monitoring_config_file(self): # pylint: disable=R0915 self.conf.prepare_for_sending() # Ignore daemon configuration parameters (port, log, ...) in the monitoring configuration - # It's better to use daemon default parameters rather than host found in the monitoring - # configuration... + # It's better to use daemon default parameters rather than those found in the monitoring + # configuration (if some are found because they should not be there)... self.accept_passive_unknown_check_results = BoolProp.pythonize( getattr(self.myself, 'accept_passive_unknown_check_results', '0') ) # We need to set self.host & self.port to be used by do_daemon_init_and_start - self.host = self.myself.address - self.port = self.myself.port + # self.host = self.myself.address + # self.port = self.myself.port - logger.info("Configuration Loaded") + logger.info("Configuration loaded and prepared") # Still a last configuration check because some things may have changed when # we prepared the configuration for sending @@ -492,7 +496,7 @@ def load_modules_configuration_objects(self, raw_objects): len(objs[prop]), type_c, inst.get_name()) def launch_analyse(self): - """Print the number of objects we have for each type. + """ Dump the number of objects we have for each type to a JSON formatted file :return: None """ @@ -556,7 +560,7 @@ def main(self): else: self.request_stop() - except SystemExit, exp: + except SystemExit as exp: # With a 2.4 interpreter the sys.exit() in load_config_file # ends up here and must be handled. sys.exit(exp.code) @@ -565,27 +569,37 @@ def main(self): raise def setup_new_conf(self): - """ Setup a new conf received from a Master arbiter. + """ Setup a new configuration received from a Master arbiter. + Todo: perharps we should not accept the configuration or raise an error if we do not + find our own configuration data in the data. Thus this should never happen... :return: None """ with self.conf_lock: - conf = self.new_conf - if not conf: + if not self.new_conf: + logger.warning("Should not be here - I already got a configuration") return + + logger.info("I received a new configuration from my master") + try: - conf = unserialize(conf) + conf = unserialize(self.new_conf) except AlignakClassLookupException as exp: - logger.error('Cannot un-serialize configuration received from arbiter: %s', exp) - self.new_conf = None + logger.exception('Cannot un-serialize received configuration: %s', exp) + return + + logger.info("Got new configuration #%s", conf.magic_hash) + + logger.info("I am: %s", self.arbiter_name) + # This is my new configuration now ... self.cur_conf = conf self.conf = conf + # Ready to get a new one ... + self.new_conf = None for arb in self.conf.arbiters: - if (arb.address, arb.port) == (self.host, self.port): + if arb.get_name() in ['Default-Arbiter', self.arbiter_name]: self.myself = arb - arb.is_me = lambda x: True # we now definitively know who we are, just keep it. - else: - arb.is_me = lambda x: False # and we know who we are not, just keep it. + logger.info("I found myself in the configuration") def do_loop_turn(self): """Loop turn for Arbiter @@ -595,8 +609,8 @@ def do_loop_turn(self): """ # If I am a spare, I wait for the master arbiter to send me # true conf. - if self.myself.spare: - logger.debug("I wait for master") + if not self.is_master: + logger.info("Waiting for master...") self.wait_for_master_death() if self.must_run: @@ -608,33 +622,34 @@ def wait_for_master_death(self): :return: None """ - logger.info("Waiting for master death") timeout = 1.0 - self.last_master_speack = time.time() + self.last_master_ping = time.time() # Look for the master timeout master_timeout = 300 for arb in self.conf.arbiters: if not arb.spare: master_timeout = arb.check_interval * arb.max_check_attempts - logger.info("I'll wait master for %d seconds", master_timeout) + logger.warning("I'll wait master for %d seconds", master_timeout) while not self.interrupted: # This is basically sleep(timeout) and returns 0, [], int # We could only paste here only the code "used" but it could be # harder to maintain. _, _, tcdiff = self.handle_requests(timeout) - # if there was a system Time Change (tcdiff) then we have to adapt last_master_speak: + # if there was a system Time Change (tcdiff) then we have to adapt last_master_ping: + if tcdiff: + self.last_master_ping += tcdiff + if self.new_conf: self.setup_new_conf() - if tcdiff: - self.last_master_speack += tcdiff + sys.stdout.write(".") sys.stdout.flush() # Now check if master is dead or not now = time.time() - if now - self.last_master_speack > master_timeout: + if now - self.last_master_ping > master_timeout: logger.info("Arbiter Master is dead. The arbiter %s take the lead", self.myself.get_name()) for arb in self.conf.arbiters: @@ -685,16 +700,19 @@ def run(self): # Before running, I must be sure who am I # The arbiters change, so we must re-discover the new self.me for arb in self.conf.arbiters: - if arb.get_name() in ['Default-Arbiter', self.config_name]: + if arb.get_name() in ['Default-Arbiter', self.arbiter_name]: self.myself = arb + logger.info("I am the arbiter: %s", self.myself.arbiter_name) - logger.info("Begin to dispatch configurations to satellites") + logger.info("Begin to dispatch configuration to the satellites") + logger.warning('Configuration sent to dispatcher: %s / %s', self.conf.uuid, self.conf.magic_hash) self.dispatcher = Dispatcher(self.conf, self.myself) self.dispatcher.check_alive() self.dispatcher.check_dispatch() # REF: doc/alignak-conf-dispatching.png (3) self.dispatcher.prepare_dispatch() self.dispatcher.dispatch() + logger.info("Configuration has been dispatched to the satellites") # Now we can get all initial broks for our satellites self.get_initial_broks_from_satellitelinks() diff --git a/alignak/daemons/brokerdaemon.py b/alignak/daemons/brokerdaemon.py index df38050a2..cca5759a2 100644 --- a/alignak/daemons/brokerdaemon.py +++ b/alignak/daemons/brokerdaemon.py @@ -471,11 +471,12 @@ def setup_new_conf(self): # pylint: disable=R0915,R0912 statsd_host=self.statsd_host, statsd_port=self.statsd_port, statsd_prefix=self.statsd_prefix, statsd_enabled=self.statsd_enabled) - logger.debug("[%s] Sending us configuration %s", self.name, conf) + logger.warning("[%s] Sending us configuration %s", self.name, conf) # If we've got something in the schedulers, we do not # want it anymore # self.schedulers.clear() + logger.warning("[%s] schedulers: %s", self.name, conf['schedulers']) for sched_id in conf['schedulers']: # Must look if we already have it to do not overdie our broks @@ -517,6 +518,7 @@ def setup_new_conf(self): # pylint: disable=R0915,R0912 logger.info(" - %s ", daemon['name']) # Now get arbiter + logger.warning("[%s] arbiters: %s", self.name, conf['arbiters']) for arb_id in conf['arbiters']: # Must look if we already have it already_got = arb_id in self.arbiters @@ -551,6 +553,7 @@ def setup_new_conf(self): # pylint: disable=R0915,R0912 logger.info(" - %s ", daemon['name']) # Now for pollers + logger.warning("[%s] pollers: %s", self.name, conf['pollers']) for pol_id in conf['pollers']: # Must look if we already have it already_got = pol_id in self.pollers diff --git a/alignak/dispatcher.py b/alignak/dispatcher.py index ae27a9858..f4e039a7a 100644 --- a/alignak/dispatcher.py +++ b/alignak/dispatcher.py @@ -80,6 +80,7 @@ def __init__(self, conf, arbiter): self.arbiter = arbiter # Pointer to the whole conf self.conf = conf + logger.warning('Dispatcher configuration: %s / %s', self.conf.uuid, self.conf.magic_hash) self.realms = conf.realms # Direct pointer to important elements for us @@ -172,19 +173,21 @@ def check_dispatch(self): # Check if the other arbiter has a conf, but only if I am a master for arb in self.arbiters: # If not me and I'm a master - if arb != self.arbiter and self.arbiter and not self.arbiter.spare: + if self.arbiter and arb != self.arbiter and not self.arbiter.spare: + logger.info('Configuration to dispatch: #%s (%d bytes)', + self.conf.magic_hash, len(self.conf.whole_conf_pack)) if not arb.have_conf(self.conf.magic_hash): - if not hasattr(self.conf, 'whole_conf_pack'): - logger.error('CRITICAL: the arbiter try to send a configuration but ' - 'it is not a MASTER one?? Look at your configuration.') - continue - logger.info('Configuration sent to arbiter: %s', arb.get_name()) + logger.info('Sending configuration #%s to arbiter: %s', + self.conf.magic_hash, arb.get_name()) + test = self.conf.whole_conf_pack.split('magic_hash') arb.put_conf(self.conf.whole_conf_pack) # Remind it that WE are the master here! arb.do_not_run() + logger.info('Configuration sent to arbiter: %s', arb.get_name()) else: # Ok, it already has the conf. I remember that # it does not have to run, I'm still alive! + logger.debug("Do not send configuration") arb.do_not_run() # We check for confs to be dispatched on alive schedulers. If not dispatched, need @@ -224,9 +227,9 @@ def check_dispatch(self): sched.need_conf = True sched.conf = None - self.check_disptach_other_satellites() + self.check_dispatch_other_satellites() - def check_disptach_other_satellites(self): + def check_dispatch_other_satellites(self): """ Check the dispatch in other satellites: reactionner, poller, broker, receiver @@ -531,16 +534,19 @@ def prepare_dispatch_other_satellites(self, sat_type, realm, cfg, arbiters_cfg): satellite_string = "[%s] Dispatching %s satellites ordered as: " % ( realm.get_name(), sat_type) for sat in satellites: - satellite_string += '%s (spare:%s), ' % ( - sat.get_name(), str(sat.spare)) + satellite_string += '%s (spare:%s), ' % (sat.get_name(), str(sat.spare)) logger.info(satellite_string) conf_uuid = cfg.uuid # Now we dispatch cfg to every one ask for it nb_cfg_prepared = 0 for sat in satellites: - if nb_cfg_prepared >= realm.get_nb_of_must_have_satellites(sat_type): - continue + # Todo: Remove this test, because the number of satellites per type in a realm + # do not take care of the spare daemons + # if nb_cfg_prepared >= realm.get_nb_of_must_have_satellites(sat_type): + # logger.warning("Already prepared enough satellites: %d / %s", + # nb_cfg_prepared, sat_type) + # continue sat.cfg['schedulers'][conf_uuid] = realm.to_satellites[sat_type][conf_uuid] if sat.manage_arbiters: sat.cfg['arbiters'] = arbiters_cfg @@ -573,6 +579,7 @@ def dispatch(self): """ if self.dispatch_ok: return + self.dispatch_ok = True for scheduler in self.schedulers: if scheduler.is_sent: @@ -593,7 +600,8 @@ def dispatch(self): if satellite.get_my_type() == sat_type: if satellite.is_sent: continue - logger.info('Sending configuration to %s %s', sat_type, satellite.get_name()) + logger.info('Sending configuration to %s %s: %s', + sat_type, satellite.get_name(), satellite.cfg) is_sent = satellite.put_conf(satellite.cfg) satellite.is_sent = is_sent if not is_sent: diff --git a/alignak/http/arbiter_interface.py b/alignak/http/arbiter_interface.py index fda36322e..e50126c12 100644 --- a/alignak/http/arbiter_interface.py +++ b/alignak/http/arbiter_interface.py @@ -50,6 +50,8 @@ def have_conf(self, magic_hash=0): return self.app.cur_conf and self.app.cur_conf.magic_hash == magic_hash @cherrypy.expose + @cherrypy.tools.json_in() + @cherrypy.tools.json_out() def put_conf(self, conf=None): """HTTP POST to the arbiter with the new conf (master send to slave) @@ -57,6 +59,9 @@ def put_conf(self, conf=None): :type conf: :return: None """ + # if conf is None: + # confs = cherrypy.request.json + # conf = confs['conf'] with self.app.conf_lock: super(ArbiterInterface, self).put_conf(conf) self.app.must_run = False diff --git a/alignak/objects/config.py b/alignak/objects/config.py index d2d21b682..53ad3851a 100644 --- a/alignak/objects/config.py +++ b/alignak/objects/config.py @@ -775,23 +775,39 @@ def __init__(self, params=None, parsing=True): setattr(self, prop, clss({})) super(Config, self).__init__(params, parsing=parsing) + + if 'magic_hash' in params: + # We restore the magic_hash if it exists in the parameters + self.magic_hash = params['magic_hash'] + else: + # We tag the conf with a magic_hash, a random value to + random.seed(time.time()) + self.magic_hash = random.randint(1, 100000) + self.params = {} self.resource_macros_names = [] # By default the conf is correct and the warnings and errors lists are empty self.conf_is_correct = True self.configuration_warnings = [] self.configuration_errors = [] - # We tag the conf with a magic_hash, a random value to - # identify this conf - random.seed(time.time()) - self.magic_hash = random.randint(1, 100000) self.triggers_dirs = [] self.packs_dirs = [] def serialize(self): + """ + Serialize the whole monitoring configuration. This is to build a configuration that + will be sent to the spare arbiter. + :return: + """ + saved_magic_hash = self.magic_hash res = super(Config, self).serialize() + + # Special properties to serialize + res['macros'] = self.macros + res['magic_hash'] = saved_magic_hash if hasattr(self, 'instance_id'): res['instance_id'] = self.instance_id + # The following are not in properties so not in the dict for prop in ['triggers', 'packs', 'hosts', 'services', 'hostgroups', 'notificationways', @@ -800,12 +816,13 @@ def serialize(self): 'servicegroups', 'timeperiods', 'commands', 'escalations', 'ocsp_command', 'ochp_command', 'host_perfdata_command', 'service_perfdata_command', - 'global_host_event_handler', 'global_service_event_handler']: - if getattr(self, prop) is None: + 'global_host_event_handler', 'global_service_event_handler', + 'arbiters', 'pollers', 'brokers', 'schedulers', 'receivers', 'reactionners']: + if getattr(self, prop, None) is None: res[prop] = None else: res[prop] = getattr(self, prop).serialize() - res['macros'] = self.macros + return res def get_name(self): @@ -1224,7 +1241,7 @@ def early_arbiter_linking(self): :return: None """ - + logger.debug("Arbiters in the configuration: %s", self.arbiters) if len(self.arbiters) == 0: logger.warning("There is no arbiter, I add one in localhost:7770") arb = ArbiterLink({'arbiter_name': 'Default-Arbiter', @@ -1386,13 +1403,14 @@ def prepare_for_sending(self): :return: None """ + logger.info('Prepare the configuration sending') + # Preparing hosts and hostgroups for sending. Some properties # should be "flatten" before sent, like .realm object that should # be changed into names self.hosts.prepare_for_sending() self.hostgroups.prepare_for_sending() t01 = time.time() - logger.info('[Arbiter] Serializing the configurations...') # There are two ways of configuration serializing # One if to use the serial way, the other is with use_multiprocesses_serializer @@ -1401,24 +1419,25 @@ def prepare_for_sending(self): if os.name == 'nt' or not self.use_multiprocesses_serializer: logger.info('Using the default serialization pass') for realm in self.realms: - for (i, conf) in realm.confs.iteritems(): + for realm_conf in realm.confs.values(): # Remember to protect the local conf hostgroups too! - conf.hostgroups.prepare_for_sending() - logger.debug('[%s] Serializing the configuration %d', realm.get_name(), i) + realm_conf.hostgroups.prepare_for_sending() + logger.info("Serializing the '%s' realm configuration", realm.get_name()) t00 = time.time() - conf_id = conf.uuid - realm.serialized_confs[conf_id] = serialize(conf) - logger.debug("[config] time to serialize the conf %s:%s is %s (size:%s)", - realm.get_name(), i, time.time() - t00, - len(realm.serialized_confs[conf_id])) - logger.debug("SERIALIZE LEN : %d", len(realm.serialized_confs[conf_id])) - # Now serialize the whole conf, for easy and quick spare send + conf_id = realm_conf.uuid + realm.serialized_confs[conf_id] = serialize(realm_conf) + logger.info("Serialized the '%s' realm configuration: %s seconds (length: %s)", + realm.get_name(), time.time() - t00, + len(realm.serialized_confs[conf_id])) + + # Now serialize the whole conf, for easy and quick spare master send t00 = time.time() - whole_conf_pack = serialize(self) - logger.debug("[config] time to serialize the global conf : %s (size:%s)", - time.time() - t00, len(whole_conf_pack)) - self.whole_conf_pack = whole_conf_pack - logger.debug("[config]serializing total: %s", (time.time() - t01)) + logger.info("Serializing the global configuration, uuid: %s, #%s", + self.uuid, self.magic_hash) + self.whole_conf_pack_magic_hash = self.magic_hash + self.whole_conf_pack = serialize(self) + logger.info("Serialized the global configuration, #%s, %s seconds (length: %s)", + self.magic_hash, time.time() - t00, len(self.whole_conf_pack)) else: # pragma: no cover, not used currently (see #606) # Todo: #606, what was it done for? @@ -1431,7 +1450,7 @@ def prepare_for_sending(self): child_q = manager.list() for realm in self.realms: processes = [] - for (i, conf) in realm.confs.iteritems(): + for (i, realm_conf) in realm.confs.iteritems(): def serialize_config(comm_q, rname, cid, conf): """Serialized config. Used in subprocesses to serialize all config faster @@ -1453,7 +1472,7 @@ def serialize_config(comm_q, rname, cid, conf): # Prepare a sub-process that will manage the serialize computation proc = Process(target=serialize_config, name="serializer-%s-%d" % (realm.get_name(), i), - args=(child_q, realm.get_name(), i, conf)) + args=(child_q, realm.get_name(), i, realm_conf)) proc.start() processes.append((i, proc)) diff --git a/alignak/util.py b/alignak/util.py index 38bd455ff..72aa226c7 100644 --- a/alignak/util.py +++ b/alignak/util.py @@ -1267,32 +1267,51 @@ def is_complex_expr(expr): def parse_daemon_args(arbiter=False): """Generic parsing function for daemons + Arbiter only: + "-a", "--arbiter": Monitored configuration file(s), + (multiple -a can be used, and they will be concatenated to make a global configuration + file) + "-V", "--verify-config": Verify configuration file(s) and exit + "-n", "--config-name": Set the name of the arbiter to pick in the configuration files. + This allows an arbiter to find its own configuration in the whole Alignak configuration + Using this parameter is mandatory when several arbiters are existing in the + configuration to determine which one is the master/spare. The spare arbiter must be + launched with this parameter! + + All daemons: + '-c', '--config': Daemon configuration file (ini file) + '-d', '--daemon': Run as a daemon + '-r', '--replace': Replace previous running daemon + '-f', '--debugfile': File to dump debug logs + + :param arbiter: Do we parse args for arbiter? :type arbiter: bool :return: args - - TODO : Remove, profile, name, migrate, analyse opt from code """ - parser = argparse.ArgumentParser(version="%(prog)s " + VERSION) + parser = argparse.ArgumentParser(version='%(prog)s ' + VERSION) if arbiter: parser.add_argument('-a', '--arbiter', action='append', required=True, - dest="monitoring_files", - help='Monitored configuration file(s),' - 'multiple -a can be used, and they will be concatenated. ') - parser.add_argument("-V", "--verify-config", dest="verify_only", action="store_true", - help="Verify config file and exit") - parser.add_argument("-n", "--config-name", dest="config_name", + dest='monitoring_files', + help='Monitored configuration file(s), ' + '(multiple -a can be used, and they will be concatenated ' + 'to make a global configuration file)') + parser.add_argument('-V', '--verify-config', dest='verify_only', action='store_true', + help='Verify configuration file(s) and exit') + parser.add_argument('-n', '--arbiter-name', dest='arbiter_name', default='arbiter-master', - help="Use name of arbiter defined in the configuration files " - "(default arbiter-master)") + help='Set the name of the arbiter to pick in the configuration files ' + 'For a spare arbiter, this parameter must contain its name!') - parser.add_argument('-c', '--config', dest="config_file", + parser.add_argument('-s', '--spare', dest='config_file', + help='Daemon is a spare daemon') + parser.add_argument('-c', '--config', dest='config_file', help='Daemon configuration file') - parser.add_argument('-d', '--daemon', dest="is_daemon", action='store_true', + parser.add_argument('-d', '--daemon', dest='is_daemon', action='store_true', help='Run as a daemon') - parser.add_argument('-r', '--replace', dest="do_replace", action='store_true', + parser.add_argument('-r', '--replace', dest='do_replace', action='store_true', help='Replace previous running daemon') - parser.add_argument('--debugfile', dest="debug_file", - help="File to dump debug logs") + parser.add_argument('-f', '--debugfile', dest='debug_file', + help='File to dump debug logs') return parser.parse_args() diff --git a/test/alignak_test.py b/test/alignak_test.py index 8c50daa1a..96e7b2f7d 100644 --- a/test/alignak_test.py +++ b/test/alignak_test.py @@ -231,7 +231,7 @@ def setup_with_file(self, configuration_file): raise for arb in self.arbiter.conf.arbiters: - if arb.get_name() == self.arbiter.config_name: + if arb.get_name() == self.arbiter.arbiter_name: self.arbiter.myself = arb self.arbiter.dispatcher = Dispatcher(self.arbiter.conf, self.arbiter.myself) self.arbiter.dispatcher.prepare_dispatch() diff --git a/test/cfg/alignak_full_run_spare/arbiter/daemons/broker-spare.cfg b/test/cfg/alignak_full_run_spare/arbiter/daemons/broker-spare.cfg index 263db450a..3ae8ee664 100755 --- a/test/cfg/alignak_full_run_spare/arbiter/daemons/broker-spare.cfg +++ b/test/cfg/alignak_full_run_spare/arbiter/daemons/broker-spare.cfg @@ -18,7 +18,7 @@ define broker { port 17772 ## Realm - realm All + #realm All ## Modules # Default: None diff --git a/test/cfg/alignak_full_run_spare/arbiter/daemons/poller-spare.cfg b/test/cfg/alignak_full_run_spare/arbiter/daemons/poller-spare.cfg index 0a1320ee2..b92c682f0 100755 --- a/test/cfg/alignak_full_run_spare/arbiter/daemons/poller-spare.cfg +++ b/test/cfg/alignak_full_run_spare/arbiter/daemons/poller-spare.cfg @@ -12,7 +12,7 @@ define poller { port 17771 ## Realm - realm All + #realm All ## Modules # Default: None diff --git a/test/cfg/alignak_full_run_spare/arbiter/daemons/receiver-spare.cfg b/test/cfg/alignak_full_run_spare/arbiter/daemons/receiver-spare.cfg index f21a01772..a8bde97eb 100755 --- a/test/cfg/alignak_full_run_spare/arbiter/daemons/receiver-spare.cfg +++ b/test/cfg/alignak_full_run_spare/arbiter/daemons/receiver-spare.cfg @@ -10,7 +10,7 @@ define receiver { port 17773 ## Realm - realm All + #realm All ## Modules # Default: None diff --git a/test/cfg/alignak_full_run_spare/arbiter/daemons/scheduler-spare.cfg b/test/cfg/alignak_full_run_spare/arbiter/daemons/scheduler-spare.cfg index 95e61cc9b..c7f18cb04 100755 --- a/test/cfg/alignak_full_run_spare/arbiter/daemons/scheduler-spare.cfg +++ b/test/cfg/alignak_full_run_spare/arbiter/daemons/scheduler-spare.cfg @@ -17,7 +17,7 @@ define scheduler { port 17768 ## Realm - realm All + #realm All ## Modules # Default: None diff --git a/test/cfg/alignak_full_run_spare/daemons/arbiter.ini b/test/cfg/alignak_full_run_spare/daemons/arbiter.ini index 772ce47a2..f3e1bfd6b 100755 --- a/test/cfg/alignak_full_run_spare/daemons/arbiter.ini +++ b/test/cfg/alignak_full_run_spare/daemons/arbiter.ini @@ -9,7 +9,7 @@ etcdir=/tmp/etc/alignak # The daemon will chdir into the directory workdir when launched # It will create its pid file in the working dir -pidfile=%(workdir)s/arbiter.pid +pidfile=%(workdir)s/arbiter-master.pid #-- Username and group to run (defaults to current user) #user=alignak @@ -35,7 +35,7 @@ use_ssl=0 #-- Local log management -- # Enabled by default to ease troubleshooting #use_local_log=1 -local_log=%(logdir)s/arbiter.log +local_log=%(logdir)s/arbiter-master.log # Log with a formatted human date #human_timestamp_log=1 #human_date_format=%Y-%m-%d %H:%M:%S %Z diff --git a/test/test_launch_daemons_spare.py b/test/test_launch_daemons_spare.py index b8a59037f..85ef20044 100644 --- a/test/test_launch_daemons_spare.py +++ b/test/test_launch_daemons_spare.py @@ -71,7 +71,7 @@ def run_and_check_alignak_daemons(self, runtime=10, spare_daemons= []): 'scheduler', 'scheduler-spare'] print("Cleaning pid and log files...") - for daemon in ['arbiter', 'arbiter-spare'] + daemons_list: + for daemon in ['arbiter-master', 'arbiter-spare'] + daemons_list: if os.path.exists('/tmp/%s.pid' % daemon): os.remove('/tmp/%s.pid' % daemon) print("- removed /tmp/%s.pid" % daemon) @@ -90,6 +90,27 @@ def run_and_check_alignak_daemons(self, runtime=10, spare_daemons= []): subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print("- %s launched (pid=%d)" % (daemon, self.procs[daemon].pid)) + # Let the daemons start ... + sleep(1) + + print("Launching spare arbiter...") + # Note the -n parameter in the comand line arguments! + args = ["../alignak/bin/alignak_arbiter.py", + "-c", "cfg/alignak_full_run_spare/daemons/arbiter-spare.ini", + "-a", "cfg/alignak_full_run_spare/alignak.cfg", + "-n", "arbiter-spare"] + self.procs['arbiter-spare'] = \ + subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + print("- %s launched (pid=%d)" % ('arbiter-spare', self.procs['arbiter-spare'].pid)) + + print("Launching master arbiter...") + args = ["../alignak/bin/alignak_arbiter.py", + "-c", "cfg/alignak_full_run_spare/daemons/arbiter.ini", + "-a", "cfg/alignak_full_run_spare/alignak.cfg"] + self.procs['arbiter-master'] = \ + subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + print("- %s launched (pid=%d)" % ('arbiter-master', self.procs['arbiter-master'].pid)) + sleep(1) print("Testing daemons start") @@ -104,46 +125,13 @@ def run_and_check_alignak_daemons(self, runtime=10, spare_daemons= []): assert ret is None, "Daemon %s not started!" % name print("- %s running (pid=%d)" % (name, self.procs[daemon].pid)) - # Let the daemons start ... - sleep(1) - - # print("Launching spare arbiter...") - # args = ["../alignak/bin/alignak_arbiter.py", - # "-c", "cfg/alignak_full_run_spare/daemons/arbiter-spare.ini", - # "-a", "cfg/alignak_full_run_spare/alignak.cfg"] - # self.procs['arbiter-spare'] = \ - # subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - # print("- %s launched (pid=%d)" % ('arbiter-spare', self.procs['arbiter-spare'].pid)) - - print("Launching master arbiter...") - args = ["../alignak/bin/alignak_arbiter.py", - "-c", "cfg/alignak_full_run_spare/daemons/arbiter.ini", - "-a", "cfg/alignak_full_run_spare/alignak.cfg"] - self.procs['arbiter'] = \ - subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - print("- %s launched (pid=%d)" % ('arbiter', self.procs['arbiter'].pid)) - - sleep(5) - - name = 'arbiter' - print("Testing Arbiter start %s" % name) - ret = self.procs[name].poll() - if ret is not None: - print("*** %s exited on start!" % (name)) - for line in iter(self.procs[name].stdout.readline, b''): - print(">>> " + line.rstrip()) - for line in iter(self.procs[name].stderr.readline, b''): - print(">>> " + line.rstrip()) - assert ret is None, "Daemon %s not started!" % name - print("- %s running (pid=%d)" % (name, self.procs[name].pid)) - # Let the arbiter build and dispatch its configuration # Let the schedulers get their configuration and run the first checks sleep(runtime) print("Get information from log files...") nb_errors = 0 - for daemon in ['arbiter'] + daemons_list: + for daemon in ['arbiter-master', 'arbiter-spare'] + daemons_list: assert os.path.exists('/tmp/%s.log' % daemon), '/tmp/%s.log does not exist!' % daemon daemon_errors = False print("-----\n%s log file\n-----\n" % daemon) @@ -156,14 +144,15 @@ def run_and_check_alignak_daemons(self, runtime=10, spare_daemons= []): print(line[:-1]) daemon_errors = True nb_errors += 1 - assert nb_errors == 0, "Error logs raised!" - print("No error logs raised when daemons loaded the modules") print("Stopping the daemons...") for name, proc in self.procs.items(): print("Asking %s to end..." % name) os.kill(self.procs[name].pid, signal.SIGTERM) + assert nb_errors == 0, "Error logs raised!" + print("No error logs raised when daemons loaded the modules") + def test_daemons_spare(self): """ Running the Alignak daemons for a spare configuration