Esempio n. 1
0
def register(config,
             reactor=None,
             connector_factory=RemoteBrokerConnector,
             got_connection=got_connection,
             max_retries=14,
             on_error=None,
             results=None):
    """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.  This parameter is optional because
        the client charm does not pass it.
    @param connector_factory: A callable that accepts a reactor and a
        configuration object and returns a new remote broker connection.  Used
        primarily for dependency injection.
    @param got_connection: The handler to trigger when the remote broker
        connects.  Used primarily for dependency injection.
    @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.
    @param on_error: A callable that will be passed a non-zero positive
        integer argument in the case that some error occurs.  This is a legacy
        API provided for use by the client charm.
    @param results: This parameter provides a mechanism to pre-seed the result
        of registering.  Used for testing.
    """
    if reactor is None:
        reactor = LandscapeReactor()

    if results is None:
        results = []
    add_result = results.append

    connector = connector_factory(reactor, config)
    connection = connector.connect(max_retries=max_retries, quiet=True)
    connection.addCallback(
        partial(got_connection, add_result, connector, reactor))
    connection.addErrback(
        partial(got_error, reactor=reactor, add_result=add_result))
    reactor.run()

    assert len(results) == 1, "We expect exactly one result."
    # Results will be things like "success" or "ssl-error".
    result = results[0]

    if isinstance(result, SystemExit):
        raise result

    # If there was an error and the caller requested that errors be reported
    # to the on_error callable, then do so.
    if result != "success" and on_error is not None:
        on_error(1)
    return result
Esempio n. 2
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