def execute_config(self, log, transaction_id, scaling_group, launch_config): """ see :meth:`ISupervisor.execute_config` """ 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, log=log) def when_authenticated((auth_token, service_catalog)): log.msg("Executing launch config.") return launch_server_v1.launch_server( log, self.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.", 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) self.deferred_pool.add(d) d.chainDeferred(completion_d) return succeed((job_id, completion_d))
def start(self, launch_config): """ Kick off a job by calling the supervisor with a launch config. :param dict launch_config: The launch config to scale up a server. """ try: image = launch_config['args']['server']['imageRef'] except: image = 'Unable to pull image ref.' try: flavor = launch_config['args']['server']['flavorRef'] except: flavor = 'Unable to pull flavor ref.' self.job_id = generate_job_id(self.scaling_group.uuid) self.log = self.log.bind(image_ref=image, flavor_ref=flavor, job_id=self.job_id) d = self.supervisor.execute_config( self.log, self.transaction_id, self.scaling_group, launch_config) d.addCallbacks(self._job_succeeded, self._job_failed) d.addErrback(self.log.err) 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' 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']) 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))
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))