fractal-server 2.15.10a2__tar.gz → 2.15.10a3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/PKG-INFO +1 -1
- fractal_server-2.15.10a3/fractal_server/__init__.py +1 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/task_group.py +0 -32
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +67 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +22 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +1 -1
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task_group.py +0 -38
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +69 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/runner.py +10 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/submit_workflow.py +33 -44
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/task_group.py +1 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/__init__.py +1 -0
- fractal_server-2.15.10a3/fractal_server/tasks/v2/local/delete.py +76 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/__init__.py +1 -0
- fractal_server-2.15.10a3/fractal_server/tasks/v2/ssh/delete.py +115 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/utils_background.py +3 -1
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/pyproject.toml +2 -2
- fractal_server-2.15.10a2/fractal_server/__init__.py +0 -1
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/LICENSE +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/README.md +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/__main__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/accounting.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/history.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/task.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/task_group.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/job.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/admin/v2/task.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/history.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/pre_submission_checks.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/status_legacy.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task_collection_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task_version_update.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/workflow.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/pagination.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/base_runner.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/call_command_wrapper.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/local/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/local/get_local_config.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/local/runner.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/_batching.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/_job_states.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/_slurm_config.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/remote.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_ssh/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_ssh/runner.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_ssh/tar_commands.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/executors/slurm_sudo/runner.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/task_files.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/_local.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/_slurm_ssh.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/_slurm_sudo.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/db_tools.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/runner_functions.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/accounting.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/dataset.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/history.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/task_collection.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/security/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/security/signup_email.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/config.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/data_migrations/2_14_10.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/exceptions.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/images/models.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/images/status_tools.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/logger.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/main.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/1a83a5260664_rename.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/791ce783d3d8_add_indices.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/py.typed +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/ssh/_fabric.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/string_tools.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/syringe.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/utils.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/_utils.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/collect.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/collect_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/deactivate.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/deactivate_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/reactivate.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/reactivate_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/collect.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/collect_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/deactivate_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/reactivate_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/pixi_1_extract.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/pixi_2_install.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/templates/pixi_3_post_install.sh +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/utils_database.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/utils_package_names.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/utils_pixi.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/utils_templates.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/types/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/types/validators/__init__.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/types/validators/_common_validators.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/types/validators/_filter_validators.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/types/validators/_workflow_task_arguments_validators.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/urls.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/utils.py +0 -0
- {fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/zip_tools.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__VERSION__ = "2.15.10a3"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from fastapi import APIRouter
|
|
2
2
|
from fastapi import Depends
|
|
3
3
|
from fastapi import HTTPException
|
|
4
|
-
from fastapi import Response
|
|
5
4
|
from fastapi import status
|
|
6
5
|
from pydantic.types import AwareDatetime
|
|
7
6
|
from sqlalchemy.sql.operators import is_
|
|
@@ -13,7 +12,6 @@ from fractal_server.app.db import get_async_db
|
|
|
13
12
|
from fractal_server.app.models import UserOAuth
|
|
14
13
|
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
|
15
14
|
from fractal_server.app.models.v2 import TaskGroupV2
|
|
16
|
-
from fractal_server.app.models.v2 import WorkflowTaskV2
|
|
17
15
|
from fractal_server.app.routes.auth import current_active_superuser
|
|
18
16
|
from fractal_server.app.routes.auth._aux_auth import (
|
|
19
17
|
_verify_user_belongs_to_group,
|
|
@@ -161,33 +159,3 @@ async def patch_task_group(
|
|
|
161
159
|
await db.commit()
|
|
162
160
|
await db.refresh(task_group)
|
|
163
161
|
return task_group
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
@router.delete("/{task_group_id}/", status_code=204)
|
|
167
|
-
async def delete_task_group(
|
|
168
|
-
task_group_id: int,
|
|
169
|
-
user: UserOAuth = Depends(current_active_superuser),
|
|
170
|
-
db: AsyncSession = Depends(get_async_db),
|
|
171
|
-
):
|
|
172
|
-
task_group = await db.get(TaskGroupV2, task_group_id)
|
|
173
|
-
if task_group is None:
|
|
174
|
-
raise HTTPException(
|
|
175
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
|
176
|
-
detail=f"TaskGroupV2 {task_group_id} not found",
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
stm = select(WorkflowTaskV2).where(
|
|
180
|
-
WorkflowTaskV2.task_id.in_({task.id for task in task_group.task_list})
|
|
181
|
-
)
|
|
182
|
-
res = await db.execute(stm)
|
|
183
|
-
workflow_tasks = res.scalars().all()
|
|
184
|
-
if workflow_tasks != []:
|
|
185
|
-
raise HTTPException(
|
|
186
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
187
|
-
detail=f"TaskV2 {workflow_tasks[0].task_id} is still in use",
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
await db.delete(task_group)
|
|
191
|
-
await db.commit()
|
|
192
|
-
|
|
193
|
-
return Response(status_code=status.HTTP_204_NO_CONTENT)
|
|
@@ -12,6 +12,9 @@ from fractal_server.app.models.v2 import TaskGroupActivityV2
|
|
|
12
12
|
from fractal_server.app.routes.api.v2._aux_functions_task_lifecycle import (
|
|
13
13
|
check_no_ongoing_activity,
|
|
14
14
|
)
|
|
15
|
+
from fractal_server.app.routes.api.v2._aux_functions_task_lifecycle import (
|
|
16
|
+
check_no_related_workflowtask,
|
|
17
|
+
)
|
|
15
18
|
from fractal_server.app.routes.api.v2._aux_functions_task_lifecycle import (
|
|
16
19
|
check_no_submitted_job,
|
|
17
20
|
)
|
|
@@ -31,8 +34,10 @@ from fractal_server.logger import set_logger
|
|
|
31
34
|
from fractal_server.ssh._fabric import SSHConfig
|
|
32
35
|
from fractal_server.syringe import Inject
|
|
33
36
|
from fractal_server.tasks.v2.local import deactivate_local
|
|
37
|
+
from fractal_server.tasks.v2.local import delete_local
|
|
34
38
|
from fractal_server.tasks.v2.local import reactivate_local
|
|
35
39
|
from fractal_server.tasks.v2.ssh import deactivate_ssh
|
|
40
|
+
from fractal_server.tasks.v2.ssh import delete_ssh
|
|
36
41
|
from fractal_server.tasks.v2.ssh import reactivate_ssh
|
|
37
42
|
from fractal_server.utils import get_timestamp
|
|
38
43
|
|
|
@@ -258,3 +263,65 @@ async def reactivate_task_group(
|
|
|
258
263
|
)
|
|
259
264
|
response.status_code = status.HTTP_202_ACCEPTED
|
|
260
265
|
return task_group_activity
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@router.post("/{task_group_id}/delete/", status_code=202)
|
|
269
|
+
async def delete_task_group(
|
|
270
|
+
task_group_id: int,
|
|
271
|
+
background_tasks: BackgroundTasks,
|
|
272
|
+
response: Response,
|
|
273
|
+
superuser: UserOAuth = Depends(current_active_superuser),
|
|
274
|
+
db: AsyncSession = Depends(get_async_db),
|
|
275
|
+
):
|
|
276
|
+
task_group = await _get_task_group_or_404(
|
|
277
|
+
task_group_id=task_group_id, db=db
|
|
278
|
+
)
|
|
279
|
+
await check_no_ongoing_activity(task_group_id=task_group_id, db=db)
|
|
280
|
+
await check_no_submitted_job(task_group_id=task_group_id, db=db)
|
|
281
|
+
await check_no_related_workflowtask(task_group=task_group, db=db)
|
|
282
|
+
|
|
283
|
+
task_group_activity = TaskGroupActivityV2(
|
|
284
|
+
user_id=task_group.user_id,
|
|
285
|
+
taskgroupv2_id=task_group.id,
|
|
286
|
+
status=TaskGroupActivityStatusV2.PENDING,
|
|
287
|
+
action=TaskGroupActivityActionV2.DELETE,
|
|
288
|
+
pkg_name=task_group.pkg_name,
|
|
289
|
+
version=(task_group.version or "N/A"),
|
|
290
|
+
timestamp_started=get_timestamp(),
|
|
291
|
+
)
|
|
292
|
+
db.add(task_group_activity)
|
|
293
|
+
await db.commit()
|
|
294
|
+
|
|
295
|
+
settings = Inject(get_settings)
|
|
296
|
+
if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
|
|
297
|
+
# Validate user settings (backend-specific)
|
|
298
|
+
task_owner = await db.get(UserOAuth, task_group.user_id)
|
|
299
|
+
task_owner_settings = await validate_user_settings(
|
|
300
|
+
user=task_owner, backend=settings.FRACTAL_RUNNER_BACKEND, db=db
|
|
301
|
+
)
|
|
302
|
+
# Use appropriate FractalSSH object
|
|
303
|
+
ssh_config = SSHConfig(
|
|
304
|
+
user=task_owner_settings.ssh_username,
|
|
305
|
+
host=task_owner_settings.ssh_host,
|
|
306
|
+
key_path=task_owner_settings.ssh_private_key_path,
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
background_tasks.add_task(
|
|
310
|
+
delete_ssh,
|
|
311
|
+
task_group_id=task_group.id,
|
|
312
|
+
task_group_activity_id=task_group_activity.id,
|
|
313
|
+
ssh_config=ssh_config,
|
|
314
|
+
tasks_base_dir=task_owner_settings.ssh_tasks_dir,
|
|
315
|
+
)
|
|
316
|
+
else:
|
|
317
|
+
background_tasks.add_task(
|
|
318
|
+
delete_local,
|
|
319
|
+
task_group_id=task_group.id,
|
|
320
|
+
task_group_activity_id=task_group_activity.id,
|
|
321
|
+
)
|
|
322
|
+
logger.debug(
|
|
323
|
+
"Admin task group deletion endpoint: start deletion "
|
|
324
|
+
"and return task_group_activity"
|
|
325
|
+
)
|
|
326
|
+
response.status_code = status.HTTP_202_ACCEPTED
|
|
327
|
+
return task_group_activity
|
|
@@ -8,6 +8,7 @@ from sqlmodel import select
|
|
|
8
8
|
from fractal_server.app.db import AsyncSession
|
|
9
9
|
from fractal_server.app.models.v2 import JobV2
|
|
10
10
|
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
|
11
|
+
from fractal_server.app.models.v2 import TaskGroupV2
|
|
11
12
|
from fractal_server.app.models.v2 import TaskV2
|
|
12
13
|
from fractal_server.app.models.v2 import WorkflowTaskV2
|
|
13
14
|
from fractal_server.app.models.v2 import WorkflowV2
|
|
@@ -203,3 +204,24 @@ async def check_no_submitted_job(
|
|
|
203
204
|
"submitted jobs use its tasks."
|
|
204
205
|
),
|
|
205
206
|
)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
async def check_no_related_workflowtask(
|
|
210
|
+
*,
|
|
211
|
+
task_group: TaskGroupV2,
|
|
212
|
+
db: AsyncSession,
|
|
213
|
+
) -> None:
|
|
214
|
+
"""
|
|
215
|
+
Raises an HTTPException if any of the tasks in the TaskGroup are referenced
|
|
216
|
+
by an existing WorkflowTask.
|
|
217
|
+
"""
|
|
218
|
+
stm = select(WorkflowTaskV2).where(
|
|
219
|
+
WorkflowTaskV2.task_id.in_([task.id for task in task_group.task_list])
|
|
220
|
+
)
|
|
221
|
+
res = await db.execute(stm)
|
|
222
|
+
bad_wftask = res.scalars().first()
|
|
223
|
+
if bad_wftask is not None:
|
|
224
|
+
raise HTTPException(
|
|
225
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
226
|
+
detail=f"TaskV2 {bad_wftask.task_id} is still in use",
|
|
227
|
+
)
|
|
@@ -243,7 +243,7 @@ async def _get_collection_task_group_activity_status_message(
|
|
|
243
243
|
)
|
|
244
244
|
elif len(task_group_activity_list) == 1:
|
|
245
245
|
msg = (
|
|
246
|
-
"\nNote:"
|
|
246
|
+
"\nNote: "
|
|
247
247
|
"There exists another task-group collection "
|
|
248
248
|
f"(activity ID={task_group_activity_list[0].id}) for "
|
|
249
249
|
f"this task group (ID={task_group_id}), with status "
|
{fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/routes/api/v2/task_group.py
RENAMED
|
@@ -3,7 +3,6 @@ import itertools
|
|
|
3
3
|
from fastapi import APIRouter
|
|
4
4
|
from fastapi import Depends
|
|
5
5
|
from fastapi import HTTPException
|
|
6
|
-
from fastapi import Response
|
|
7
6
|
from fastapi import status
|
|
8
7
|
from packaging.version import InvalidVersion
|
|
9
8
|
from packaging.version import parse
|
|
@@ -12,7 +11,6 @@ from pydantic.types import AwareDatetime
|
|
|
12
11
|
from sqlmodel import or_
|
|
13
12
|
from sqlmodel import select
|
|
14
13
|
|
|
15
|
-
from ._aux_functions_task_lifecycle import check_no_ongoing_activity
|
|
16
14
|
from ._aux_functions_tasks import _get_task_group_full_access
|
|
17
15
|
from ._aux_functions_tasks import _get_task_group_read_access
|
|
18
16
|
from ._aux_functions_tasks import _verify_non_duplication_group_constraint
|
|
@@ -23,7 +21,6 @@ from fractal_server.app.models import LinkUserGroup
|
|
|
23
21
|
from fractal_server.app.models import UserOAuth
|
|
24
22
|
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
|
25
23
|
from fractal_server.app.models.v2 import TaskGroupV2
|
|
26
|
-
from fractal_server.app.models.v2 import WorkflowTaskV2
|
|
27
24
|
from fractal_server.app.routes.auth import current_active_user
|
|
28
25
|
from fractal_server.app.routes.auth._aux_auth import _get_default_usergroup_id
|
|
29
26
|
from fractal_server.app.routes.auth._aux_auth import (
|
|
@@ -199,41 +196,6 @@ async def get_task_group(
|
|
|
199
196
|
return task_group
|
|
200
197
|
|
|
201
198
|
|
|
202
|
-
@router.delete("/{task_group_id}/", status_code=204)
|
|
203
|
-
async def delete_task_group(
|
|
204
|
-
task_group_id: int,
|
|
205
|
-
user: UserOAuth = Depends(current_active_user),
|
|
206
|
-
db: AsyncSession = Depends(get_async_db),
|
|
207
|
-
):
|
|
208
|
-
"""
|
|
209
|
-
Delete single TaskGroup
|
|
210
|
-
"""
|
|
211
|
-
|
|
212
|
-
task_group = await _get_task_group_full_access(
|
|
213
|
-
task_group_id=task_group_id,
|
|
214
|
-
user_id=user.id,
|
|
215
|
-
db=db,
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
await check_no_ongoing_activity(task_group_id=task_group_id, db=db)
|
|
219
|
-
|
|
220
|
-
stm = select(WorkflowTaskV2).where(
|
|
221
|
-
WorkflowTaskV2.task_id.in_({task.id for task in task_group.task_list})
|
|
222
|
-
)
|
|
223
|
-
res = await db.execute(stm)
|
|
224
|
-
workflow_tasks = res.scalars().all()
|
|
225
|
-
if workflow_tasks != []:
|
|
226
|
-
raise HTTPException(
|
|
227
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
228
|
-
detail=f"TaskV2 {workflow_tasks[0].task_id} is still in use",
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
await db.delete(task_group)
|
|
232
|
-
await db.commit()
|
|
233
|
-
|
|
234
|
-
return Response(status_code=status.HTTP_204_NO_CONTENT)
|
|
235
|
-
|
|
236
|
-
|
|
237
199
|
@router.patch("/{task_group_id}/", response_model=TaskGroupReadV2)
|
|
238
200
|
async def patch_task_group(
|
|
239
201
|
task_group_id: int,
|
|
@@ -7,6 +7,7 @@ from fastapi import status
|
|
|
7
7
|
|
|
8
8
|
from ...aux.validate_user_settings import validate_user_settings
|
|
9
9
|
from ._aux_functions_task_lifecycle import check_no_ongoing_activity
|
|
10
|
+
from ._aux_functions_task_lifecycle import check_no_related_workflowtask
|
|
10
11
|
from ._aux_functions_task_lifecycle import check_no_submitted_job
|
|
11
12
|
from ._aux_functions_tasks import _get_task_group_full_access
|
|
12
13
|
from fractal_server.app.db import AsyncSession
|
|
@@ -25,10 +26,12 @@ from fractal_server.ssh._fabric import SSHConfig
|
|
|
25
26
|
from fractal_server.syringe import Inject
|
|
26
27
|
from fractal_server.tasks.v2.local import deactivate_local
|
|
27
28
|
from fractal_server.tasks.v2.local import deactivate_local_pixi
|
|
29
|
+
from fractal_server.tasks.v2.local import delete_local
|
|
28
30
|
from fractal_server.tasks.v2.local import reactivate_local
|
|
29
31
|
from fractal_server.tasks.v2.local import reactivate_local_pixi
|
|
30
32
|
from fractal_server.tasks.v2.ssh import deactivate_ssh
|
|
31
33
|
from fractal_server.tasks.v2.ssh import deactivate_ssh_pixi
|
|
34
|
+
from fractal_server.tasks.v2.ssh import delete_ssh
|
|
32
35
|
from fractal_server.tasks.v2.ssh import reactivate_ssh
|
|
33
36
|
from fractal_server.tasks.v2.ssh import reactivate_ssh_pixi
|
|
34
37
|
from fractal_server.utils import get_timestamp
|
|
@@ -281,3 +284,69 @@ async def reactivate_task_group(
|
|
|
281
284
|
)
|
|
282
285
|
response.status_code = status.HTTP_202_ACCEPTED
|
|
283
286
|
return task_group_activity
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
@router.post(
|
|
290
|
+
"/{task_group_id}/delete/",
|
|
291
|
+
status_code=202,
|
|
292
|
+
)
|
|
293
|
+
async def delete_task_group(
|
|
294
|
+
task_group_id: int,
|
|
295
|
+
background_tasks: BackgroundTasks,
|
|
296
|
+
response: Response,
|
|
297
|
+
user: UserOAuth = Depends(current_active_user),
|
|
298
|
+
db: AsyncSession = Depends(get_async_db),
|
|
299
|
+
) -> TaskGroupActivityV2Read:
|
|
300
|
+
"""
|
|
301
|
+
Deletion of task-group from db and file system
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
task_group = await _get_task_group_full_access(
|
|
305
|
+
task_group_id=task_group_id,
|
|
306
|
+
user_id=user.id,
|
|
307
|
+
db=db,
|
|
308
|
+
)
|
|
309
|
+
await check_no_ongoing_activity(task_group_id=task_group_id, db=db)
|
|
310
|
+
await check_no_related_workflowtask(task_group=task_group, db=db)
|
|
311
|
+
|
|
312
|
+
task_group_activity = TaskGroupActivityV2(
|
|
313
|
+
user_id=task_group.user_id,
|
|
314
|
+
taskgroupv2_id=task_group.id,
|
|
315
|
+
status=TaskGroupActivityStatusV2.PENDING,
|
|
316
|
+
action=TaskGroupActivityActionV2.DELETE,
|
|
317
|
+
pkg_name=task_group.pkg_name,
|
|
318
|
+
version=(task_group.version or "N/A"),
|
|
319
|
+
timestamp_started=get_timestamp(),
|
|
320
|
+
)
|
|
321
|
+
db.add(task_group_activity)
|
|
322
|
+
await db.commit()
|
|
323
|
+
|
|
324
|
+
settings = Inject(get_settings)
|
|
325
|
+
if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
|
|
326
|
+
# Validate user settings (backend-specific)
|
|
327
|
+
user_settings = await validate_user_settings(
|
|
328
|
+
user=user, backend=settings.FRACTAL_RUNNER_BACKEND, db=db
|
|
329
|
+
)
|
|
330
|
+
# User appropriate FractalSSH object
|
|
331
|
+
ssh_config = SSHConfig(
|
|
332
|
+
user=user_settings.ssh_username,
|
|
333
|
+
host=user_settings.ssh_host,
|
|
334
|
+
key_path=user_settings.ssh_private_key_path,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
background_tasks.add_task(
|
|
338
|
+
delete_ssh,
|
|
339
|
+
task_group_id=task_group.id,
|
|
340
|
+
task_group_activity_id=task_group_activity.id,
|
|
341
|
+
ssh_config=ssh_config,
|
|
342
|
+
tasks_base_dir=user_settings.ssh_tasks_dir,
|
|
343
|
+
)
|
|
344
|
+
else:
|
|
345
|
+
background_tasks.add_task(
|
|
346
|
+
delete_local,
|
|
347
|
+
task_group_id=task_group.id,
|
|
348
|
+
task_group_activity_id=task_group_activity.id,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
response.status_code = status.HTTP_202_ACCEPTED
|
|
352
|
+
return task_group_activity
|
{fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/app/runner/v2/runner.py
RENAMED
|
@@ -194,6 +194,16 @@ def execute_tasks_v2(
|
|
|
194
194
|
db.refresh(history_run)
|
|
195
195
|
history_run_id = history_run.id
|
|
196
196
|
|
|
197
|
+
# Refresh `job.executor_error_log`, to avoid a spurious value left
|
|
198
|
+
# over from a previous task
|
|
199
|
+
job_db = db.get(JobV2, job_id)
|
|
200
|
+
job_db.executor_error_log = None
|
|
201
|
+
logger.debug(
|
|
202
|
+
f"Resetting `JobV2[{job_id}].executor_error_log` to None."
|
|
203
|
+
)
|
|
204
|
+
db.merge(job_db)
|
|
205
|
+
db.commit()
|
|
206
|
+
|
|
197
207
|
# TASK EXECUTION (V2)
|
|
198
208
|
try:
|
|
199
209
|
if task.type in [
|
|
@@ -244,6 +244,7 @@ def submit_workflow(
|
|
|
244
244
|
logger.debug(f"job.first_task_index: {job.first_task_index}")
|
|
245
245
|
logger.debug(f"job.last_task_index: {job.last_task_index}")
|
|
246
246
|
logger.debug(f'START workflow "{workflow.name}"')
|
|
247
|
+
job_working_dir = job.working_dir
|
|
247
248
|
|
|
248
249
|
try:
|
|
249
250
|
if FRACTAL_RUNNER_BACKEND == "local":
|
|
@@ -267,19 +268,6 @@ def submit_workflow(
|
|
|
267
268
|
f"Invalid runner backend {FRACTAL_RUNNER_BACKEND=}"
|
|
268
269
|
)
|
|
269
270
|
|
|
270
|
-
# "The Session.close() method does not prevent the Session from being
|
|
271
|
-
# used again. The Session itself does not actually have a distinct
|
|
272
|
-
# “closed” state; it merely means the Session will release all database
|
|
273
|
-
# connections and ORM objects."
|
|
274
|
-
# (https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.close).
|
|
275
|
-
#
|
|
276
|
-
# We close the session before the (possibly long) process_workflow
|
|
277
|
-
# call, to make sure all DB connections are released. The reason why we
|
|
278
|
-
# are not using a context manager within the try block is that we also
|
|
279
|
-
# need access to db_sync in the except branches.
|
|
280
|
-
db_sync = next(DB.get_sync_db())
|
|
281
|
-
db_sync.close()
|
|
282
|
-
|
|
283
271
|
process_workflow(
|
|
284
272
|
workflow=workflow,
|
|
285
273
|
dataset=dataset,
|
|
@@ -303,47 +291,48 @@ def submit_workflow(
|
|
|
303
291
|
logger.debug(f'END workflow "{workflow.name}"')
|
|
304
292
|
|
|
305
293
|
# Update job DB entry
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
294
|
+
with next(DB.get_sync_db()) as db_sync:
|
|
295
|
+
job = db_sync.get(JobV2, job_id)
|
|
296
|
+
job.status = JobStatusTypeV2.DONE
|
|
297
|
+
job.end_timestamp = get_timestamp()
|
|
298
|
+
with log_file_path.open("r") as f:
|
|
299
|
+
logs = f.read()
|
|
300
|
+
job.log = logs
|
|
301
|
+
db_sync.merge(job)
|
|
302
|
+
db_sync.commit()
|
|
314
303
|
|
|
315
304
|
except JobExecutionError as e:
|
|
316
305
|
logger.debug(f'FAILED workflow "{workflow.name}", JobExecutionError.')
|
|
317
306
|
logger.info(f'Workflow "{workflow.name}" failed (JobExecutionError).')
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
307
|
+
with next(DB.get_sync_db()) as db_sync:
|
|
308
|
+
job = db_sync.get(JobV2, job_id)
|
|
309
|
+
fail_job(
|
|
310
|
+
db=db_sync,
|
|
311
|
+
job=job,
|
|
312
|
+
log_msg=(
|
|
313
|
+
f"JOB ERROR in Fractal job {job.id}:\n"
|
|
314
|
+
f"TRACEBACK:\n{e.assemble_error()}"
|
|
315
|
+
),
|
|
316
|
+
logger_name=logger_name,
|
|
317
|
+
)
|
|
328
318
|
|
|
329
319
|
except Exception:
|
|
330
320
|
logger.debug(f'FAILED workflow "{workflow.name}", unknown error.')
|
|
331
321
|
logger.info(f'Workflow "{workflow.name}" failed (unkwnon error).')
|
|
332
322
|
|
|
333
323
|
current_traceback = traceback.format_exc()
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
324
|
+
with next(DB.get_sync_db()) as db_sync:
|
|
325
|
+
job = db_sync.get(JobV2, job_id)
|
|
326
|
+
fail_job(
|
|
327
|
+
db=db_sync,
|
|
328
|
+
job=job,
|
|
329
|
+
log_msg=(
|
|
330
|
+
f"UNKNOWN ERROR in Fractal job {job.id}\n"
|
|
331
|
+
f"TRACEBACK:\n{current_traceback}"
|
|
332
|
+
),
|
|
333
|
+
logger_name=logger_name,
|
|
334
|
+
)
|
|
343
335
|
|
|
344
336
|
finally:
|
|
345
337
|
reset_logger_handlers(logger)
|
|
346
|
-
|
|
347
|
-
job = db_sync.get(JobV2, job_id)
|
|
348
|
-
db_sync.close()
|
|
349
|
-
_zip_folder_to_file_and_remove(folder=job.working_dir)
|
|
338
|
+
_zip_folder_to_file_and_remove(folder=job_working_dir)
|
{fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/local/__init__.py
RENAMED
|
@@ -2,5 +2,6 @@ from .collect import collect_local # noqa
|
|
|
2
2
|
from .collect_pixi import collect_local_pixi # noqa
|
|
3
3
|
from .deactivate import deactivate_local # noqa
|
|
4
4
|
from .deactivate_pixi import deactivate_local_pixi # noqa
|
|
5
|
+
from .delete import delete_local # noqa
|
|
5
6
|
from .reactivate import reactivate_local # noqa
|
|
6
7
|
from .reactivate_pixi import reactivate_local_pixi # noqa
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from tempfile import TemporaryDirectory
|
|
4
|
+
|
|
5
|
+
from fractal_server.app.db import get_sync_db
|
|
6
|
+
from fractal_server.app.schemas.v2 import TaskGroupActivityStatusV2
|
|
7
|
+
from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
|
|
8
|
+
from fractal_server.logger import reset_logger_handlers
|
|
9
|
+
from fractal_server.logger import set_logger
|
|
10
|
+
from fractal_server.tasks.utils import get_log_path
|
|
11
|
+
from fractal_server.tasks.v2.utils_background import add_commit_refresh
|
|
12
|
+
from fractal_server.tasks.v2.utils_background import fail_and_cleanup
|
|
13
|
+
from fractal_server.tasks.v2.utils_background import (
|
|
14
|
+
get_activity_and_task_group,
|
|
15
|
+
)
|
|
16
|
+
from fractal_server.tasks.v2.utils_background import get_current_log
|
|
17
|
+
from fractal_server.utils import get_timestamp
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def delete_local(
|
|
21
|
+
*,
|
|
22
|
+
task_group_activity_id: int,
|
|
23
|
+
task_group_id: int,
|
|
24
|
+
) -> None:
|
|
25
|
+
LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
|
|
26
|
+
|
|
27
|
+
with TemporaryDirectory() as tmpdir:
|
|
28
|
+
log_file_path = get_log_path(Path(tmpdir))
|
|
29
|
+
|
|
30
|
+
logger = set_logger(
|
|
31
|
+
logger_name=LOGGER_NAME,
|
|
32
|
+
log_file_path=log_file_path,
|
|
33
|
+
)
|
|
34
|
+
logger.debug("START")
|
|
35
|
+
with next(get_sync_db()) as db:
|
|
36
|
+
db_objects_ok, task_group, activity = get_activity_and_task_group(
|
|
37
|
+
task_group_activity_id=task_group_activity_id,
|
|
38
|
+
task_group_id=task_group_id,
|
|
39
|
+
db=db,
|
|
40
|
+
logger_name=LOGGER_NAME,
|
|
41
|
+
)
|
|
42
|
+
if not db_objects_ok:
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
activity.status = TaskGroupActivityStatusV2.ONGOING
|
|
47
|
+
activity.log = get_current_log(log_file_path)
|
|
48
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
|
49
|
+
|
|
50
|
+
db.commit()
|
|
51
|
+
db.delete(task_group)
|
|
52
|
+
logger.debug("Task group removed from database.")
|
|
53
|
+
|
|
54
|
+
if task_group.origin != TaskGroupV2OriginEnum.OTHER:
|
|
55
|
+
logger.debug(f"Removing {task_group.path=}.")
|
|
56
|
+
shutil.rmtree(task_group.path)
|
|
57
|
+
logger.debug(f"{task_group.path=} removed.")
|
|
58
|
+
|
|
59
|
+
activity.status = TaskGroupActivityStatusV2.OK
|
|
60
|
+
activity.log = get_current_log(log_file_path)
|
|
61
|
+
activity.timestamp_ended = get_timestamp()
|
|
62
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
|
63
|
+
|
|
64
|
+
logger.debug("END")
|
|
65
|
+
|
|
66
|
+
except Exception as delete_e:
|
|
67
|
+
fail_and_cleanup(
|
|
68
|
+
task_group=task_group,
|
|
69
|
+
task_group_activity=activity,
|
|
70
|
+
logger_name=LOGGER_NAME,
|
|
71
|
+
log_file_path=log_file_path,
|
|
72
|
+
exception=delete_e,
|
|
73
|
+
db=db,
|
|
74
|
+
)
|
|
75
|
+
finally:
|
|
76
|
+
reset_logger_handlers(logger)
|
{fractal_server-2.15.10a2 → fractal_server-2.15.10a3}/fractal_server/tasks/v2/ssh/__init__.py
RENAMED
|
@@ -2,5 +2,6 @@ from .collect import collect_ssh # noqa
|
|
|
2
2
|
from .collect_pixi import collect_ssh_pixi # noqa
|
|
3
3
|
from .deactivate import deactivate_ssh # noqa
|
|
4
4
|
from .deactivate_pixi import deactivate_ssh_pixi # noqa
|
|
5
|
+
from .delete import delete_ssh # noqa
|
|
5
6
|
from .reactivate import reactivate_ssh # noqa
|
|
6
7
|
from .reactivate_pixi import reactivate_ssh_pixi # noqa
|