fractal-server 2.13.1__py3-none-any.whl → 2.14.0a1__py3-none-any.whl
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/__init__.py +1 -1
- fractal_server/app/history/__init__.py +4 -0
- fractal_server/app/history/image_updates.py +142 -0
- fractal_server/app/history/status_enum.py +16 -0
- fractal_server/app/models/v2/__init__.py +5 -1
- fractal_server/app/models/v2/history.py +53 -0
- fractal_server/app/routes/api/v2/__init__.py +2 -2
- fractal_server/app/routes/api/v2/_aux_functions.py +78 -0
- fractal_server/app/routes/api/v2/dataset.py +12 -9
- fractal_server/app/routes/api/v2/history.py +247 -0
- fractal_server/app/routes/api/v2/project.py +25 -0
- fractal_server/app/routes/api/v2/workflow.py +18 -3
- fractal_server/app/routes/api/v2/workflowtask.py +22 -0
- fractal_server/app/runner/executors/base_runner.py +114 -0
- fractal_server/app/runner/{v2/_local → executors/local}/_local_config.py +3 -3
- fractal_server/app/runner/executors/local/_submit_setup.py +54 -0
- fractal_server/app/runner/executors/local/runner.py +200 -0
- fractal_server/app/runner/executors/{slurm → slurm_common}/_batching.py +1 -1
- fractal_server/app/runner/executors/{slurm → slurm_common}/_slurm_config.py +3 -3
- fractal_server/app/runner/{v2/_slurm_ssh → executors/slurm_common}/_submit_setup.py +13 -12
- fractal_server/app/runner/{v2/_slurm_common → executors/slurm_common}/get_slurm_config.py +9 -15
- fractal_server/app/runner/executors/{slurm/ssh → slurm_ssh}/_executor_wait_thread.py +1 -1
- fractal_server/app/runner/executors/{slurm/ssh → slurm_ssh}/_slurm_job.py +1 -1
- fractal_server/app/runner/executors/{slurm/ssh → slurm_ssh}/executor.py +13 -14
- fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_check_jobs_status.py +11 -9
- fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_executor_wait_thread.py +3 -3
- fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_subprocess_run_as_user.py +2 -68
- fractal_server/app/runner/executors/slurm_sudo/runner.py +632 -0
- fractal_server/app/runner/task_files.py +70 -96
- fractal_server/app/runner/v2/__init__.py +5 -19
- fractal_server/app/runner/v2/_local.py +84 -0
- fractal_server/app/runner/v2/{_slurm_ssh/__init__.py → _slurm_ssh.py} +10 -13
- fractal_server/app/runner/v2/{_slurm_sudo/__init__.py → _slurm_sudo.py} +10 -12
- fractal_server/app/runner/v2/runner.py +93 -28
- fractal_server/app/runner/v2/runner_functions.py +85 -62
- fractal_server/app/runner/v2/runner_functions_low_level.py +20 -20
- fractal_server/app/schemas/v2/dataset.py +0 -17
- fractal_server/app/schemas/v2/history.py +23 -0
- fractal_server/config.py +2 -2
- fractal_server/migrations/versions/8223fcef886c_image_status.py +63 -0
- fractal_server/migrations/versions/87cd72a537a2_add_historyitem_table.py +68 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a1.dist-info}/METADATA +1 -1
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a1.dist-info}/RECORD +53 -47
- fractal_server/app/routes/api/v2/status.py +0 -168
- fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -1281
- fractal_server/app/runner/v2/_local/__init__.py +0 -132
- fractal_server/app/runner/v2/_local/_submit_setup.py +0 -52
- fractal_server/app/runner/v2/_local/executor.py +0 -100
- fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -83
- fractal_server/app/runner/v2/handle_failed_job.py +0 -59
- /fractal_server/app/runner/executors/{slurm → local}/__init__.py +0 -0
- /fractal_server/app/runner/executors/{slurm/ssh → slurm_common}/__init__.py +0 -0
- /fractal_server/app/runner/executors/{_job_states.py → slurm_common/_job_states.py} +0 -0
- /fractal_server/app/runner/executors/{slurm → slurm_common}/remote.py +0 -0
- /fractal_server/app/runner/executors/{slurm → slurm_common}/utils_executors.py +0 -0
- /fractal_server/app/runner/executors/{slurm/sudo → slurm_ssh}/__init__.py +0 -0
- /fractal_server/app/runner/{v2/_slurm_common → executors/slurm_sudo}/__init__.py +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a1.dist-info}/LICENSE +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a1.dist-info}/WHEEL +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0a1.dist-info}/entry_points.txt +0 -0
@@ -15,22 +15,21 @@ from typing import Sequence
|
|
15
15
|
|
16
16
|
import cloudpickle
|
17
17
|
|
18
|
-
from
|
19
|
-
from
|
20
|
-
from
|
21
|
-
from
|
22
|
-
from
|
23
|
-
from
|
24
|
-
from ..
|
25
|
-
from ..utils_executors import
|
26
|
-
from ..utils_executors import
|
27
|
-
from ..utils_executors import get_slurm_script_file_path
|
18
|
+
from ...filenames import SHUTDOWN_FILENAME
|
19
|
+
from ...task_files import TaskFiles
|
20
|
+
from ...versions import get_versions
|
21
|
+
from ..slurm_common._batching import heuristics
|
22
|
+
from ..slurm_common._job_states import STATES_FINISHED
|
23
|
+
from ..slurm_common._slurm_config import SlurmConfig
|
24
|
+
from ..slurm_common.utils_executors import get_pickle_file_path
|
25
|
+
from ..slurm_common.utils_executors import get_slurm_file_path
|
26
|
+
from ..slurm_common.utils_executors import get_slurm_script_file_path
|
28
27
|
from ._executor_wait_thread import FractalSlurmSSHWaitThread
|
29
28
|
from fractal_server.app.runner.components import _COMPONENT_KEY_
|
30
29
|
from fractal_server.app.runner.compress_folder import compress_folder
|
31
30
|
from fractal_server.app.runner.exceptions import JobExecutionError
|
32
31
|
from fractal_server.app.runner.exceptions import TaskExecutionError
|
33
|
-
from fractal_server.app.runner.executors.
|
32
|
+
from fractal_server.app.runner.executors.slurm_ssh._slurm_job import SlurmJob
|
34
33
|
from fractal_server.app.runner.extract_archive import extract_archive
|
35
34
|
from fractal_server.config import get_settings
|
36
35
|
from fractal_server.logger import set_logger
|
@@ -533,9 +532,9 @@ class FractalSlurmSSHExecutor(Executor):
|
|
533
532
|
except AttributeError:
|
534
533
|
actual_component = str(component)
|
535
534
|
|
536
|
-
_task_file_paths =
|
537
|
-
|
538
|
-
|
535
|
+
_task_file_paths = TaskFiles(
|
536
|
+
root_dir_local=task_files.workflow_dir_local,
|
537
|
+
root_dir_remote=task_files.workflow_dir_remote,
|
539
538
|
task_name=task_files.task_name,
|
540
539
|
task_order=task_files.task_order,
|
541
540
|
component=actual_component,
|
@@ -1,18 +1,20 @@
|
|
1
|
-
|
1
|
+
import subprocess # nosec
|
2
2
|
|
3
|
-
from
|
4
|
-
|
3
|
+
from fractal_server.app.runner.executors.slurm_common._job_states import (
|
4
|
+
STATES_FINISHED,
|
5
|
+
)
|
6
|
+
from fractal_server.logger import set_logger
|
5
7
|
|
6
8
|
|
7
9
|
logger = set_logger(__name__)
|
8
10
|
|
9
11
|
|
10
|
-
def run_squeue(job_ids):
|
11
|
-
res = run( # nosec
|
12
|
+
def run_squeue(job_ids: list[str]) -> subprocess.CompletedProcess:
|
13
|
+
res = subprocess.run( # nosec
|
12
14
|
[
|
13
15
|
"squeue",
|
14
16
|
"--noheader",
|
15
|
-
"--format
|
17
|
+
"--format='%i %T'",
|
16
18
|
"--jobs",
|
17
19
|
",".join([str(j) for j in job_ids]),
|
18
20
|
"--states=all",
|
@@ -23,14 +25,14 @@ def run_squeue(job_ids):
|
|
23
25
|
)
|
24
26
|
if res.returncode != 0:
|
25
27
|
logger.warning(
|
26
|
-
f"squeue command with {job_ids}"
|
27
|
-
f"
|
28
|
+
f"squeue command with {job_ids} failed with:"
|
29
|
+
f"\n{res.stderr=}\n{res.stdout=}"
|
28
30
|
)
|
29
31
|
|
30
32
|
return res
|
31
33
|
|
32
34
|
|
33
|
-
def
|
35
|
+
def get_finished_jobs(job_ids: list[str]) -> set[str]:
|
34
36
|
"""
|
35
37
|
Check which ones of the given Slurm jobs already finished
|
36
38
|
|
@@ -5,9 +5,9 @@ import traceback
|
|
5
5
|
from itertools import count
|
6
6
|
from typing import Optional
|
7
7
|
|
8
|
-
from
|
9
|
-
from ._check_jobs_status import _jobs_finished
|
8
|
+
from ._check_jobs_status import get_finished_jobs
|
10
9
|
from fractal_server.app.runner.exceptions import JobExecutionError
|
10
|
+
from fractal_server.logger import set_logger
|
11
11
|
|
12
12
|
logger = set_logger(__name__)
|
13
13
|
|
@@ -115,7 +115,7 @@ class FractalSlurmSudoWaitThread(threading.Thread):
|
|
115
115
|
self.check_shutdown(i)
|
116
116
|
if i % (self.slurm_poll_interval // self.interval) == 0:
|
117
117
|
try:
|
118
|
-
finished_jobs =
|
118
|
+
finished_jobs = get_finished_jobs(self.waiting.values())
|
119
119
|
except Exception:
|
120
120
|
# Don't abandon completion checking if jobs_finished errors
|
121
121
|
traceback.print_exc()
|
@@ -19,7 +19,7 @@ import shlex
|
|
19
19
|
import subprocess # nosec
|
20
20
|
from typing import Optional
|
21
21
|
|
22
|
-
from
|
22
|
+
from fractal_server.logger import set_logger
|
23
23
|
from fractal_server.string_tools import validate_cmd
|
24
24
|
|
25
25
|
logger = set_logger(__name__)
|
@@ -65,10 +65,7 @@ def _run_command_as_user(
|
|
65
65
|
|
66
66
|
if check and not res.returncode == 0:
|
67
67
|
raise RuntimeError(
|
68
|
-
f"{cmd=}\n\n"
|
69
|
-
f"{res.returncode=}\n\n"
|
70
|
-
f"{res.stdout=}\n\n"
|
71
|
-
f"{res.stderr=}\n"
|
68
|
+
f"{cmd=}\n\n{res.returncode=}\n\n{res.stdout=}\n\n{res.stderr=}\n"
|
72
69
|
)
|
73
70
|
|
74
71
|
return res
|
@@ -93,69 +90,6 @@ def _mkdir_as_user(*, folder: str, user: str) -> None:
|
|
93
90
|
_run_command_as_user(cmd=cmd, user=user, check=True)
|
94
91
|
|
95
92
|
|
96
|
-
def _glob_as_user(
|
97
|
-
*, folder: str, user: str, startswith: Optional[str] = None
|
98
|
-
) -> list[str]:
|
99
|
-
"""
|
100
|
-
Run `ls` in a folder (as a user) and filter results
|
101
|
-
|
102
|
-
Execute `ls` on a folder (impersonating a user, if `user` is not `None`)
|
103
|
-
and select results that start with `startswith` (if not `None`).
|
104
|
-
|
105
|
-
Arguments:
|
106
|
-
folder: Absolute path to the folder
|
107
|
-
user: If not `None`, the user to be impersonated via `sudo -u`
|
108
|
-
startswith: If not `None`, this is used to filter output of `ls`.
|
109
|
-
"""
|
110
|
-
|
111
|
-
res = _run_command_as_user(cmd=f"ls {folder}", user=user, check=True)
|
112
|
-
output = res.stdout.split()
|
113
|
-
if startswith:
|
114
|
-
output = [f for f in output if f.startswith(startswith)]
|
115
|
-
return output
|
116
|
-
|
117
|
-
|
118
|
-
def _glob_as_user_strict(
|
119
|
-
*,
|
120
|
-
folder: str,
|
121
|
-
user: str,
|
122
|
-
startswith: str,
|
123
|
-
) -> list[str]:
|
124
|
-
"""
|
125
|
-
Run `ls` in a folder (as a user) and filter results
|
126
|
-
|
127
|
-
Execute `ls` on a folder (impersonating a user, if `user` is not `None`)
|
128
|
-
and select results that comply with a set of rules. They all start with
|
129
|
-
`startswith` (if not `None`), and they match one of the known filename
|
130
|
-
patterns. See details in
|
131
|
-
https://github.com/fractal-analytics-platform/fractal-server/issues/1240
|
132
|
-
|
133
|
-
|
134
|
-
Arguments:
|
135
|
-
folder: Absolute path to the folder
|
136
|
-
user: If not `None`, the user to be impersonated via `sudo -u`
|
137
|
-
startswith: If not `None`, this is used to filter output of `ls`.
|
138
|
-
"""
|
139
|
-
|
140
|
-
res = _run_command_as_user(cmd=f"ls {folder}", user=user, check=True)
|
141
|
-
output = res.stdout.split()
|
142
|
-
|
143
|
-
new_output = []
|
144
|
-
known_filenames = [
|
145
|
-
f"{startswith}{suffix}"
|
146
|
-
for suffix in [".args.json", ".metadiff.json", ".err", ".out", ".log"]
|
147
|
-
]
|
148
|
-
for filename in output:
|
149
|
-
if filename in known_filenames:
|
150
|
-
new_output.append(filename)
|
151
|
-
elif filename.startswith(f"{startswith}_out_") and filename.endswith(
|
152
|
-
".pickle"
|
153
|
-
):
|
154
|
-
new_output.append(filename)
|
155
|
-
|
156
|
-
return new_output
|
157
|
-
|
158
|
-
|
159
93
|
def _path_exists_as_user(*, path: str, user: Optional[str] = None) -> bool:
|
160
94
|
"""
|
161
95
|
Impersonate a user and check if `path` exists via `ls`
|