def setUp(self): """ Configure an empty stack. """ def termination(): return lambda: True def run_immediately(f): f() self.cooperator = Cooperator(terminationPredicateFactory=termination, scheduler=run_immediately) self.undo = InMemoryUndoStack(self.cooperator.coiterate)
def execute_config(self, log, transaction_id, scaling_group, launch_config): """ see :meth:`ISupervisor.execute_config` """ log = log.bind(worker=launch_config['type'], tenant_id=scaling_group.tenant_id) assert launch_config['type'] == 'launch_server' undo = InMemoryUndoStack(self.coiterate) d = self._get_request_bag(log, scaling_group) def got_request_bag(request_bag): log.msg("Executing launch config.") return launch_server_v1.launch_server(log, request_bag, scaling_group, launch_config['args'], undo) d.addCallback(got_request_bag) def when_launch_server_completed(result): # XXX: Something should be done with this data. Currently only # enough to pass to the controller to store in the active state is # returned server_details, lb_info = result log.msg("Done executing launch config.", server_id=server_details['server']['id']) return { 'id': server_details['server']['id'], 'links': server_details['server']['links'], 'name': server_details['server']['name'], 'lb_info': lb_info } d.addCallback(when_launch_server_completed) def when_fails(result): log.msg("Encountered an error, rewinding {worker!r} job undo stack.", exc=result.value) ud = undo.rewind() ud.addCallback(lambda _: result) return ud d.addErrback(when_fails) return d
def execute_config(self, log, transaction_id, scaling_group, launch_config): """ Executes a single launch config. :param log: Bound logger. :param str transaction_id: Transaction ID. :param callable auth_function: A 1-argument callable that takes a tenant_id, and returns a Deferred that fires with a 2-tuple of auth_token and service_catalog. :param IScalingGroup scaling_group: Scaling Group. :param dict launch_config: The launch config for the scaling group. :returns: A deferred that fires with a 3-tuple of job_id, completion deferred, and job_info (a dict) :rtype: ``Deferred`` """ job_id = generate_job_id(scaling_group.uuid) completion_d = Deferred() log = log.bind(job_id=job_id, worker=launch_config['type'], tenant_id=scaling_group.tenant_id) assert launch_config['type'] == 'launch_server' undo = InMemoryUndoStack(self.coiterate) def when_fails(result): log.msg( "Encountered an error, rewinding {worker!r} job undo stack.", exc=result.value) ud = undo.rewind() ud.addCallback(lambda _: result) return ud completion_d.addErrback(when_fails) log.msg("Authenticating for tenant") d = self.auth_function(scaling_group.tenant_id) def when_authenticated((auth_token, service_catalog)): log.msg("Executing launch config.") return launch_server_v1.launch_server(log, config_value('region'), scaling_group, service_catalog, auth_token, launch_config['args'], undo) d.addCallback(when_authenticated) def when_launch_server_completed(result): # XXX: Something should be done with this data. Currently only enough # to pass to the controller to store in the active state is returned server_details, lb_info = result log.msg("Done executing launch config.", instance_id=server_details['server']['id']) return { 'id': server_details['server']['id'], 'links': server_details['server']['links'], 'name': server_details['server']['name'], 'lb_info': lb_info } d.addCallback(when_launch_server_completed) d.chainDeferred(completion_d) return succeed((job_id, completion_d))