def _start_workflow(blueprint_id, deployment_id, execution_id, op_name, sm): workflow_id = "hosts_software_" + op_name new_execution = models.Execution( id=execution_id, status=models.Execution.PENDING, created_at=str(datetime.now()), blueprint_id=blueprint_id, workflow_id=workflow_id, deployment_id=deployment_id, error="", parameters=[], is_system_workflow=False, ) sm.put_execution(new_execution.id, new_execution) workflow = {"operation": "software_replacement_workflow.replace_host_software"} workflow_client().execute_workflow( workflow_id, workflow, blueprint_id=blueprint_id, deployment_id=deployment_id, execution_id=execution_id, execution_parameters={"op_name": op_name}, )
def _start_workflow(blueprint_id, deployment_id, execution_id, op_name, sm): workflow_id = 'hosts_software_' + op_name new_execution = models.Execution(id=execution_id, status=models.Execution.PENDING, created_at=str(datetime.now()), blueprint_id=blueprint_id, workflow_id=workflow_id, deployment_id=deployment_id, error='', parameters=[], is_system_workflow=False) sm.put_execution(new_execution.id, new_execution) workflow = { 'operation': 'software_replacement_workflow.replace_host_software' } workflow_client().execute_workflow( workflow_id, workflow, blueprint_id=blueprint_id, deployment_id=deployment_id, execution_id=execution_id, execution_parameters={'op_name': op_name})
def execute_workflow(self, deployment_id, workflow_id, parameters=None, allow_custom_parameters=False, force=False): deployment = self.get_deployment(deployment_id) if workflow_id not in deployment.workflows: raise manager_exceptions.NonexistentWorkflowError( 'Workflow {0} does not exist in deployment {1}'.format( workflow_id, deployment_id)) workflow = deployment.workflows[workflow_id] self._verify_deployment_environment_created_successfully(deployment_id) # validate no execution is currently in progress if not force: executions = get_storage_manager().executions_list( deployment_id=deployment_id) running = [ e.id for e in executions if get_storage_manager().get_execution(e.id).status not in models.Execution.END_STATES ] if len(running) > 0: raise manager_exceptions.ExistingRunningExecutionError( 'The following executions are currently running for this ' 'deployment: {0}. To execute this workflow anyway, pass ' '"force=true" as a query parameter to this request'.format( running)) execution_parameters = \ BlueprintsManager._merge_and_validate_execution_parameters( workflow, workflow_id, parameters, allow_custom_parameters) execution_id = str(uuid.uuid4()) new_execution = models.Execution( id=execution_id, status=models.Execution.PENDING, created_at=str(datetime.now()), blueprint_id=deployment.blueprint_id, workflow_id=workflow_id, deployment_id=deployment_id, error='', parameters=self._get_only_user_execution_parameters( execution_parameters)) get_storage_manager().put_execution(new_execution.id, new_execution) workflow_client().execute_workflow( workflow_id, workflow, blueprint_id=deployment.blueprint_id, deployment_id=deployment_id, execution_id=execution_id, execution_parameters=execution_parameters) return new_execution
def execute_workflow(self, deployment_id, workflow_id, parameters=None, allow_custom_parameters=False, force=False): deployment = self.get_deployment(deployment_id) if workflow_id not in deployment.workflows: raise manager_exceptions.NonexistentWorkflowError( 'Workflow {0} does not exist in deployment {1}'.format( workflow_id, deployment_id)) workflow = deployment.workflows[workflow_id] self._verify_deployment_environment_created_successfully(deployment_id) # validate no execution is currently in progress if not force: executions = get_storage_manager().executions_list( deployment_id=deployment_id) running = [ e.id for e in executions if get_storage_manager().get_execution(e.id).status not in models.Execution.END_STATES] if len(running) > 0: raise manager_exceptions.ExistingRunningExecutionError( 'The following executions are currently running for this ' 'deployment: {0}. To execute this workflow anyway, pass ' '"force=true" as a query parameter to this request'.format( running)) execution_parameters = \ BlueprintsManager._merge_and_validate_execution_parameters( workflow, workflow_id, parameters, allow_custom_parameters) execution_id = str(uuid.uuid4()) new_execution = models.Execution( id=execution_id, status=models.Execution.PENDING, created_at=str(datetime.now()), blueprint_id=deployment.blueprint_id, workflow_id=workflow_id, deployment_id=deployment_id, error='', parameters=self._get_only_user_execution_parameters( execution_parameters)) get_storage_manager().put_execution(new_execution.id, new_execution) workflow_client().execute_workflow( workflow_id, workflow, blueprint_id=deployment.blueprint_id, deployment_id=deployment_id, execution_id=execution_id, execution_parameters=execution_parameters) return new_execution
def execute_workflow(self, deployment_id, workflow_id): deployment = self.get_deployment(deployment_id) if workflow_id not in deployment.plan['workflows']: raise manager_exceptions.NonexistentWorkflowError( 'Workflow {0} does not exist in deployment {1}'.format( workflow_id, deployment_id)) workflow = deployment.plan['workflows'][workflow_id] plan = deployment.plan execution_id = str(uuid.uuid4()) response = workflow_client().execute_workflow( workflow_id, workflow, plan, blueprint_id=deployment.blueprint_id, deployment_id=deployment_id, execution_id=execution_id) # TODO raise error if there is error in response new_execution = models.Execution( id=execution_id, status=response['state'], internal_workflow_id=response['id'], created_at=str(response['created']), blueprint_id=deployment.blueprint_id, workflow_id=workflow_id, deployment_id=deployment_id, error='None') self.sm.put_execution(new_execution.id, new_execution) return new_execution
def validate_blueprint(self, blueprint_id): blueprint = self.get_blueprint(blueprint_id) plan = blueprint.plan response = workflow_client().validate_workflows(plan) # TODO raise error if error return responses.BlueprintValidationStatus( blueprint_id=blueprint_id, status=response['status'])
def _execute_system_workflow(self, deployment, wf_id, task_mapping, execution_parameters=None, timeout=0, created_at=None): """ :param deployment: deployment for workflow execution :param wf_id: workflow id :param task_mapping: mapping to the system workflow :param execution_parameters: parameters for the system workflow :param timeout: 0 will return immediately; any positive value will cause this method to wait for the given timeout for the task to complete, and verify it finished successfully before returning :param created_at: creation time for the workflow execution object. if omitted, a value will be generated by this method. :return: async task object """ execution_id = str(uuid.uuid4()) # will also serve as the task id execution_parameters = execution_parameters or {} # currently, deployment env creation/deletion are not set as # system workflows is_system_workflow = wf_id not in ( 'create_deployment_environment', 'delete_deployment_environment') execution = models.Execution( id=execution_id, status=models.Execution.PENDING, created_at=created_at or str(datetime.now()), blueprint_id=deployment.blueprint_id, workflow_id=wf_id, deployment_id=deployment.id, error='', parameters=self._get_only_user_execution_parameters( execution_parameters), is_system_workflow=is_system_workflow) self.sm.put_execution(execution.id, execution) async_task = workflow_client().execute_system_workflow( deployment, wf_id, execution_id, task_mapping, execution_parameters) if timeout > 0: try: # wait for the workflow execution to complete async_task.get(timeout=timeout, propagate=True) except Exception as e: # error message for the user error_msg =\ 'Error occurred while executing the {0} system workflow '\ 'for deployment {1}: {2} - {3}'.format( wf_id, deployment.id, type(e).__name__, str(e)) # adding traceback to the log error message tb = StringIO() traceback.print_exc(file=tb) log_error_msg = '{0}; traceback: {1}'.format( error_msg, tb.getvalue()) current_app.logger.error(log_error_msg) raise RuntimeError(error_msg) # verify the execution completed successfully execution = self.sm.get_execution(async_task.id) if execution.status != models.Execution.TERMINATED: raise RuntimeError( 'Failed executing the {0} system workflow for deployment ' '{1}: Execution did not complete successfully before ' 'timeout ({2} seconds)'.format( wf_id, deployment.id, timeout)) return async_task
def execute_workflow(self, deployment_id, workflow_id, parameters=None, allow_custom_parameters=False, force=False): deployment = self.get_deployment(deployment_id) if workflow_id not in deployment.workflows: raise manager_exceptions.NonexistentWorkflowError( 'Workflow {0} does not exist in deployment {1}'.format( workflow_id, deployment_id)) workflow = deployment.workflows[workflow_id] self._verify_deployment_environment_created_successfully(deployment_id) transient_workers_config =\ self._get_transient_deployment_workers_mode_config() is_transient_workers_enabled = transient_workers_config['enabled'] self._check_for_active_executions(deployment_id, force, transient_workers_config) execution_parameters = \ BlueprintsManager._merge_and_validate_execution_parameters( workflow, workflow_id, parameters, allow_custom_parameters) if is_transient_workers_enabled: # in this mode, we push the user execution object to storage # before executing the "_start_deployment_environment" system # workflow, to prevent from other executions to start running in # between the system workflow and the user workflow execution. # to keep correct chronological order, the system workflow's # "created_at" field is generated here. start_deployment_env_created_at_time = str(datetime.now()) execution_id = str(uuid.uuid4()) new_execution = models.Execution( id=execution_id, status=models.Execution.PENDING, created_at=str(datetime.now()), blueprint_id=deployment.blueprint_id, workflow_id=workflow_id, deployment_id=deployment_id, error='', parameters=self._get_only_user_execution_parameters( execution_parameters), is_system_workflow=False) self.sm.put_execution(new_execution.id, new_execution) if is_transient_workers_enabled: # initiating a workflow to start deployment workers wf_id = '_start_deployment_environment' deployment_env_start_task_name = \ 'cloudify_system_workflows.deployment_environment.start' self._execute_system_workflow( deployment, wf_id, deployment_env_start_task_name, timeout=300, created_at=start_deployment_env_created_at_time) # executing the user workflow workflow_client().execute_workflow( workflow_id, workflow, blueprint_id=deployment.blueprint_id, deployment_id=deployment_id, execution_id=execution_id, execution_parameters=execution_parameters) return new_execution
def _execute_system_workflow(self, deployment, wf_id, task_mapping, execution_parameters=None, timeout=0, created_at=None): """ :param deployment: deployment for workflow execution :param wf_id: workflow id :param task_mapping: mapping to the system workflow :param execution_parameters: parameters for the system workflow :param timeout: 0 will return immediately; any positive value will cause this method to wait for the given timeout for the task to complete, and verify it finished successfully before returning :param created_at: creation time for the workflow execution object. if omitted, a value will be generated by this method. :return: async task object """ execution_id = str(uuid.uuid4()) # will also serve as the task id execution_parameters = execution_parameters or {} # currently, deployment env creation/deletion are not set as # system workflows is_system_workflow = wf_id not in ('create_deployment_environment', 'delete_deployment_environment') execution = models.Execution( id=execution_id, status=models.Execution.PENDING, created_at=created_at or str(datetime.now()), blueprint_id=deployment.blueprint_id, workflow_id=wf_id, deployment_id=deployment.id, error='', parameters=self._get_only_user_execution_parameters( execution_parameters), is_system_workflow=is_system_workflow) self.sm.put_execution(execution.id, execution) async_task = workflow_client().execute_system_workflow( deployment, wf_id, execution_id, task_mapping, execution_parameters) if timeout > 0: try: # wait for the workflow execution to complete async_task.get(timeout=timeout, propagate=True) except Exception as e: # error message for the user error_msg =\ 'Error occurred while executing the {0} system workflow '\ 'for deployment {1}: {2} - {3}'.format( wf_id, deployment.id, type(e).__name__, str(e)) # adding traceback to the log error message tb = StringIO() traceback.print_exc(file=tb) log_error_msg = '{0}; traceback: {1}'.format( error_msg, tb.getvalue()) current_app.logger.error(log_error_msg) raise RuntimeError(error_msg) # verify the execution completed successfully execution = self.sm.get_execution(async_task.id) if execution.status != models.Execution.TERMINATED: raise RuntimeError( 'Failed executing the {0} system workflow for deployment ' '{1}: Execution did not complete successfully before ' 'timeout ({2} seconds)'.format(wf_id, deployment.id, timeout)) return async_task
def cancel_workflow(self, execution_id): execution = self.get_execution(execution_id) workflow_client().cancel_workflow( execution.internal_workflow_id ) return execution
def get_workflows_states_by_internal_workflows_ids(self, internal_wfs_ids): return workflow_client().get_workflows_statuses(internal_wfs_ids)