Ejemplo n.º 1
0
def start_workflow(workflow, parameters):
    """Start a workflow."""

    def _start_workflow_db(workflow, parameters):
        workflow.run_started_at = datetime.now()
        workflow.status = WorkflowStatus.running
        if parameters:
            workflow.input_parameters = parameters.get("input_parameters")
            workflow.operational_options = parameters.get("operational_options")
        current_db_sessions.add(workflow)
        current_db_sessions.commit()

    current_db_sessions = Session.object_session(workflow)
    kwrm = KubernetesWorkflowRunManager(workflow)

    failure_message = (
        "Workflow {id_} could not be started because it {verb} " "already {status}."
    ).format(
        id_=workflow.id_,
        verb=get_workflow_status_change_verb(workflow.status.name),
        status=str(workflow.status.name),
    )
    if "restart" in parameters.keys():
        if parameters["restart"]:
            if workflow.status not in [
                WorkflowStatus.failed,
                WorkflowStatus.finished,
                WorkflowStatus.queued,
            ]:
                raise REANAWorkflowControllerError(failure_message)
    elif workflow.status not in [WorkflowStatus.created, WorkflowStatus.queued]:
        if workflow.status == WorkflowStatus.deleted:
            raise REANAWorkflowStatusError(failure_message)
        raise REANAWorkflowControllerError(failure_message)

    try:
        kwrm.start_batch_workflow_run(
            overwrite_input_params=parameters.get("input_parameters"),
            overwrite_operational_options=parameters.get("operational_options"),
        )
        _start_workflow_db(workflow, parameters)
    except SQLAlchemyError as e:
        message = "Database connection failed, please retry."
        logging.error(
            f"Error while creating {workflow.id_}: {message}\n{e}", exc_info=True
        )
        # Rollback Kubernetes job creation
        kwrm.stop_batch_workflow_run()
        logging.error(
            f"Stopping Kubernetes jobs associated with workflow " f"{workflow.id_} ..."
        )
        raise REANAExternalCallError(message)
    except ApiException as e:
        message = "Kubernetes connection failed, please retry."
        logging.error(
            f"Error while creating {workflow.id_}: {message}\n{e}", exc_info=True
        )
        raise REANAExternalCallError(message)
Ejemplo n.º 2
0
def stop_workflow(workflow):
    """Stop a given workflow."""
    if workflow.status == RunStatus.running:
        kwrm = KubernetesWorkflowRunManager(workflow)
        kwrm.stop_batch_workflow_run()
        workflow.status = RunStatus.stopped
        Session.add(workflow)
        Session.commit()
    else:
        message = ("Workflow {id_} is not running.").format(id_=workflow.id_)
        raise REANAWorkflowControllerError(message)
Ejemplo n.º 3
0
def stop_workflow(workflow):
    """Stop a given workflow."""
    if workflow.status == WorkflowStatus.running:
        kwrm = KubernetesWorkflowRunManager(workflow)
        workflow.run_stopped_at = datetime.now()
        kwrm.stop_batch_workflow_run()
        workflow.status = WorkflowStatus.stopped
        current_db_sessions = Session.object_session(workflow)
        current_db_sessions.add(workflow)
        current_db_sessions.commit()
    else:
        message = ("Workflow {id_} is not running.").format(id_=workflow.id_)
        raise REANAWorkflowControllerError(message)
Ejemplo n.º 4
0
def test_stop_workflow_backend_only_kubernetes(
        sample_serial_workflow_in_db, add_kubernetes_jobs_to_workflow):
    """Test deletion of workflows with only Kubernetes based jobs."""
    workflow = sample_serial_workflow_in_db
    workflow.status = WorkflowStatus.running
    workflow_jobs = add_kubernetes_jobs_to_workflow(workflow)
    backend_job_ids = [job.backend_job_id for job in workflow_jobs]
    with patch("reana_workflow_controller.workflow_run_manager."
               "current_k8s_batchv1_api_client") as api_client:
        kwrm = KubernetesWorkflowRunManager(workflow)
        kwrm.stop_batch_workflow_run()
        for delete_call in api_client.delete_namespaced_job.call_args_list:
            if delete_call.args[0] in backend_job_ids:
                del backend_job_ids[backend_job_ids.index(delete_call.args[0])]

        assert not backend_job_ids