def test_parameterized_for_each_with_set(self): values = ([3, 2, 5]) retry1 = retry.ParameterizedForEach('r1', provides='x') flow = lf.Flow('flow-1', retry1).add(utils.FailingTaskWithOneArg('t1')) engine = self._make_engine(flow) engine.storage.inject({'values': values, 'y': 1}) with utils.CaptureListener(engine) as capturer: self.assertRaisesRegexp(RuntimeError, '^Woot', engine.run) expected = ['flow-1.f RUNNING', 'r1.r RUNNING', 'r1.r SUCCESS(3)', 't1.t RUNNING', 't1.t FAILURE(Failure: RuntimeError: Woot with 3)', 't1.t REVERTING', 't1.t REVERTED', 'r1.r RETRYING', 't1.t PENDING', 'r1.r RUNNING', 'r1.r SUCCESS(2)', 't1.t RUNNING', 't1.t FAILURE(Failure: RuntimeError: Woot with 2)', 't1.t REVERTING', 't1.t REVERTED', 'r1.r RETRYING', 't1.t PENDING', 'r1.r RUNNING', 'r1.r SUCCESS(5)', 't1.t RUNNING', 't1.t FAILURE(Failure: RuntimeError: Woot with 5)', 't1.t REVERTING', 't1.t REVERTED', 'r1.r REVERTING', 'r1.r REVERTED', 'flow-1.f REVERTED'] self.assertItemsEqual(capturer.values, expected)
def test_parameterized_for_each_empty_collection(self): values = [] retry1 = retry.ParameterizedForEach('r1', provides='x') flow = lf.Flow('flow-1', retry1).add(utils.ConditionalTask('t1')) engine = self._make_engine(flow) engine.storage.inject({'values': values, 'y': 1}) self.assertRaisesRegexp(exc.NotFound, '^No elements left', engine.run)
def get_rh_flow(novaclient, process_what): """Constructs and returns the engine entrypoint flow. This flow will do the following: 1. Disable compute service on source host 2. Get all HA_Enabled instances. 3. Evacuate all the HA_Enabled instances using reserved_host. 4. Confirm evacuation of instances. """ flow_name = ACTION.replace(":", "_") + "_engine" nested_flow = linear_flow.Flow(flow_name) rh_flow = linear_flow.Flow("retry_%s" % flow_name, retry=retry.ParameterizedForEach( rebind=['reserved_host_list'], provides='reserved_host')) rh_flow.add(PrepareHAEnabledInstancesTask(novaclient), EvacuateInstancesTask(novaclient), ConfirmEvacuationTask(novaclient)) nested_flow.add(DisableComputeServiceTask(novaclient), rh_flow) return taskflow.engines.load(nested_flow, store=process_what)
def enable_service(): flow = linear_flow.Flow('Enable service').add( update_service_state_tasks.UpdateServiceStateTask(), linear_flow.Flow('Break DNS Chain', retry=retry.ParameterizedForEach( rebind=['time_seconds'], provides='retry_sleep_time') ).add( update_service_state_tasks.FixDNSChainTask()) ) return flow
def disable_service(): flow = linear_flow.Flow('Disable service').add( linear_flow.Flow('Update Oslo Context').add( common.ContextUpdateTask()), linear_flow.Flow('Update Service State').add( update_service_state_tasks.UpdateServiceStateTask()), linear_flow.Flow( 'Break DNS Chain', retry=retry.ParameterizedForEach( rebind=['time_seconds'], provides='retry_sleep_time')).add( update_service_state_tasks.BreakDNSChainTask())) return flow
def create_service(): flow = graph_flow.Flow('Creating poppy-service').add( create_service_tasks.CreateProviderServicesTask(), linear_flow.Flow( 'Create Service DNS Mapping flow', retry=retry.ParameterizedForEach( rebind=['time_seconds'], provides='retry_sleep_time')).add( create_service_tasks.CreateServiceDNSMappingTask( rebind=['responders'])), create_service_tasks.CreateLogDeliveryContainerTask(), create_service_tasks.GatherProviderDetailsTask( rebind=['responders', 'dns_responder', 'log_responders']), common.UpdateProviderDetailTask(rebind=['provider_details_dict'])) return flow
def test_parameterized_for_each_with_set(self): values = ([3, 2, 5]) retry1 = retry.ParameterizedForEach('r1', provides='x') flow = lf.Flow('flow-1', retry1).add(utils.FailingTaskWithOneArg('t1')) engine = self._make_engine(flow) engine.storage.inject({'values': values, 'y': 1}) self.assertRaisesRegexp(RuntimeError, '^Woot', engine.run) expected = [ u't1 reverted(Failure: RuntimeError: Woot with 3)', u't1 reverted(Failure: RuntimeError: Woot with 2)', u't1 reverted(Failure: RuntimeError: Woot with 5)' ] self.assertItemsEqual(self.values, expected)
def delete_service(): flow = graph_flow.Flow('Deleting poppy-service').add( delete_service_tasks.DeleteProviderServicesTask(), linear_flow.Flow('Delete Service DNS Mapping flow', retry=retry.ParameterizedForEach( rebind=['time_seconds'], provides='retry_sleep_time')).add( delete_service_tasks.DeleteServiceDNSMappingTask()), delete_service_tasks.GatherProviderDetailsTask( rebind=['responders', 'dns_responder']), linear_flow.Flow('Delete service storage operation').add( common.UpdateProviderDetailIfNotEmptyTask( rebind=['provider_details_dict']), delete_service_tasks.DeleteStorageServiceTask()) ) return flow
def get_rh_flow(context, novaclient, process_what, **kwargs): """Constructs and returns the engine entrypoint flow. This flow will do the following: 1. Disable compute service on source host 2. Get all HA_Enabled instances. 3. Evacuate all the HA_Enabled instances using reserved_host. 4. Confirm evacuation of instances. """ flow_name = ACTION.replace(":", "_") + "_engine" nested_flow = linear_flow.Flow(flow_name) task_dict = TASKFLOW_CONF.host_rh_failure_recovery_tasks rh_evacuate_flow_pre = linear_flow.Flow('pre_tasks') for plugin in base.get_recovery_flow(task_dict['pre'], context=context, novaclient=novaclient, **kwargs): rh_evacuate_flow_pre.add(plugin) rh_evacuate_flow_main = linear_flow.Flow("retry_%s" % flow_name, retry=retry.ParameterizedForEach( rebind=['reserved_host_list'], provides='reserved_host')) for plugin in base.get_recovery_flow(task_dict['main'], context=context, novaclient=novaclient, **kwargs): rh_evacuate_flow_main.add(plugin) rh_evacuate_flow_post = linear_flow.Flow('post_tasks') for plugin in base.get_recovery_flow(task_dict['post'], context=context, novaclient=novaclient, **kwargs): rh_evacuate_flow_post.add(plugin) nested_flow.add(rh_evacuate_flow_pre) nested_flow.add(rh_evacuate_flow_main) nested_flow.add(rh_evacuate_flow_post) return base.load_taskflow_into_engine(ACTION, nested_flow, process_what)
def update_service(): flow = linear_flow.Flow('Updating poppy-service').add( linear_flow.Flow('Update Oslo Context').add( common.ContextUpdateTask()), linear_flow.Flow('Update Provider Services').add( update_service_tasks.UpdateProviderServicesTask()), linear_flow.Flow( 'Update Service DNS Mapping flow', retry=retry.ParameterizedForEach( rebind=['time_seconds'], provides='retry_sleep_time')).add( update_service_tasks.UpdateServiceDNSMappingTask( rebind=['responders'])), update_service_tasks.UpdateLogDeliveryContainerTask(), update_service_tasks.GatherProviderDetailsTask( rebind=['responders', 'dns_responder', 'log_responders']), update_service_tasks.UpdateProviderDetailsTask_Errors( rebind=['provider_details_dict_errors_tuple'])) return flow
class ConnectToServer(task.Task): def execute(self, ip): print("Connecting to %s" % ip) status, result = sp.getstatusoutput("ping -c1 -W2 " + str(ip)) if status == 0: print("Connection to %s succesfull!!!" % ip) else: raise Exception("Wrong IP!") def revert(self, ip, **kwargs): print("Wrong IP!!") flow = linear_flow.Flow( 'send_message', retry=retry.ParameterizedForEach(rebind={'values': 'server_ips'}, provides='ip')).add(ConnectToServer()) try: print("Loading...") e = engines.load( flow, store={ 'server_ips': ['192.168.1.1', '192.168.1.2', '172.30.1.60', '192.168.1.3'] }) print("Compiling...") e.compile() print("Preparing...") e.prepare() print("Running...") e.run()
# directory and tries different phone numbers. The next task tries to call Jim # using the given number. If if is not a Jim's number, the tasks raises an # exception and retry controller takes the next number from the phone # directory and retries the call. # # This example shows a basic usage of retry controllers in a flow. # Retry controllers allows to revert and retry a failed subflow with new # parameters. class CallJim(task.Task): def execute(self, jim_number): print("Calling jim %s." % jim_number) if jim_number != 555: raise Exception("Wrong number!") else: print("Hello Jim!") def revert(self, jim_number, **kwargs): print("Wrong number, apologizing.") # Create your flow and associated tasks (the work to be done). flow = lf.Flow('retrying-linear', retry=retry.ParameterizedForEach(rebind=['phone_directory'], provides='jim_number')).add( CallJim()) # Now run that flow using the provided initial data (store below). taskflow.engines.run(flow, store={'phone_directory': [333, 444, 555, 666]})