fractal-server 2.14.5__py3-none-any.whl → 2.14.7__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/db/__init__.py +2 -2
- fractal_server/app/models/security.py +8 -8
- fractal_server/app/models/user_settings.py +8 -10
- fractal_server/app/models/v2/accounting.py +2 -3
- fractal_server/app/models/v2/dataset.py +1 -2
- fractal_server/app/models/v2/history.py +3 -4
- fractal_server/app/models/v2/job.py +10 -11
- fractal_server/app/models/v2/project.py +1 -2
- fractal_server/app/models/v2/task.py +13 -14
- fractal_server/app/models/v2/task_group.py +15 -16
- fractal_server/app/models/v2/workflow.py +1 -2
- fractal_server/app/models/v2/workflowtask.py +6 -7
- fractal_server/app/routes/admin/v2/accounting.py +3 -4
- fractal_server/app/routes/admin/v2/job.py +13 -14
- fractal_server/app/routes/admin/v2/project.py +2 -4
- fractal_server/app/routes/admin/v2/task.py +11 -13
- fractal_server/app/routes/admin/v2/task_group.py +15 -17
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +5 -8
- fractal_server/app/routes/api/v2/__init__.py +2 -0
- fractal_server/app/routes/api/v2/_aux_functions.py +7 -9
- fractal_server/app/routes/api/v2/_aux_functions_history.py +1 -1
- fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +1 -3
- fractal_server/app/routes/api/v2/_aux_functions_tasks.py +5 -6
- fractal_server/app/routes/api/v2/dataset.py +6 -8
- fractal_server/app/routes/api/v2/history.py +5 -8
- fractal_server/app/routes/api/v2/images.py +2 -3
- fractal_server/app/routes/api/v2/job.py +5 -6
- fractal_server/app/routes/api/v2/pre_submission_checks.py +1 -3
- fractal_server/app/routes/api/v2/project.py +2 -4
- fractal_server/app/routes/api/v2/status_legacy.py +2 -4
- fractal_server/app/routes/api/v2/submit.py +3 -4
- fractal_server/app/routes/api/v2/task.py +6 -7
- fractal_server/app/routes/api/v2/task_collection.py +11 -13
- fractal_server/app/routes/api/v2/task_collection_custom.py +4 -4
- fractal_server/app/routes/api/v2/task_group.py +6 -8
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +6 -9
- fractal_server/app/routes/api/v2/task_version_update.py +270 -0
- fractal_server/app/routes/api/v2/workflow.py +5 -6
- fractal_server/app/routes/api/v2/workflow_import.py +3 -5
- fractal_server/app/routes/api/v2/workflowtask.py +2 -114
- fractal_server/app/routes/auth/current_user.py +2 -2
- fractal_server/app/routes/pagination.py +2 -3
- fractal_server/app/runner/exceptions.py +15 -16
- fractal_server/app/runner/executors/base_runner.py +3 -3
- fractal_server/app/runner/executors/call_command_wrapper.py +1 -1
- fractal_server/app/runner/executors/local/get_local_config.py +2 -3
- fractal_server/app/runner/executors/local/runner.py +1 -1
- fractal_server/app/runner/executors/slurm_common/_batching.py +2 -3
- fractal_server/app/runner/executors/slurm_common/_slurm_config.py +27 -29
- fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +32 -14
- fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +2 -3
- fractal_server/app/runner/executors/slurm_common/remote.py +2 -2
- fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/runner.py +5 -4
- fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -2
- fractal_server/app/runner/executors/slurm_sudo/runner.py +7 -8
- fractal_server/app/runner/set_start_and_last_task_index.py +2 -5
- fractal_server/app/runner/shutdown.py +5 -11
- fractal_server/app/runner/task_files.py +3 -5
- fractal_server/app/runner/v2/_local.py +3 -4
- fractal_server/app/runner/v2/_slurm_ssh.py +8 -7
- fractal_server/app/runner/v2/_slurm_sudo.py +8 -9
- fractal_server/app/runner/v2/runner.py +4 -5
- fractal_server/app/runner/v2/runner_functions.py +4 -5
- fractal_server/app/runner/v2/submit_workflow.py +12 -11
- fractal_server/app/runner/v2/task_interface.py +2 -3
- fractal_server/app/runner/versions.py +1 -2
- fractal_server/app/schemas/user.py +2 -4
- fractal_server/app/schemas/user_group.py +1 -2
- fractal_server/app/schemas/user_settings.py +19 -21
- fractal_server/app/schemas/v2/dataset.py +2 -3
- fractal_server/app/schemas/v2/dumps.py +13 -15
- fractal_server/app/schemas/v2/history.py +6 -7
- fractal_server/app/schemas/v2/job.py +17 -18
- fractal_server/app/schemas/v2/manifest.py +12 -13
- fractal_server/app/schemas/v2/status_legacy.py +2 -2
- fractal_server/app/schemas/v2/task.py +29 -30
- fractal_server/app/schemas/v2/task_collection.py +8 -9
- fractal_server/app/schemas/v2/task_group.py +22 -23
- fractal_server/app/schemas/v2/workflow.py +1 -2
- fractal_server/app/schemas/v2/workflowtask.py +27 -29
- fractal_server/app/security/__init__.py +10 -12
- fractal_server/config.py +32 -33
- fractal_server/images/models.py +2 -4
- fractal_server/images/tools.py +4 -7
- fractal_server/logger.py +3 -5
- fractal_server/ssh/_fabric.py +37 -12
- fractal_server/string_tools.py +2 -2
- fractal_server/syringe.py +1 -1
- fractal_server/tasks/v2/local/collect.py +2 -3
- fractal_server/tasks/v2/local/deactivate.py +1 -1
- fractal_server/tasks/v2/local/reactivate.py +1 -1
- fractal_server/tasks/v2/ssh/collect.py +256 -245
- fractal_server/tasks/v2/ssh/deactivate.py +210 -187
- fractal_server/tasks/v2/ssh/reactivate.py +154 -146
- fractal_server/tasks/v2/utils_background.py +2 -3
- fractal_server/types/__init__.py +1 -2
- fractal_server/types/validators/_filter_validators.py +1 -2
- fractal_server/utils.py +4 -5
- fractal_server/zip_tools.py +1 -1
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/METADATA +2 -3
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/RECORD +107 -107
- fractal_server/app/history/__init__.py +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/LICENSE +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/WHEEL +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/entry_points.txt +0 -0
@@ -2,8 +2,8 @@ import logging
|
|
2
2
|
import time
|
3
3
|
from pathlib import Path
|
4
4
|
from tempfile import TemporaryDirectory
|
5
|
-
from typing import Optional
|
6
5
|
|
6
|
+
from ....ssh._fabric import SingleUseFractalSSH
|
7
7
|
from ..utils_background import _prepare_tasks_metadata
|
8
8
|
from ..utils_background import fail_and_cleanup
|
9
9
|
from ..utils_database import create_db_tasks_and_update_task_group_sync
|
@@ -16,7 +16,7 @@ from fractal_server.app.schemas.v2 import WheelFile
|
|
16
16
|
from fractal_server.app.schemas.v2.manifest import ManifestV2
|
17
17
|
from fractal_server.logger import reset_logger_handlers
|
18
18
|
from fractal_server.logger import set_logger
|
19
|
-
from fractal_server.ssh._fabric import
|
19
|
+
from fractal_server.ssh._fabric import SSHConfig
|
20
20
|
from fractal_server.tasks.v2.ssh._utils import _customize_and_run_template
|
21
21
|
from fractal_server.tasks.v2.utils_background import add_commit_refresh
|
22
22
|
from fractal_server.tasks.v2.utils_background import get_current_log
|
@@ -36,9 +36,9 @@ def collect_ssh(
|
|
36
36
|
*,
|
37
37
|
task_group_id: int,
|
38
38
|
task_group_activity_id: int,
|
39
|
-
|
39
|
+
ssh_config: SSHConfig,
|
40
40
|
tasks_base_dir: str,
|
41
|
-
wheel_file:
|
41
|
+
wheel_file: WheelFile | None = None,
|
42
42
|
) -> None:
|
43
43
|
"""
|
44
44
|
Collect a task package over SSH
|
@@ -54,7 +54,7 @@ def collect_ssh(
|
|
54
54
|
Arguments:
|
55
55
|
task_group_id:
|
56
56
|
task_group_activity_id:
|
57
|
-
|
57
|
+
ssh_config:
|
58
58
|
tasks_base_dir:
|
59
59
|
Only used as a `safe_root` in `remove_dir`, and typically set to
|
60
60
|
`user_settings.ssh_tasks_dir`.
|
@@ -65,256 +65,267 @@ def collect_ssh(
|
|
65
65
|
|
66
66
|
# Work within a temporary folder, where also logs will be placed
|
67
67
|
with TemporaryDirectory() as tmpdir:
|
68
|
-
LOGGER_NAME = "task_collection_ssh"
|
69
68
|
log_file_path = Path(tmpdir) / "log"
|
70
69
|
logger = set_logger(
|
71
70
|
logger_name=LOGGER_NAME,
|
72
71
|
log_file_path=log_file_path,
|
73
72
|
)
|
73
|
+
with SingleUseFractalSSH(
|
74
|
+
ssh_config=ssh_config,
|
75
|
+
logger_name=LOGGER_NAME,
|
76
|
+
) as fractal_ssh:
|
77
|
+
|
78
|
+
with next(get_sync_db()) as db:
|
79
|
+
# Get main objects from db
|
80
|
+
activity = db.get(TaskGroupActivityV2, task_group_activity_id)
|
81
|
+
task_group = db.get(TaskGroupV2, task_group_id)
|
82
|
+
if activity is None or task_group is None:
|
83
|
+
# Use `logging` directly
|
84
|
+
logging.error(
|
85
|
+
"Cannot find database rows with "
|
86
|
+
f"{task_group_id=} and {task_group_activity_id=}:\n"
|
87
|
+
f"{task_group=}\n{activity=}. Exit."
|
88
|
+
)
|
89
|
+
return
|
90
|
+
|
91
|
+
# Log some info
|
92
|
+
logger.info("START")
|
93
|
+
for key, value in task_group.model_dump().items():
|
94
|
+
logger.debug(f"task_group.{key}: {value}")
|
95
|
+
|
96
|
+
# Check that SSH connection works
|
97
|
+
try:
|
98
|
+
fractal_ssh.check_connection()
|
99
|
+
except Exception as e:
|
100
|
+
logger.error("Cannot establish SSH connection.")
|
101
|
+
fail_and_cleanup(
|
102
|
+
task_group=task_group,
|
103
|
+
task_group_activity=activity,
|
104
|
+
logger_name=LOGGER_NAME,
|
105
|
+
log_file_path=log_file_path,
|
106
|
+
exception=e,
|
107
|
+
db=db,
|
108
|
+
)
|
109
|
+
return
|
110
|
+
|
111
|
+
# Check that the (remote) task_group path does not exist
|
112
|
+
if fractal_ssh.remote_exists(task_group.path):
|
113
|
+
error_msg = f"{task_group.path} already exists."
|
114
|
+
logger.error(error_msg)
|
115
|
+
fail_and_cleanup(
|
116
|
+
task_group=task_group,
|
117
|
+
task_group_activity=activity,
|
118
|
+
logger_name=LOGGER_NAME,
|
119
|
+
log_file_path=log_file_path,
|
120
|
+
exception=FileExistsError(error_msg),
|
121
|
+
db=db,
|
122
|
+
)
|
123
|
+
return
|
124
|
+
|
125
|
+
try:
|
126
|
+
# Create remote `task_group.path` and `script_dir_remote`
|
127
|
+
# folders (note that because of `parents=True` we are in
|
128
|
+
# the `no error if existing, make parent directories as
|
129
|
+
# needed` scenario for `mkdir`)
|
130
|
+
script_dir_remote = (
|
131
|
+
Path(task_group.path) / SCRIPTS_SUBFOLDER
|
132
|
+
).as_posix()
|
133
|
+
fractal_ssh.mkdir(folder=task_group.path, parents=True)
|
134
|
+
fractal_ssh.mkdir(folder=script_dir_remote, parents=True)
|
135
|
+
|
136
|
+
# Write wheel file locally and send it to remote path,
|
137
|
+
# and set task_group.wheel_path
|
138
|
+
if wheel_file is not None:
|
139
|
+
wheel_filename = wheel_file.filename
|
140
|
+
wheel_path = (
|
141
|
+
Path(task_group.path) / wheel_filename
|
142
|
+
).as_posix()
|
143
|
+
tmp_wheel_path = (
|
144
|
+
Path(tmpdir) / wheel_filename
|
145
|
+
).as_posix()
|
146
|
+
logger.info(
|
147
|
+
f"Write wheel-file contents into {tmp_wheel_path}"
|
148
|
+
)
|
149
|
+
with open(tmp_wheel_path, "wb") as f:
|
150
|
+
f.write(wheel_file.contents)
|
151
|
+
fractal_ssh.send_file(
|
152
|
+
local=tmp_wheel_path,
|
153
|
+
remote=wheel_path,
|
154
|
+
)
|
155
|
+
task_group.wheel_path = wheel_path
|
156
|
+
task_group = add_commit_refresh(obj=task_group, db=db)
|
157
|
+
|
158
|
+
replacements = get_collection_replacements(
|
159
|
+
task_group=task_group,
|
160
|
+
python_bin=get_python_interpreter_v2(
|
161
|
+
python_version=task_group.python_version
|
162
|
+
),
|
163
|
+
)
|
164
|
+
|
165
|
+
# Prepare common arguments for _customize_and_run_template
|
166
|
+
common_args = dict(
|
167
|
+
replacements=replacements,
|
168
|
+
script_dir_local=(
|
169
|
+
Path(tmpdir) / SCRIPTS_SUBFOLDER
|
170
|
+
).as_posix(),
|
171
|
+
script_dir_remote=script_dir_remote,
|
172
|
+
prefix=(
|
173
|
+
f"{int(time.time())}_"
|
174
|
+
f"{TaskGroupActivityActionV2.COLLECT}"
|
175
|
+
),
|
176
|
+
fractal_ssh=fractal_ssh,
|
177
|
+
logger_name=LOGGER_NAME,
|
178
|
+
)
|
179
|
+
|
180
|
+
logger.info("installing - START")
|
181
|
+
|
182
|
+
# Set status to ONGOING and refresh logs
|
183
|
+
activity.status = TaskGroupActivityStatusV2.ONGOING
|
184
|
+
activity.log = get_current_log(log_file_path)
|
185
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
186
|
+
|
187
|
+
# Run script 1
|
188
|
+
stdout = _customize_and_run_template(
|
189
|
+
template_filename="1_create_venv.sh",
|
190
|
+
**common_args,
|
191
|
+
)
|
192
|
+
activity.log = get_current_log(log_file_path)
|
193
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
194
|
+
# Run script 2
|
195
|
+
stdout = _customize_and_run_template(
|
196
|
+
template_filename="2_pip_install.sh",
|
197
|
+
**common_args,
|
198
|
+
)
|
199
|
+
activity.log = get_current_log(log_file_path)
|
200
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
74
201
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
script_dir_remote = (
|
128
|
-
Path(task_group.path) / SCRIPTS_SUBFOLDER
|
129
|
-
).as_posix()
|
130
|
-
fractal_ssh.mkdir(folder=task_group.path, parents=True)
|
131
|
-
fractal_ssh.mkdir(folder=script_dir_remote, parents=True)
|
132
|
-
|
133
|
-
# Write wheel file locally and send it to remote path,
|
134
|
-
# and set task_group.wheel_path
|
135
|
-
if wheel_file is not None:
|
136
|
-
wheel_filename = wheel_file.filename
|
137
|
-
wheel_path = (
|
138
|
-
Path(task_group.path) / wheel_filename
|
202
|
+
# Run script 3
|
203
|
+
pip_freeze_stdout = _customize_and_run_template(
|
204
|
+
template_filename="3_pip_freeze.sh",
|
205
|
+
**common_args,
|
206
|
+
)
|
207
|
+
activity.log = get_current_log(log_file_path)
|
208
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
209
|
+
|
210
|
+
# Run script 4
|
211
|
+
stdout = _customize_and_run_template(
|
212
|
+
template_filename="4_pip_show.sh",
|
213
|
+
**common_args,
|
214
|
+
)
|
215
|
+
activity.log = get_current_log(log_file_path)
|
216
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
217
|
+
|
218
|
+
# Run script 5
|
219
|
+
venv_info = _customize_and_run_template(
|
220
|
+
template_filename="5_get_venv_size_and_file_number.sh",
|
221
|
+
**common_args,
|
222
|
+
)
|
223
|
+
venv_size, venv_file_number = venv_info.split()
|
224
|
+
activity.log = get_current_log(log_file_path)
|
225
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
226
|
+
|
227
|
+
pkg_attrs = parse_script_pip_show_stdout(stdout)
|
228
|
+
|
229
|
+
for key, value in pkg_attrs.items():
|
230
|
+
logger.debug(f"parsed from pip-show: {key}={value}")
|
231
|
+
# Check package_name match between pip show and task-group
|
232
|
+
package_name_pip_show = pkg_attrs.get("package_name")
|
233
|
+
package_name_task_group = task_group.pkg_name
|
234
|
+
compare_package_names(
|
235
|
+
pkg_name_pip_show=package_name_pip_show,
|
236
|
+
pkg_name_task_group=package_name_task_group,
|
237
|
+
logger_name=LOGGER_NAME,
|
238
|
+
)
|
239
|
+
# Extract/drop parsed attributes
|
240
|
+
package_name = package_name_task_group
|
241
|
+
python_bin = pkg_attrs.pop("python_bin")
|
242
|
+
package_root_parent_remote = pkg_attrs.pop(
|
243
|
+
"package_root_parent"
|
244
|
+
)
|
245
|
+
manifest_path_remote = pkg_attrs.pop("manifest_path")
|
246
|
+
|
247
|
+
# TODO SSH: Use more robust logic to determine
|
248
|
+
# `package_root`. Examples: use `importlib.util.find_spec`
|
249
|
+
# or parse the output of `pip show --files {package_name}`.
|
250
|
+
package_name_underscore = package_name.replace("-", "_")
|
251
|
+
package_root_remote = (
|
252
|
+
Path(package_root_parent_remote)
|
253
|
+
/ package_name_underscore
|
139
254
|
).as_posix()
|
140
|
-
|
255
|
+
|
256
|
+
# Read and validate remote manifest file
|
257
|
+
pkg_manifest_dict = fractal_ssh.read_remote_json_file(
|
258
|
+
manifest_path_remote
|
259
|
+
)
|
260
|
+
logger.info(f"Loaded {manifest_path_remote=}")
|
261
|
+
pkg_manifest = ManifestV2(**pkg_manifest_dict)
|
262
|
+
logger.info("Manifest is a valid ManifestV2")
|
263
|
+
|
264
|
+
logger.info("_prepare_tasks_metadata - start")
|
265
|
+
task_list = _prepare_tasks_metadata(
|
266
|
+
package_manifest=pkg_manifest,
|
267
|
+
package_version=task_group.version,
|
268
|
+
package_root=Path(package_root_remote),
|
269
|
+
python_bin=Path(python_bin),
|
270
|
+
)
|
271
|
+
logger.info("_prepare_tasks_metadata - end")
|
272
|
+
|
141
273
|
logger.info(
|
142
|
-
|
274
|
+
"create_db_tasks_and_update_task_group - " "start"
|
143
275
|
)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
remote=wheel_path,
|
276
|
+
create_db_tasks_and_update_task_group_sync(
|
277
|
+
task_list=task_list,
|
278
|
+
task_group_id=task_group.id,
|
279
|
+
db=db,
|
149
280
|
)
|
150
|
-
|
151
|
-
task_group = add_commit_refresh(obj=task_group, db=db)
|
281
|
+
logger.info("create_db_tasks_and_update_task_group - end")
|
152
282
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
),
|
158
|
-
)
|
159
|
-
|
160
|
-
# Prepare common arguments for `_customize_and_run_template``
|
161
|
-
common_args = dict(
|
162
|
-
replacements=replacements,
|
163
|
-
script_dir_local=(
|
164
|
-
Path(tmpdir) / SCRIPTS_SUBFOLDER
|
165
|
-
).as_posix(),
|
166
|
-
script_dir_remote=script_dir_remote,
|
167
|
-
prefix=(
|
168
|
-
f"{int(time.time())}_"
|
169
|
-
f"{TaskGroupActivityActionV2.COLLECT.value}"
|
170
|
-
),
|
171
|
-
fractal_ssh=fractal_ssh,
|
172
|
-
logger_name=LOGGER_NAME,
|
173
|
-
)
|
174
|
-
|
175
|
-
logger.info("installing - START")
|
176
|
-
|
177
|
-
# Set status to ONGOING and refresh logs
|
178
|
-
activity.status = TaskGroupActivityStatusV2.ONGOING
|
179
|
-
activity.log = get_current_log(log_file_path)
|
180
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
181
|
-
|
182
|
-
# Run script 1
|
183
|
-
stdout = _customize_and_run_template(
|
184
|
-
template_filename="1_create_venv.sh",
|
185
|
-
**common_args,
|
186
|
-
)
|
187
|
-
activity.log = get_current_log(log_file_path)
|
188
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
189
|
-
# Run script 2
|
190
|
-
stdout = _customize_and_run_template(
|
191
|
-
template_filename="2_pip_install.sh",
|
192
|
-
**common_args,
|
193
|
-
)
|
194
|
-
activity.log = get_current_log(log_file_path)
|
195
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
196
|
-
|
197
|
-
# Run script 3
|
198
|
-
pip_freeze_stdout = _customize_and_run_template(
|
199
|
-
template_filename="3_pip_freeze.sh",
|
200
|
-
**common_args,
|
201
|
-
)
|
202
|
-
activity.log = get_current_log(log_file_path)
|
203
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
204
|
-
|
205
|
-
# Run script 4
|
206
|
-
stdout = _customize_and_run_template(
|
207
|
-
template_filename="4_pip_show.sh",
|
208
|
-
**common_args,
|
209
|
-
)
|
210
|
-
activity.log = get_current_log(log_file_path)
|
211
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
212
|
-
|
213
|
-
# Run script 5
|
214
|
-
venv_info = _customize_and_run_template(
|
215
|
-
template_filename="5_get_venv_size_and_file_number.sh",
|
216
|
-
**common_args,
|
217
|
-
)
|
218
|
-
venv_size, venv_file_number = venv_info.split()
|
219
|
-
activity.log = get_current_log(log_file_path)
|
220
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
221
|
-
|
222
|
-
pkg_attrs = parse_script_pip_show_stdout(stdout)
|
223
|
-
|
224
|
-
for key, value in pkg_attrs.items():
|
225
|
-
logger.debug(f"parsed from pip-show: {key}={value}")
|
226
|
-
# Check package_name match between pip show and task-group
|
227
|
-
package_name_pip_show = pkg_attrs.get("package_name")
|
228
|
-
package_name_task_group = task_group.pkg_name
|
229
|
-
compare_package_names(
|
230
|
-
pkg_name_pip_show=package_name_pip_show,
|
231
|
-
pkg_name_task_group=package_name_task_group,
|
232
|
-
logger_name=LOGGER_NAME,
|
233
|
-
)
|
234
|
-
# Extract/drop parsed attributes
|
235
|
-
package_name = package_name_task_group
|
236
|
-
python_bin = pkg_attrs.pop("python_bin")
|
237
|
-
package_root_parent_remote = pkg_attrs.pop(
|
238
|
-
"package_root_parent"
|
239
|
-
)
|
240
|
-
manifest_path_remote = pkg_attrs.pop("manifest_path")
|
241
|
-
|
242
|
-
# TODO SSH: Use more robust logic to determine `package_root`.
|
243
|
-
# Examples: use `importlib.util.find_spec`, or parse the output
|
244
|
-
# of `pip show --files {package_name}`.
|
245
|
-
package_name_underscore = package_name.replace("-", "_")
|
246
|
-
package_root_remote = (
|
247
|
-
Path(package_root_parent_remote) / package_name_underscore
|
248
|
-
).as_posix()
|
249
|
-
|
250
|
-
# Read and validate remote manifest file
|
251
|
-
pkg_manifest_dict = fractal_ssh.read_remote_json_file(
|
252
|
-
manifest_path_remote
|
253
|
-
)
|
254
|
-
logger.info(f"Loaded {manifest_path_remote=}")
|
255
|
-
pkg_manifest = ManifestV2(**pkg_manifest_dict)
|
256
|
-
logger.info("Manifest is a valid ManifestV2")
|
257
|
-
|
258
|
-
logger.info("_prepare_tasks_metadata - start")
|
259
|
-
task_list = _prepare_tasks_metadata(
|
260
|
-
package_manifest=pkg_manifest,
|
261
|
-
package_version=task_group.version,
|
262
|
-
package_root=Path(package_root_remote),
|
263
|
-
python_bin=Path(python_bin),
|
264
|
-
)
|
265
|
-
logger.info("_prepare_tasks_metadata - end")
|
266
|
-
|
267
|
-
logger.info("create_db_tasks_and_update_task_group - " "start")
|
268
|
-
create_db_tasks_and_update_task_group_sync(
|
269
|
-
task_list=task_list,
|
270
|
-
task_group_id=task_group.id,
|
271
|
-
db=db,
|
272
|
-
)
|
273
|
-
logger.info("create_db_tasks_and_update_task_group - end")
|
274
|
-
|
275
|
-
# Update task_group data
|
276
|
-
logger.info(
|
277
|
-
"Add pip_freeze, venv_size and venv_file_number "
|
278
|
-
"to TaskGroupV2 - start"
|
279
|
-
)
|
280
|
-
task_group.pip_freeze = pip_freeze_stdout
|
281
|
-
task_group.venv_size_in_kB = int(venv_size)
|
282
|
-
task_group.venv_file_number = int(venv_file_number)
|
283
|
-
task_group = add_commit_refresh(obj=task_group, db=db)
|
284
|
-
logger.info(
|
285
|
-
"Add pip_freeze, venv_size and venv_file_number "
|
286
|
-
"to TaskGroupV2 - end"
|
287
|
-
)
|
288
|
-
|
289
|
-
# Finalize (write metadata to DB)
|
290
|
-
logger.info("finalising - START")
|
291
|
-
activity.status = TaskGroupActivityStatusV2.OK
|
292
|
-
activity.timestamp_ended = get_timestamp()
|
293
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
294
|
-
logger.info("finalising - END")
|
295
|
-
logger.info("END")
|
296
|
-
reset_logger_handlers(logger)
|
297
|
-
|
298
|
-
except Exception as collection_e:
|
299
|
-
# Delete corrupted package dir
|
300
|
-
try:
|
301
|
-
logger.info(f"Now delete remote folder {task_group.path}")
|
302
|
-
fractal_ssh.remove_folder(
|
303
|
-
folder=task_group.path,
|
304
|
-
safe_root=tasks_base_dir,
|
283
|
+
# Update task_group data
|
284
|
+
logger.info(
|
285
|
+
"Add pip_freeze, venv_size and venv_file_number "
|
286
|
+
"to TaskGroupV2 - start"
|
305
287
|
)
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
288
|
+
task_group.pip_freeze = pip_freeze_stdout
|
289
|
+
task_group.venv_size_in_kB = int(venv_size)
|
290
|
+
task_group.venv_file_number = int(venv_file_number)
|
291
|
+
task_group = add_commit_refresh(obj=task_group, db=db)
|
292
|
+
logger.info(
|
293
|
+
"Add pip_freeze, venv_size and venv_file_number "
|
294
|
+
"to TaskGroupV2 - end"
|
295
|
+
)
|
296
|
+
|
297
|
+
# Finalize (write metadata to DB)
|
298
|
+
logger.info("finalising - START")
|
299
|
+
activity.status = TaskGroupActivityStatusV2.OK
|
300
|
+
activity.timestamp_ended = get_timestamp()
|
301
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
302
|
+
logger.info("finalising - END")
|
303
|
+
logger.info("END")
|
304
|
+
reset_logger_handlers(logger)
|
305
|
+
|
306
|
+
except Exception as collection_e:
|
307
|
+
# Delete corrupted package dir
|
308
|
+
try:
|
309
|
+
logger.info(
|
310
|
+
f"Now delete remote folder {task_group.path}"
|
311
|
+
)
|
312
|
+
fractal_ssh.remove_folder(
|
313
|
+
folder=task_group.path,
|
314
|
+
safe_root=tasks_base_dir,
|
315
|
+
)
|
316
|
+
logger.info(
|
317
|
+
f"Deleted remoted folder {task_group.path}"
|
318
|
+
)
|
319
|
+
except Exception as e_rm:
|
320
|
+
logger.error(
|
321
|
+
"Removing folder failed. "
|
322
|
+
f"Original error:\n{str(e_rm)}"
|
323
|
+
)
|
324
|
+
fail_and_cleanup(
|
325
|
+
task_group=task_group,
|
326
|
+
task_group_activity=activity,
|
327
|
+
log_file_path=log_file_path,
|
328
|
+
logger_name=LOGGER_NAME,
|
329
|
+
exception=collection_e,
|
330
|
+
db=db,
|
311
331
|
)
|
312
|
-
fail_and_cleanup(
|
313
|
-
task_group=task_group,
|
314
|
-
task_group_activity=activity,
|
315
|
-
log_file_path=log_file_path,
|
316
|
-
logger_name=LOGGER_NAME,
|
317
|
-
exception=collection_e,
|
318
|
-
db=db,
|
319
|
-
)
|
320
|
-
return
|