示例#1
0
    def test_key_not_present(self):
        p = TestPlugin()
        e = EtcdSynchronizer(p, "10.0.0.1", "local", None, "clearwater")

        thread = Thread(target=e.main_wrapper)
        thread.daemon = True
        thread.start()

        sleep(1)
        p._on_config_changed.assert_called_with("default_value", None)

        # Allow the EtcdSynchronizer to exit
        e._terminate_flag = True
        sleep(1)
示例#2
0
    def test_synchronisation(self):
        p = TestPlugin()
        e = EtcdSynchronizer(p, "10.0.0.1", "local", None, "clearwater")
        # Write some initial data into the key
        e._client.write("/clearwater/local/configuration/test", "initial data")

        thread = Thread(target=e.main_wrapper)
        thread.daemon = True
        thread.start()

        sleep(1)
        # Write a new value into etcd, and check that the plugin is called with
        # it
        e._client.write("/clearwater/local/configuration/test", "hello world")
        sleep(1)
        p._on_config_changed.assert_called_with("hello world", None)

        # Allow the EtcdSynchronizer to exit
        e._terminate_flag = True
        sleep(1)
示例#3
0
def main(args):
    syslog.openlog("config-manager", syslog.LOG_PID)
    pdlogs.STARTUP.log()
    try:
        arguments = docopt(__doc__, argv=args)
    except DocoptExit:
        pdlogs.EXITING_BAD_CONFIG.log()
        raise

    local_ip = arguments['--local-ip']
    local_site = arguments['--local-site']
    etcd_key = arguments['--etcd-key']
    log_dir = arguments['--log-directory']
    log_level = LOG_LEVELS.get(arguments['--log-level'], logging.DEBUG)

    stdout_err_log = os.path.join(log_dir, "config-manager.output.log")

    if not arguments['--foreground']:
        utils.daemonize(stdout_err_log)

    # Process names are limited to 15 characters, so abbreviate
    prctl.prctl(prctl.NAME, "cw-config-mgr")

    logging_config.configure_logging(log_level,
                                     log_dir,
                                     "config-manager",
                                     show_thread=True)

    # urllib3 logs a WARNING log whenever it recreates a connection, but our
    # etcd usage does this frequently (to allow watch timeouts), so deliberately
    # ignore this log
    urllib_logger = logging.getLogger('urllib3')
    urllib_logger.setLevel(logging.ERROR)

    utils.install_sigusr1_handler("config-manager")

    # Drop a pidfile. We must keep a reference to the file object here, as this keeps
    # the file locked and provides extra protection against two processes running at
    # once.
    pidfile_lock = None
    try:
        pidfile_lock = utils.lock_and_write_pid_file(
            arguments['--pidfile'])  # noqa
    except IOError:
        # We failed to take the lock - another process is already running
        exit(1)

    plugins_dir = "/usr/share/clearwater/clearwater-config-manager/plugins/"
    plugins = load_plugins_in_dir(plugins_dir)
    plugins.sort(key=lambda x: x.key())
    synchronizers = []
    threads = []

    files = [p.file() for p in plugins]
    alarm = ConfigAlarm(files)

    # Load the plugins, but don't start them until we've installed the SIGTERM
    # handler, as that handler will gracefully shut down any running
    # synchronizers on receiving a SIGTERM
    for plugin in plugins:
        syncer = EtcdSynchronizer(plugin, local_ip, local_site, alarm,
                                  etcd_key)
        synchronizers.append(syncer)
        threads.append(syncer.thread)
        _log.info("Loaded plugin %s" % plugin)

    utils.install_sigterm_handler(synchronizers)

    # Now start the plugin threads
    for syncer in synchronizers:
        syncer.start_thread()
        _log.info("Started thread for plugin %s" % syncer._plugin)

    while any([thr.isAlive() for thr in threads]):
        for thr in threads:
            if thr.isAlive():
                thr.join(1)

    while not utils.should_quit:
        sleep(1)

    _log.info("Clearwater Configuration Manager shutting down")
    pdlogs.EXITING.log()
    syslog.closelog()