Esempio n. 1
0
def run(args=sys.argv):
    """Send a message to Landscape.

    This function runs a Twisted reactor, prints various status
    messages, and exits the process.
    """
    reactor = LandscapeReactor()
    config = Configuration()
    config.load(args)

    def got_connection(broker):
        result = broker.get_accepted_message_types()
        return result.addCallback(got_accepted_types, broker, args)

    def got_error(failure):
        log_failure(failure)

    connector = RemoteBrokerConnector(reactor, config)
    result = connector.connect()
    result.addCallback(got_connection)
    result.addErrback(got_error)
    result.addBoth(lambda x: connector.disconnect())

    # For some obscure reason our LandscapeReactor.stop method calls
    # reactor.crash() instead of reactor.stop(), which doesn't work
    # here. Maybe LandscapeReactor.stop should simply use reactor.stop().
    result.addBoth(lambda ignored: reactor.call_later(
        0, reactor._reactor.stop))

    reactor.run()

    return result
Esempio n. 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.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.
        """
        self.publisher.stop()
        self.monitor.flush()
        self.connector.disconnect()
        super(MonitorService, self).stopService()
Esempio n. 3
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.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()
Esempio n. 4
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)
Esempio n. 5
0
def run_task_handler(cls, args, reactor=None):
    # please only pass reactor when you have totally mangled everything with
    # mocker. Otherwise bad things will happen.
    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
    # 0644 so...
    os.umask(022)

    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.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)
    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
Esempio n. 6
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)
Esempio n. 7
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 = filter(None, [self.broker, self.monitor, self.manager])
        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 = {}
Esempio n. 8
0
def register(config,
             on_message=print_text,
             on_error=sys.exit,
             reactor=None,
             max_retries=14):
    """Instruct the Landscape Broker to register the client.

    The broker will be instructed to reload its configuration and then to
    attempt a registration.

    @param reactor: The reactor to use.  Please only pass reactor when you
        have totally mangled everything with mocker.  Otherwise bad things
        will happen.
    @param max_retries: The number of times to retry connecting to the
        landscape client service.  The delay between retries is calculated
        by Twisted and increases geometrically.  The default of 14 results in
        a total wait time of about 70 seconds.

        initialDelay = 0.05
        factor =  1.62
        maxDelay = 30
        max_retries = 14

        0.05 * (1 - 1.62 ** 14) / (1 - 1.62) = 69 seconds
   """
    if reactor is None:
        reactor = LandscapeReactor()
    exit_with_error = []

    def stop(errors):
        if not config.ok_no_register:
            for error in errors:
                if error is not None:
                    exit_with_error.append(error)
        connector.disconnect()
        reactor.stop()

    def failure():
        on_message("Invalid account name or " "registration key.", error=True)
        return 2

    def success():
        on_message("System successfully registered.")

    def exchange_failure():
        on_message(
            "We were unable to contact the server. "
            "Your internet connection may be down. "
            "The landscape client will continue to try and contact "
            "the server periodically.",
            error=True)
        return 2

    def handle_registration_errors(failure):
        # We'll get invalid credentials through the signal.
        failure.trap(InvalidCredentialsError, MethodCallError)
        connector.disconnect()

    def catch_all(failure):
        on_message(failure.getTraceback(), error=True)
        on_message("Unknown error occurred.", error=True)
        return [2]

    on_message("Please wait... ", "")

    time.sleep(2)

    def got_connection(remote):
        handlers = {
            "registration-done": success,
            "registration-failed": failure,
            "exchange-failed": exchange_failure
        }
        deferreds = [
            remote.call_on_event(handlers),
            remote.register().addErrback(handle_registration_errors)
        ]
        # We consume errors here to ignore errors after the first one.
        # catch_all will be called for the very first deferred that fails.
        results = gather_results(deferreds, consume_errors=True)
        results.addErrback(catch_all)
        results.addCallback(stop)

    def got_error(failure):
        on_message(
            "There was an error communicating with the Landscape"
            " client.",
            error=True)
        on_message(
            "This machine will be registered with the provided "
            "details when the client runs.",
            error=True)
        stop([2])

    connector = RemoteBrokerConnector(reactor, config)
    result = connector.connect(max_retries=max_retries, quiet=True)
    result.addCallback(got_connection)
    result.addErrback(got_error)

    reactor.run()

    if exit_with_error:
        on_error(exit_with_error[0])

    return result