From 22245c487a6c762785ff566f444c20d4243a85dd Mon Sep 17 00:00:00 2001 From: Vladyslav Moisieienkov Date: Tue, 16 Aug 2022 14:47:13 +0200 Subject: [PATCH] workflow: always upload REANA specification on create and restart closes #623 --- CHANGES.rst | 1 + reana_client/cli/workflow.py | 111 +++++++++++++++++++++-------------- tests/test_cli_workflows.py | 5 +- 3 files changed, 71 insertions(+), 46 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 49ea1c7f..c1346249 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,7 @@ Version 0.9.0 (UNRELEASED) - Adds support for ``.reanaignore`` during file upload. Files that match ``.reanaignore`` will not be uploaded. - Adds support for ``.gitignore`` during file upload. Files that match ``.gitignore`` will not be uploaded. - Adds ``retention-rules-list`` command to list the retention rules of a workflow. +- Changes ``create`` and ``restart`` commands to always upload REANA specification file. - Changes ``delete`` CLI command to always delete workspace. - Changes ``delete_workflow`` API method to always delete workspace. - Changes ``list`` to hide deleted workflows by default. diff --git a/reana_client/cli/workflow.py b/reana_client/cli/workflow.py index 80f1089b..4dfcb48d 100644 --- a/reana_client/cli/workflow.py +++ b/reana_client/cli/workflow.py @@ -356,19 +356,23 @@ def workflow_create(ctx, file, name, skip_validation, access_token): # noqa: D3 display_message("Workflow name cannot be a valid UUIDv4", msg_type="error") sys.exit(1) + specification_filename = click.format_filename(file) + try: reana_specification = load_validate_reana_spec( - click.format_filename(file), + specification_filename, access_token=access_token, skip_validation=skip_validation, server_capabilities=True, ) logging.info("Connecting to {0}".format(get_api_url())) response = create_workflow(reana_specification, name, access_token) - click.echo(click.style(response["workflow_name"], fg="green")) + workflow_name = response["workflow_name"] + + click.echo(click.style(workflow_name, fg="green")) # check if command is called from wrapper command if "invoked_by_subcommand" in ctx.parent.__dict__: - ctx.parent.workflow_name = response["workflow_name"] + ctx.parent.workflow_name = workflow_name except Exception as e: logging.debug(traceback.format_exc()) logging.debug(str(e)) @@ -377,6 +381,14 @@ def workflow_create(ctx, file, name, skip_validation, access_token): # noqa: D3 ) sys.exit(1) + # upload specification file by default + ctx.invoke( + upload_files, + workflow=workflow_name, + filenames=(specification_filename,), + access_token=access_token, + ) + @workflow_execution_group.command("start") @add_workflow_option @@ -578,61 +590,70 @@ def workflow_restart( "restart": True, } if file: + specification_filename = click.format_filename(file) parsed_parameters["reana_specification"] = load_validate_reana_spec( click.format_filename(file) ) - if workflow: - if parameters or options: - try: - if "reana_specification" in parsed_parameters: - workflow_type = parsed_parameters["reana_specification"][ - "workflow" - ]["type"] - original_parameters = ( - parsed_parameters["reana_specification"] - .get("inputs", {}) - .get("parameters", {}) - ) - else: - response = get_workflow_parameters(workflow, access_token) - workflow_type = response["type"] - original_parameters = response["parameters"] + # upload new specification + ctx.invoke( + upload_files, + workflow=workflow, + filenames=(specification_filename,), + access_token=access_token, + ) - parsed_parameters["operational_options"] = validate_operational_options( - workflow_type, parsed_parameters["operational_options"] - ) - parsed_parameters["input_parameters"] = validate_input_parameters( - parsed_parameters["input_parameters"], original_parameters + if parameters or options: + try: + if "reana_specification" in parsed_parameters: + workflow_type = parsed_parameters["reana_specification"]["workflow"][ + "type" + ] + original_parameters = ( + parsed_parameters["reana_specification"] + .get("inputs", {}) + .get("parameters", {}) ) + else: + response = get_workflow_parameters(workflow, access_token) + workflow_type = response["type"] + original_parameters = response["parameters"] - except REANAValidationError as e: - display_message(e.message, msg_type="error") - sys.exit(1) - except Exception as e: - display_message( - "Could not apply given input parameters: " - "{0} \n{1}".format(parameters, str(e)), - msg_type="error", - ) - sys.exit(1) - try: - logging.info("Connecting to {0}".format(get_api_url())) - response = start_workflow(workflow, access_token, parsed_parameters) - workflow = response["workflow_name"] + "." + str(response["run_number"]) - current_status = get_workflow_status(workflow, access_token).get("status") - display_message( - get_workflow_status_change_msg(workflow, current_status), - msg_type="success", + parsed_parameters["operational_options"] = validate_operational_options( + workflow_type, parsed_parameters["operational_options"] + ) + parsed_parameters["input_parameters"] = validate_input_parameters( + parsed_parameters["input_parameters"], original_parameters ) + + except REANAValidationError as e: + display_message(e.message, msg_type="error") + sys.exit(1) except Exception as e: - logging.debug(traceback.format_exc()) - logging.debug(str(e)) display_message( - "Cannot start workflow {}: \n{}".format(workflow, str(e)), + "Could not apply given input parameters: " + "{0} \n{1}".format(parameters, str(e)), msg_type="error", ) sys.exit(1) + try: + logging.info("Connecting to {0}".format(get_api_url())) + response = start_workflow(workflow, access_token, parsed_parameters) + workflow = response["workflow_name"] + "." + str(response["run_number"]) + current_status = get_workflow_status(workflow, access_token).get("status") + display_message( + get_workflow_status_change_msg(workflow, current_status), + msg_type="success", + ) + except Exception as e: + logging.debug(traceback.format_exc()) + logging.debug(str(e)) + display_message( + "Cannot start workflow {}: \n{}".format(workflow, str(e)), + msg_type="error", + ) + sys.exit(1) + @workflow_execution_group.command("status") @add_workflow_option diff --git a/tests/test_cli_workflows.py b/tests/test_cli_workflows.py index c3ddd242..1983141f 100644 --- a/tests/test_cli_workflows.py +++ b/tests/test_cli_workflows.py @@ -485,7 +485,7 @@ def test_workflow_create_successful(create_yaml_workflow_schema): with patch( "reana_client.api.client.current_rs_api_client", make_mock_api_client("reana-server")(mock_response, mock_http_response), - ): + ), patch("reana_client.api.client.requests.post") as upload_request: with runner.isolated_filesystem(): with open("reana.yaml", "w") as f: f.write(create_yaml_workflow_schema) @@ -495,6 +495,9 @@ def test_workflow_create_successful(create_yaml_workflow_schema): assert result.exit_code == 0 assert response["workflow_name"] in result.output + upload_request.assert_called_once() + assert "File /reana.yaml was successfully uploaded." in result.output + def test_workflow_create_not_valid_name(create_yaml_workflow_schema): """Test workflow create when creation is successfull."""