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
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