示例#1
0
 def set_up(self, test_case):
     super(BrokerServiceHelper, self).set_up(test_case)
     test_case.broker_service.startService()
     # Use different reactor to simulate separate processes
     self._connector = RemoteBrokerConnector(
         FakeReactor(), test_case.broker_service.config)
     deferred = self._connector.connect()
     test_case.remote = test_case.successResultOf(deferred)
示例#2
0
class MonitorService(LandscapeService):
    """
    The core Twisted Service which creates and runs all necessary monitoring
    components when started.
    """

    service_name = Monitor.name

    def __init__(self, config):
        self.persist_filename = os.path.join(config.data_path,
                                             "%s.bpickle" % self.service_name)
        super(MonitorService, self).__init__(config)
        self.plugins = self.get_plugins()
        self.monitor = Monitor(self.reactor,
                               self.config,
                               self.persist,
                               persist_filename=self.persist_filename)
        self.publisher = ComponentPublisher(self.monitor, self.reactor,
                                            self.config)

    def get_plugins(self):
        return [
            namedClass("landscape.client.monitor.%s.%s" %
                       (plugin_name.lower(), plugin_name))()
            for plugin_name in self.config.plugin_factories
        ]

    def startService(self):
        """Start the monitor."""
        super(MonitorService, self).startService()
        self.publisher.start()

        def start_plugins(broker):
            self.broker = broker
            self.monitor.broker = broker
            for plugin in self.plugins:
                self.monitor.add(plugin)
            return self.broker.register_client(self.service_name)

        self.connector = RemoteBrokerConnector(self.reactor, self.config)
        connected = self.connector.connect()
        return connected.addCallback(start_plugins)

    def stopService(self):
        """Stop the monitor.

        The monitor is flushed to ensure that things like persist databases
        get saved to disk.
        """
        deferred = self.publisher.stop()
        self.monitor.flush()
        self.connector.disconnect()
        super(MonitorService, self).stopService()
        return deferred
示例#3
0
    def set_up(self, test_case):
        super(RemoteBrokerHelper, self).set_up(test_case)

        self._publisher = ComponentPublisher(test_case.broker,
                                             test_case.reactor,
                                             test_case.config)
        self._connector = RemoteBrokerConnector(test_case.reactor,
                                                test_case.config)

        self._publisher.start()
        deferred = self._connector.connect()
        test_case.remote = test_case.successResultOf(deferred)
示例#4
0
class ManagerService(LandscapeService):
    """
    The core Twisted Service which creates and runs all necessary managing
    components when started.
    """

    service_name = Manager.name

    def __init__(self, config):
        super(ManagerService, self).__init__(config)
        self.plugins = self.get_plugins()
        self.manager = Manager(self.reactor, self.config)
        self.publisher = ComponentPublisher(self.manager, self.reactor,
                                            self.config)

    def get_plugins(self):
        """Return instances of all the plugins enabled in the configuration."""
        return [
            namedClass("landscape.client.manager.%s.%s" %
                       (plugin_name.lower(), plugin_name))()
            for plugin_name in self.config.plugin_factories
        ]

    def startService(self):
        """Start the manager service.

        This method does 3 things, in this order:

          - Start listening for connections on the manager socket.
          - Connect to the broker.
          - Add all configured plugins, that will in turn register themselves.
        """
        super(ManagerService, self).startService()
        self.publisher.start()

        def start_plugins(broker):
            self.broker = broker
            self.manager.broker = broker
            for plugin in self.plugins:
                self.manager.add(plugin)
            return self.broker.register_client(self.service_name)

        self.connector = RemoteBrokerConnector(self.reactor, self.config)
        connected = self.connector.connect()
        return connected.addCallback(start_plugins)

    def stopService(self):
        """Stop the manager and close the connection with the broker."""
        self.connector.disconnect()
        self.publisher.stop()
        super(ManagerService, self).stopService()
示例#5
0
    def startService(self):
        """Start the monitor."""
        super(MonitorService, self).startService()
        self.publisher.start()

        def start_plugins(broker):
            self.broker = broker
            self.monitor.broker = broker
            for plugin in self.plugins:
                self.monitor.add(plugin)
            return self.broker.register_client(self.service_name)

        self.connector = RemoteBrokerConnector(self.reactor, self.config)
        connected = self.connector.connect()
        return connected.addCallback(start_plugins)
示例#6
0
def run_task_handler(cls, args, reactor=None):
    if reactor is None:
        reactor = LandscapeReactor()

    config = cls.config_factory()
    config.load(args)

    for directory in [config.package_directory, config.hash_id_directory]:
        if not os.path.isdir(directory):
            os.mkdir(directory)

    program_name = cls.queue_name
    lock_filename = os.path.join(config.package_directory,
                                 program_name + ".lock")
    try:
        lock_path(lock_filename)
    except LockError:
        if config.quiet:
            raise SystemExit()
        raise SystemExit("error: package %s is already running"
                         % program_name)

    words = re.findall("[A-Z][a-z]+", cls.__name__)
    init_logging(config, "-".join(word.lower() for word in words))

    # Setup our umask for Apt to use, this needs to setup file permissions to
    # 0o644 so...
    os.umask(0o022)

    package_store = cls.package_store_class(config.store_filename)
    # Delay importing of the facades so that we don't
    # import Apt unless we need to.
    from landscape.lib.apt.package.facade import AptFacade
    package_facade = AptFacade()

    def finish():
        connector.disconnect()
        reactor.call_later(0, reactor.stop)

    def got_error(failure):
        log_failure(failure)
        finish()

    connector = RemoteBrokerConnector(reactor, config, retry_on_reconnect=True)
    remote = LazyRemoteBroker(connector)
    handler = cls(package_store, package_facade, remote, config, reactor)
    result = Deferred()
    result.addCallback(lambda x: handler.run())
    result.addCallback(lambda x: finish())
    result.addErrback(got_error)
    reactor.call_when_running(lambda: result.callback(None))
    reactor.run()

    return result
示例#7
0
class BrokerServiceHelper(FakeBrokerServiceHelper):
    """
    Provides what L{FakeBrokerServiceHelper} does, and makes it a
    'live' service using a real L{RemoteBroker} connected over AMP.

    This adds the following attributes to your test case:
     - remote: A connected L{RemoteBroker}.
    """
    def set_up(self, test_case):
        super(BrokerServiceHelper, self).set_up(test_case)
        test_case.broker_service.startService()
        # Use different reactor to simulate separate processes
        self._connector = RemoteBrokerConnector(
            FakeReactor(), test_case.broker_service.config)
        deferred = self._connector.connect()
        test_case.remote = test_case.successResultOf(deferred)

    def tear_down(self, test_case):
        self._connector.disconnect()
        test_case.broker_service.stopService()
示例#8
0
    def test_start_stop(self):
        """
        The L{BrokerService.startService} method makes the process start
        listening to the broker socket, and starts the L{Exchanger} and
        the L{Pinger} as well.
        """
        self.service.exchanger.start = Mock()
        self.service.pinger.start = Mock()
        self.service.exchanger.stop = Mock()

        self.service.startService()
        reactor = FakeReactor()
        connector = RemoteBrokerConnector(reactor, self.config)
        connected = connector.connect()
        connected.addCallback(lambda remote: remote.get_server_uuid())
        connected.addCallback(lambda x: connector.disconnect())
        connected.addCallback(lambda x: self.service.stopService())

        self.service.exchanger.start.assert_called_with()
        self.service.pinger.start.assert_called_with()
        self.service.exchanger.stop.assert_called_with()
示例#9
0
    def startService(self):
        """Start the manager service.

        This method does 3 things, in this order:

          - Start listening for connections on the manager socket.
          - Connect to the broker.
          - Add all configured plugins, that will in turn register themselves.
        """
        super(ManagerService, self).startService()
        self.publisher.start()

        def start_plugins(broker):
            self.broker = broker
            self.manager.broker = broker
            for plugin in self.plugins:
                self.manager.add(plugin)
            return self.broker.register_client(self.service_name)

        self.connector = RemoteBrokerConnector(self.reactor, self.config)
        connected = self.connector.connect()
        return connected.addCallback(start_plugins)
示例#10
0
class RemoteBrokerHelper(BrokerServerHelper):
    """Setup a connected L{RemoteBroker}.

    This helper extends L{BrokerServerHelper}.by adding a L{RemoteBroker} which
    exposes the L{BrokerServer} instance remotely via our AMP-based machinery.

    IMPORTANT: note that the connection is created using a *real* Unix socket,
    calling L{FakeReactor.call_unix} which in turn defers to the *real* Twisted
    reactor. This means that all calls to the L{RemoteBroker} instance will
    be truly asynchronous and tests will need to return deferreds in order to
    let the reactor run. See also::

        http://twistedmatrix.com/documents/current/core/howto/testing.html

    and the "Leave the Reactor as you found it" paragraph to understand how
    to write tests interacting with the reactor.

    The following attributes will be set in your test case:

      - C{remote}: A C{RemoteObject} connected to the broker server.
    """
    def set_up(self, test_case):
        super(RemoteBrokerHelper, self).set_up(test_case)

        self._publisher = ComponentPublisher(test_case.broker,
                                             test_case.reactor,
                                             test_case.config)
        self._connector = RemoteBrokerConnector(test_case.reactor,
                                                test_case.config)

        self._publisher.start()
        deferred = self._connector.connect()
        test_case.remote = test_case.successResultOf(deferred)

    def tear_down(self, test_case):
        self._connector.disconnect()
        self._publisher.stop()
        super(RemoteBrokerHelper, self).tear_down(test_case)
示例#11
0
    def __init__(self,
                 reactor=reactor,
                 verbose=False,
                 config=None,
                 broker=None,
                 monitor=None,
                 manager=None,
                 enabled_daemons=None):
        landscape_reactor = LandscapeReactor()
        if enabled_daemons is None:
            enabled_daemons = [Broker, Monitor, Manager]
        if broker is None and Broker in enabled_daemons:
            broker = Broker(RemoteBrokerConnector(landscape_reactor, config),
                            verbose=verbose,
                            config=config.config)
        if monitor is None and Monitor in enabled_daemons:
            monitor = Monitor(RemoteMonitorConnector(landscape_reactor,
                                                     config),
                              verbose=verbose,
                              config=config.config)
        if manager is None and Manager in enabled_daemons:
            manager = Manager(RemoteManagerConnector(landscape_reactor,
                                                     config),
                              verbose=verbose,
                              config=config.config)

        self.broker = broker
        self.monitor = monitor
        self.manager = manager
        self.daemons = [
            daemon for daemon in [self.broker, self.monitor, self.manager]
            if daemon
        ]
        self.reactor = reactor
        self._checking = None
        self._stopping = False
        signal.signal(
            signal.SIGUSR1, lambda signal, frame: reactor.callFromThread(
                self._notify_rotate_logs))
        if config is not None and config.clones > 0:
            options = [
                "--clones",
                str(config.clones), "--start-clones-over",
                str(config.start_clones_over)
            ]
            for daemon in self.daemons:
                daemon.options = options

        self._ping_failures = {}
示例#12
0
    def test_wb_is_lazy(self):
        """
        The L{LazyRemoteBroker} class doesn't initialize the actual remote
        broker until one of its attributes gets actually accessed.
        """
        reactor = FakeReactor()
        connector = RemoteBrokerConnector(reactor, self.broker_service.config)
        self.broker = LazyRemoteBroker(connector)
        self.assertIs(self.broker._remote, None)

        def close_connection(result):
            self.assertTrue(result)
            connector.disconnect()

        result = self.broker.ping()
        return result.addCallback(close_connection)