fractal-server 2.16.2a0__tar.gz → 2.16.3__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.16.2a0 → fractal_server-2.16.3}/PKG-INFO +2 -2
- fractal_server-2.16.3/fractal_server/__init__.py +1 -0
- fractal_server-2.16.3/fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +255 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/collect_pixi.py +20 -15
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/reactivate_pixi.py +20 -15
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/utils_background.py +1 -1
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/pyproject.toml +3 -3
- fractal_server-2.16.2a0/fractal_server/__init__.py +0 -1
- fractal_server-2.16.2a0/fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +0 -115
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/LICENSE +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/README.md +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/__main__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/accounting.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/history.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/task.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/task_group.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/job.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/task.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/history.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/pre_submission_checks.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/status_legacy.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/task_collection_pixi.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/task_group.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/task_version_update.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/workflow.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/pagination.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/base_runner.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/call_command_wrapper.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/local/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/local/get_local_config.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/local/runner.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/_batching.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/_job_states.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/_slurm_config.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/remote.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_ssh/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_ssh/runner.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_ssh/tar_commands.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/executors/slurm_sudo/runner.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/task_files.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/_local.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/_slurm_ssh.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/_slurm_sudo.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/db_tools.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/runner.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/runner_functions.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/submit_workflow.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/accounting.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/dataset.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/history.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/task_collection.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/task_group.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/security/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/security/signup_email.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/config.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/data_migrations/2_14_10.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/exceptions.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/images/models.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/images/status_tools.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/logger.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/main.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/1a83a5260664_rename.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/791ce783d3d8_add_indices.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/py.typed +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/ssh/_fabric.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/string_tools.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/syringe.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/utils.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/_utils.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/collect.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/collect_pixi.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/deactivate.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/deactivate_pixi.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/delete.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/reactivate.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/local/reactivate_pixi.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/collect.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/deactivate_pixi.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/delete.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/pixi_1_extract.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/pixi_2_install.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/templates/pixi_3_post_install.sh +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/utils_database.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/utils_package_names.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/utils_pixi.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/utils_templates.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/types/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/types/validators/__init__.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/types/validators/_common_validators.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/types/validators/_filter_validators.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/types/validators/_workflow_task_arguments_validators.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/urls.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/utils.py +0 -0
- {fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/zip_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: fractal-server
|
|
3
|
-
Version: 2.16.
|
|
3
|
+
Version: 2.16.3
|
|
4
4
|
Summary: Backend component of the Fractal analytics platform
|
|
5
5
|
License: BSD-3-Clause
|
|
6
6
|
Author: Tommaso Comparin
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
14
|
Requires-Dist: alembic (>=1.13.1,<2.0.0)
|
|
15
|
-
Requires-Dist: cryptography (>=
|
|
15
|
+
Requires-Dist: cryptography (>=46.0.0,<47.0.0)
|
|
16
16
|
Requires-Dist: fabric (>=3.2.2,<3.3.0)
|
|
17
17
|
Requires-Dist: fastapi (>=0.116.0,<0.117.0)
|
|
18
18
|
Requires-Dist: fastapi-users[oauth] (>=14,<15)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__VERSION__ = "2.16.3"
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from sqlalchemy.orm import Session
|
|
6
|
+
|
|
7
|
+
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
|
8
|
+
from fractal_server.config import get_settings
|
|
9
|
+
from fractal_server.config import PixiSLURMConfig
|
|
10
|
+
from fractal_server.logger import get_logger
|
|
11
|
+
from fractal_server.ssh._fabric import FractalSSH
|
|
12
|
+
from fractal_server.syringe import Inject
|
|
13
|
+
from fractal_server.tasks.v2.utils_background import add_commit_refresh
|
|
14
|
+
from fractal_server.tasks.v2.utils_background import get_current_log
|
|
15
|
+
|
|
16
|
+
FRACTAL_SQUEUE_ERROR_STATE = "__FRACTAL_SQUEUE_ERROR__"
|
|
17
|
+
|
|
18
|
+
# https://slurm.schedmd.com/squeue.html#lbAG
|
|
19
|
+
STATES_FINISHED = {
|
|
20
|
+
"BOOT_FAIL",
|
|
21
|
+
"CANCELLED",
|
|
22
|
+
"COMPLETED",
|
|
23
|
+
"DEADLINE",
|
|
24
|
+
"FAILED",
|
|
25
|
+
"NODE_FAIL",
|
|
26
|
+
"OUT_OF_MEMORY",
|
|
27
|
+
"PREEMPTED",
|
|
28
|
+
"SPECIAL_EXIT",
|
|
29
|
+
"TIMEOUT",
|
|
30
|
+
FRACTAL_SQUEUE_ERROR_STATE,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _get_workdir_remote(script_paths: list[str]) -> str:
|
|
35
|
+
"""
|
|
36
|
+
Check that there is one and only one `workdir`, and return it.
|
|
37
|
+
|
|
38
|
+
Note: The `is_absolute` check is to filter out a `chmod` command.
|
|
39
|
+
"""
|
|
40
|
+
workdirs = [
|
|
41
|
+
Path(script_path).parent.as_posix()
|
|
42
|
+
for script_path in script_paths
|
|
43
|
+
if Path(script_path).is_absolute()
|
|
44
|
+
]
|
|
45
|
+
if not len(set(workdirs)) == 1:
|
|
46
|
+
raise ValueError(f"Invalid {script_paths=}.")
|
|
47
|
+
return workdirs[0]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _read_file_if_exists(
|
|
51
|
+
*,
|
|
52
|
+
fractal_ssh: FractalSSH,
|
|
53
|
+
path: str,
|
|
54
|
+
) -> str:
|
|
55
|
+
"""
|
|
56
|
+
Read a remote file if it exists, or return an empty string.
|
|
57
|
+
"""
|
|
58
|
+
if fractal_ssh.remote_exists(path=path):
|
|
59
|
+
return fractal_ssh.read_remote_text_file(path)
|
|
60
|
+
else:
|
|
61
|
+
return ""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _log_change_of_job_state(
|
|
65
|
+
*,
|
|
66
|
+
old_state: str | None,
|
|
67
|
+
new_state: str,
|
|
68
|
+
logger_name: str,
|
|
69
|
+
) -> None:
|
|
70
|
+
"""
|
|
71
|
+
Emit a log for state changes.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
old_state:
|
|
75
|
+
new_state:
|
|
76
|
+
logger_name:
|
|
77
|
+
"""
|
|
78
|
+
if new_state != old_state:
|
|
79
|
+
logger = get_logger(logger_name=logger_name)
|
|
80
|
+
logger.debug(
|
|
81
|
+
f"SLURM-job state changed from {old_state=} to {new_state=}."
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _run_squeue(
|
|
86
|
+
*,
|
|
87
|
+
fractal_ssh: FractalSSH,
|
|
88
|
+
squeue_cmd: str,
|
|
89
|
+
logger_name: str,
|
|
90
|
+
) -> str:
|
|
91
|
+
"""
|
|
92
|
+
Run a `squeue` command and handle exceptions.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
fractal_ssh:
|
|
96
|
+
logger_name:
|
|
97
|
+
squeue_cmd:
|
|
98
|
+
|
|
99
|
+
Return:
|
|
100
|
+
state: The SLURM-job state.
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
cmd_stdout = fractal_ssh.run_command(cmd=squeue_cmd)
|
|
104
|
+
state = cmd_stdout.strip().split()[1]
|
|
105
|
+
return state
|
|
106
|
+
except Exception as e:
|
|
107
|
+
logger = get_logger(logger_name=logger_name)
|
|
108
|
+
logger.info(f"`squeue` command failed (original error: {e})")
|
|
109
|
+
return FRACTAL_SQUEUE_ERROR_STATE
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _verify_success_file_exists(
|
|
113
|
+
*,
|
|
114
|
+
fractal_ssh: FractalSSH,
|
|
115
|
+
success_file_remote: str,
|
|
116
|
+
logger_name: str,
|
|
117
|
+
stderr_remote: str,
|
|
118
|
+
) -> None:
|
|
119
|
+
"""
|
|
120
|
+
Fail if the success sentinel file does not exist remotely.
|
|
121
|
+
|
|
122
|
+
Note: the `FractalSSH` methods in this function may fail, and such failures
|
|
123
|
+
are not handled in this function. Any such failure, however, will lead to
|
|
124
|
+
a "failed" task-group lifecycle activity (because it will raise an
|
|
125
|
+
exception from within `run_script_on_remote_slurm`, which will then be
|
|
126
|
+
handled at the calling-function level.
|
|
127
|
+
"""
|
|
128
|
+
if not fractal_ssh.remote_exists(path=success_file_remote):
|
|
129
|
+
logger = get_logger(logger_name=logger_name)
|
|
130
|
+
error_msg = f"{success_file_remote=} missing."
|
|
131
|
+
logger.info(error_msg)
|
|
132
|
+
|
|
133
|
+
stderr = _read_file_if_exists(
|
|
134
|
+
fractal_ssh=fractal_ssh, path=stderr_remote
|
|
135
|
+
)
|
|
136
|
+
if stderr:
|
|
137
|
+
logger.info(f"SLURM-job stderr:\n{stderr}")
|
|
138
|
+
raise RuntimeError(error_msg)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def run_script_on_remote_slurm(
|
|
142
|
+
*,
|
|
143
|
+
script_paths: list[str],
|
|
144
|
+
slurm_config: PixiSLURMConfig,
|
|
145
|
+
fractal_ssh: FractalSSH,
|
|
146
|
+
logger_name: str,
|
|
147
|
+
log_file_path: Path,
|
|
148
|
+
prefix: str,
|
|
149
|
+
db: Session,
|
|
150
|
+
activity: TaskGroupActivityV2,
|
|
151
|
+
):
|
|
152
|
+
"""
|
|
153
|
+
Run a `pixi install` script as a SLURM job.
|
|
154
|
+
|
|
155
|
+
NOTE: This is called from within a try/except, thus we can use exceptions
|
|
156
|
+
as a mechanism to propagate failure/errors.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
logger = get_logger(logger_name=logger_name)
|
|
160
|
+
settings = Inject(get_settings)
|
|
161
|
+
|
|
162
|
+
# (1) Prepare remote submission script
|
|
163
|
+
workdir_remote = _get_workdir_remote(script_paths)
|
|
164
|
+
submission_script_remote = os.path.join(
|
|
165
|
+
workdir_remote, f"{prefix}-submit.sh"
|
|
166
|
+
)
|
|
167
|
+
stderr_remote = os.path.join(workdir_remote, f"{prefix}-err.txt")
|
|
168
|
+
stdout_remote = os.path.join(workdir_remote, f"{prefix}-out.txt")
|
|
169
|
+
success_file_remote = os.path.join(workdir_remote, f"{prefix}-success.txt")
|
|
170
|
+
script_lines = [
|
|
171
|
+
"#!/bin/bash",
|
|
172
|
+
f"#SBATCH --partition={slurm_config.partition}",
|
|
173
|
+
f"#SBATCH --cpus-per-task={slurm_config.cpus}",
|
|
174
|
+
f"#SBATCH --mem={slurm_config.mem}",
|
|
175
|
+
f"#SBATCH --time={slurm_config.time}",
|
|
176
|
+
f"#SBATCH --err={stderr_remote}",
|
|
177
|
+
f"#SBATCH --out={stdout_remote}",
|
|
178
|
+
f"#SBATCH -D {workdir_remote}",
|
|
179
|
+
"",
|
|
180
|
+
]
|
|
181
|
+
for script_path in script_paths:
|
|
182
|
+
script_lines.append(f"bash {script_path}")
|
|
183
|
+
script_lines.append(f"touch {success_file_remote}")
|
|
184
|
+
|
|
185
|
+
script_contents = "\n".join(script_lines)
|
|
186
|
+
fractal_ssh.write_remote_file(
|
|
187
|
+
path=submission_script_remote,
|
|
188
|
+
content=script_contents,
|
|
189
|
+
)
|
|
190
|
+
logger.debug(f"Written {submission_script_remote=}.")
|
|
191
|
+
|
|
192
|
+
activity.log = get_current_log(log_file_path)
|
|
193
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
|
194
|
+
|
|
195
|
+
# (2) Submit SLURM job
|
|
196
|
+
logger.debug("Now submit SLURM job.")
|
|
197
|
+
sbatch_cmd = f"sbatch --parsable {submission_script_remote}"
|
|
198
|
+
try:
|
|
199
|
+
stdout = fractal_ssh.run_command(cmd=sbatch_cmd)
|
|
200
|
+
job_id = int(stdout)
|
|
201
|
+
logger.debug(f"SLURM-job submission successful ({job_id=}).")
|
|
202
|
+
except Exception as e:
|
|
203
|
+
logger.error(
|
|
204
|
+
(
|
|
205
|
+
f"Submission of {submission_script_remote} failed. "
|
|
206
|
+
f"Original error: {str(e)}"
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
raise e
|
|
210
|
+
finally:
|
|
211
|
+
activity.log = get_current_log(log_file_path)
|
|
212
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
|
213
|
+
|
|
214
|
+
# (3) Monitor job
|
|
215
|
+
squeue_cmd = (
|
|
216
|
+
f"squeue --noheader --format='%i %T' --states=all --jobs={job_id}"
|
|
217
|
+
)
|
|
218
|
+
logger.debug(f"Start monitoring job with {squeue_cmd=}.")
|
|
219
|
+
old_state = None
|
|
220
|
+
while True:
|
|
221
|
+
new_state = _run_squeue(
|
|
222
|
+
fractal_ssh=fractal_ssh,
|
|
223
|
+
squeue_cmd=squeue_cmd,
|
|
224
|
+
logger_name=logger_name,
|
|
225
|
+
)
|
|
226
|
+
_log_change_of_job_state(
|
|
227
|
+
old_state=old_state,
|
|
228
|
+
new_state=new_state,
|
|
229
|
+
logger_name=logger_name,
|
|
230
|
+
)
|
|
231
|
+
activity.log = get_current_log(log_file_path)
|
|
232
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
|
233
|
+
if new_state in STATES_FINISHED:
|
|
234
|
+
logger.debug(f"Exit retrieval loop (state={new_state}).")
|
|
235
|
+
break
|
|
236
|
+
old_state = new_state
|
|
237
|
+
time.sleep(settings.FRACTAL_SLURM_POLL_INTERVAL)
|
|
238
|
+
|
|
239
|
+
_verify_success_file_exists(
|
|
240
|
+
fractal_ssh=fractal_ssh,
|
|
241
|
+
logger_name=logger_name,
|
|
242
|
+
success_file_remote=success_file_remote,
|
|
243
|
+
stderr_remote=stderr_remote,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
stdout = _read_file_if_exists(
|
|
247
|
+
fractal_ssh=fractal_ssh,
|
|
248
|
+
path=stdout_remote,
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
logger.info("SLURM-job execution completed successfully, continue.")
|
|
252
|
+
activity.log = get_current_log(log_file_path)
|
|
253
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
|
254
|
+
|
|
255
|
+
return stdout
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/collect_pixi.py
RENAMED
|
@@ -203,12 +203,21 @@ def collect_ssh_pixi(
|
|
|
203
203
|
pyproject_toml_path=pyproject_toml_path,
|
|
204
204
|
)
|
|
205
205
|
|
|
206
|
-
#
|
|
206
|
+
# Prepare scripts 2 and 3
|
|
207
207
|
remote_script2_path = _customize_and_send_template(
|
|
208
208
|
template_filename="pixi_2_install.sh",
|
|
209
209
|
replacements=replacements,
|
|
210
210
|
**common_args,
|
|
211
211
|
)
|
|
212
|
+
remote_script3_path = _customize_and_send_template(
|
|
213
|
+
template_filename="pixi_3_post_install.sh",
|
|
214
|
+
replacements=replacements,
|
|
215
|
+
**common_args,
|
|
216
|
+
)
|
|
217
|
+
logger.debug(
|
|
218
|
+
"Post-installation script written to "
|
|
219
|
+
f"{remote_script3_path=}."
|
|
220
|
+
)
|
|
212
221
|
logger.debug(
|
|
213
222
|
"Installation script written to "
|
|
214
223
|
f"{remote_script2_path=}."
|
|
@@ -216,26 +225,24 @@ def collect_ssh_pixi(
|
|
|
216
225
|
activity.log = get_current_log(log_file_path)
|
|
217
226
|
activity = add_commit_refresh(obj=activity, db=db)
|
|
218
227
|
|
|
219
|
-
|
|
220
|
-
|
|
228
|
+
# Run scripts 2 and 3
|
|
229
|
+
stdout = run_script_on_remote_slurm(
|
|
230
|
+
script_paths=[
|
|
231
|
+
remote_script2_path,
|
|
232
|
+
remote_script3_path,
|
|
233
|
+
f"chmod -R 755 {source_dir}",
|
|
234
|
+
],
|
|
221
235
|
slurm_config=settings.pixi.SLURM_CONFIG,
|
|
222
236
|
fractal_ssh=fractal_ssh,
|
|
223
237
|
logger_name=LOGGER_NAME,
|
|
224
238
|
prefix=common_args["prefix"],
|
|
239
|
+
db=db,
|
|
240
|
+
activity=activity,
|
|
241
|
+
log_file_path=log_file_path,
|
|
225
242
|
)
|
|
226
243
|
activity.log = get_current_log(log_file_path)
|
|
227
244
|
activity = add_commit_refresh(obj=activity, db=db)
|
|
228
245
|
|
|
229
|
-
# Run script 3 - post-install
|
|
230
|
-
stdout = _customize_and_run_template(
|
|
231
|
-
template_filename="pixi_3_post_install.sh",
|
|
232
|
-
replacements=replacements,
|
|
233
|
-
**common_args,
|
|
234
|
-
)
|
|
235
|
-
logger.debug(f"STDOUT: {stdout}")
|
|
236
|
-
activity.log = get_current_log(log_file_path)
|
|
237
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
|
238
|
-
|
|
239
246
|
# Parse stdout
|
|
240
247
|
parsed_output = parse_collect_stdout(stdout)
|
|
241
248
|
package_root_remote = parsed_output["package_root"]
|
|
@@ -245,8 +252,6 @@ def collect_ssh_pixi(
|
|
|
245
252
|
"project_python_wrapper"
|
|
246
253
|
]
|
|
247
254
|
|
|
248
|
-
fractal_ssh.run_command(cmd=f"chmod -R 755 {source_dir}")
|
|
249
|
-
|
|
250
255
|
# Read and validate remote manifest file
|
|
251
256
|
manifest_path_remote = (
|
|
252
257
|
f"{package_root_remote}/__FRACTAL_MANIFEST__.json"
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/tasks/v2/ssh/reactivate_pixi.py
RENAMED
|
@@ -188,12 +188,21 @@ def reactivate_ssh_pixi(
|
|
|
188
188
|
remote=pixi_lock_remote,
|
|
189
189
|
)
|
|
190
190
|
|
|
191
|
-
#
|
|
191
|
+
# Prepare scripts 2 and 3
|
|
192
192
|
remote_script2_path = _customize_and_send_template(
|
|
193
193
|
template_filename="pixi_2_install.sh",
|
|
194
194
|
replacements=replacements,
|
|
195
195
|
**common_args,
|
|
196
196
|
)
|
|
197
|
+
remote_script3_path = _customize_and_send_template(
|
|
198
|
+
template_filename="pixi_3_post_install.sh",
|
|
199
|
+
replacements=replacements,
|
|
200
|
+
**common_args,
|
|
201
|
+
)
|
|
202
|
+
logger.debug(
|
|
203
|
+
"Post-installation script written to "
|
|
204
|
+
f"{remote_script3_path=}."
|
|
205
|
+
)
|
|
197
206
|
logger.debug(
|
|
198
207
|
"Installation script written to "
|
|
199
208
|
f"{remote_script2_path=}."
|
|
@@ -201,28 +210,24 @@ def reactivate_ssh_pixi(
|
|
|
201
210
|
activity.log = get_current_log(log_file_path)
|
|
202
211
|
activity = add_commit_refresh(obj=activity, db=db)
|
|
203
212
|
|
|
204
|
-
|
|
205
|
-
|
|
213
|
+
# Run scripts 2 and 3
|
|
214
|
+
stdout = run_script_on_remote_slurm(
|
|
215
|
+
script_paths=[
|
|
216
|
+
remote_script2_path,
|
|
217
|
+
remote_script3_path,
|
|
218
|
+
f"chmod -R 755 {source_dir}",
|
|
219
|
+
],
|
|
206
220
|
slurm_config=settings.pixi.SLURM_CONFIG,
|
|
207
221
|
fractal_ssh=fractal_ssh,
|
|
208
222
|
logger_name=LOGGER_NAME,
|
|
209
223
|
prefix=common_args["prefix"],
|
|
224
|
+
db=db,
|
|
225
|
+
activity=activity,
|
|
226
|
+
log_file_path=log_file_path,
|
|
210
227
|
)
|
|
211
228
|
activity.log = get_current_log(log_file_path)
|
|
212
229
|
activity = add_commit_refresh(obj=activity, db=db)
|
|
213
230
|
|
|
214
|
-
# Run script 3 - post-install
|
|
215
|
-
stdout = _customize_and_run_template(
|
|
216
|
-
template_filename="pixi_3_post_install.sh",
|
|
217
|
-
replacements=replacements,
|
|
218
|
-
**common_args,
|
|
219
|
-
)
|
|
220
|
-
logger.debug(f"STDOUT: {stdout}")
|
|
221
|
-
activity.log = get_current_log(log_file_path)
|
|
222
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
|
223
|
-
|
|
224
|
-
fractal_ssh.run_command(cmd=f"chmod -R 755 {source_dir}")
|
|
225
|
-
|
|
226
231
|
# Finalize (write metadata to DB)
|
|
227
232
|
activity.status = TaskGroupActivityStatusV2.OK
|
|
228
233
|
activity.timestamp_ended = get_timestamp()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "fractal-server"
|
|
3
|
-
version = "2.16.
|
|
3
|
+
version = "2.16.3"
|
|
4
4
|
description = "Backend component of the Fractal analytics platform"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name="Tommaso Comparin", email="tommaso.comparin@exact-lab.it" },
|
|
@@ -26,7 +26,7 @@ dependencies = [
|
|
|
26
26
|
"fabric >= 3.2.2, <3.3.0",
|
|
27
27
|
"gunicorn >=23.0,<24.0",
|
|
28
28
|
"psycopg[binary] >= 3.1.0, <4.0.0",
|
|
29
|
-
"cryptography >=
|
|
29
|
+
"cryptography >=46.0.0,<47.0.0",
|
|
30
30
|
"tomli_w >=1.2.0, <1.3.0 "
|
|
31
31
|
]
|
|
32
32
|
|
|
@@ -95,7 +95,7 @@ filterwarnings = [
|
|
|
95
95
|
markers = ["container", "ssh", "fails_on_macos"]
|
|
96
96
|
|
|
97
97
|
[tool.bumpver]
|
|
98
|
-
current_version = "2.16.
|
|
98
|
+
current_version = "2.16.3"
|
|
99
99
|
version_pattern = "MAJOR.MINOR.PATCH[PYTAGNUM]"
|
|
100
100
|
commit_message = "bump version {old_version} -> {new_version}"
|
|
101
101
|
commit = true
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__VERSION__ = "2.16.2a0"
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import time
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
from fractal_server.config import get_settings
|
|
6
|
-
from fractal_server.config import PixiSLURMConfig
|
|
7
|
-
from fractal_server.logger import get_logger
|
|
8
|
-
from fractal_server.ssh._fabric import FractalSSH
|
|
9
|
-
from fractal_server.syringe import Inject
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# https://slurm.schedmd.com/squeue.html#lbAG
|
|
13
|
-
STATES_FINISHED = {
|
|
14
|
-
"BOOT_FAIL",
|
|
15
|
-
"CANCELLED",
|
|
16
|
-
"COMPLETED",
|
|
17
|
-
"DEADLINE",
|
|
18
|
-
"FAILED",
|
|
19
|
-
"NODE_FAIL",
|
|
20
|
-
"OUT_OF_MEMORY",
|
|
21
|
-
"PREEMPTED",
|
|
22
|
-
"SPECIAL_EXIT",
|
|
23
|
-
"TIMEOUT",
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def run_script_on_remote_slurm(
|
|
28
|
-
*,
|
|
29
|
-
script_path: str,
|
|
30
|
-
slurm_config: PixiSLURMConfig,
|
|
31
|
-
fractal_ssh: FractalSSH,
|
|
32
|
-
logger_name: str,
|
|
33
|
-
prefix: str,
|
|
34
|
-
):
|
|
35
|
-
"""
|
|
36
|
-
FIXME
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
NOTE: This is called from within a try/except, thus we can use exceptions
|
|
40
|
-
as a mechanism to propagate failure/errors.
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
logger = get_logger(logger_name=logger_name)
|
|
44
|
-
settings = Inject(get_settings)
|
|
45
|
-
|
|
46
|
-
# (1) Prepare remote submission script
|
|
47
|
-
workdir_remote = Path(script_path).parent.as_posix()
|
|
48
|
-
submission_script_remote = os.path.join(
|
|
49
|
-
workdir_remote, f"{prefix}-submit.sh"
|
|
50
|
-
)
|
|
51
|
-
stderr_remote = os.path.join(workdir_remote, f"{prefix}-err.txt")
|
|
52
|
-
stdout_remote = os.path.join(workdir_remote, f"{prefix}-out.txt")
|
|
53
|
-
success_file_remote = os.path.join(workdir_remote, f"{prefix}-success.txt")
|
|
54
|
-
script_lines = [
|
|
55
|
-
"#!/bin/bash",
|
|
56
|
-
f"#SBATCH --partition={slurm_config.partition}",
|
|
57
|
-
f"#SBATCH --cpus-per-task={slurm_config.cpus}",
|
|
58
|
-
f"#SBATCH --mem={slurm_config.mem}",
|
|
59
|
-
f"#SBATCH --time={slurm_config.time}",
|
|
60
|
-
f"#SBATCH --err={stderr_remote}",
|
|
61
|
-
f"#SBATCH --out={stdout_remote}",
|
|
62
|
-
f"#SBATCH -D {workdir_remote}",
|
|
63
|
-
"",
|
|
64
|
-
f"bash {script_path}",
|
|
65
|
-
f"touch {success_file_remote}",
|
|
66
|
-
"",
|
|
67
|
-
]
|
|
68
|
-
script_contents = "\n".join(script_lines)
|
|
69
|
-
fractal_ssh.write_remote_file(
|
|
70
|
-
path=submission_script_remote,
|
|
71
|
-
content=script_contents,
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
# (2) Submit SLURM job
|
|
75
|
-
sbatch_cmd = f"sbatch --parsable {submission_script_remote} "
|
|
76
|
-
try:
|
|
77
|
-
stdout = fractal_ssh.run_command(cmd=sbatch_cmd)
|
|
78
|
-
except Exception as e:
|
|
79
|
-
logger.error(
|
|
80
|
-
f"Submission of {submission_script_remote} failed. "
|
|
81
|
-
f"Original error: {str(e)}"
|
|
82
|
-
)
|
|
83
|
-
raise e
|
|
84
|
-
logger.debug(f"Now submit job {submission_script_remote} to SLURM.")
|
|
85
|
-
job_id = int(stdout)
|
|
86
|
-
logger.debug(f"SLURM-job submission successful ({job_id=}).")
|
|
87
|
-
|
|
88
|
-
# (3) Monitor job
|
|
89
|
-
squeue_cmd = (
|
|
90
|
-
f"squeue --noheader --format='%i %T' --states=all --jobs={job_id}"
|
|
91
|
-
)
|
|
92
|
-
while True:
|
|
93
|
-
try:
|
|
94
|
-
stdout = fractal_ssh.run_command(cmd=squeue_cmd)
|
|
95
|
-
except Exception as e:
|
|
96
|
-
# FIXME: review this logic
|
|
97
|
-
logger.info(
|
|
98
|
-
f"`squeue` command failed (original error: {e}), "
|
|
99
|
-
"consider the job as complete."
|
|
100
|
-
)
|
|
101
|
-
break
|
|
102
|
-
state = stdout.strip().split()[1]
|
|
103
|
-
logger.debug(f"Status of SLURM job {job_id}: {state}")
|
|
104
|
-
if state in STATES_FINISHED:
|
|
105
|
-
logger.debug(f"Exit retrieval loop ({state=}).")
|
|
106
|
-
break
|
|
107
|
-
time.sleep(settings.FRACTAL_SLURM_POLL_INTERVAL)
|
|
108
|
-
|
|
109
|
-
if fractal_ssh.remote_exists(path=success_file_remote):
|
|
110
|
-
logger.info(f"{success_file_remote=} exists.")
|
|
111
|
-
else:
|
|
112
|
-
raise RuntimeError(
|
|
113
|
-
"SLURM job did not complete correctly "
|
|
114
|
-
f"({success_file_remote=} missing)."
|
|
115
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/linkusergroup.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/linkuserproject.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/user_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/accounting.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/task_group.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/models/v2/workflowtask.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/__init__.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/__init__.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/accounting.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/impersonate.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/project.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/task.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/admin/v2/task_group.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/__init__.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/_aux_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/dataset.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/history.py
RENAMED
|
File without changes
|
{fractal_server-2.16.2a0 → fractal_server-2.16.3}/fractal_server/app/routes/api/v2/images.py
RENAMED
|
File without changes
|