fractal-server 2.14.15__py3-none-any.whl → 2.15.0__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.
Files changed (61) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/app/models/security.py +2 -2
  3. fractal_server/app/models/user_settings.py +2 -2
  4. fractal_server/app/models/v2/dataset.py +3 -3
  5. fractal_server/app/models/v2/history.py +2 -0
  6. fractal_server/app/models/v2/job.py +6 -6
  7. fractal_server/app/models/v2/task.py +12 -8
  8. fractal_server/app/models/v2/task_group.py +19 -7
  9. fractal_server/app/models/v2/workflowtask.py +6 -6
  10. fractal_server/app/routes/admin/v2/task_group_lifecycle.py +2 -5
  11. fractal_server/app/routes/api/v2/__init__.py +6 -0
  12. fractal_server/app/routes/api/v2/_aux_functions_tasks.py +22 -0
  13. fractal_server/app/routes/api/v2/history.py +2 -2
  14. fractal_server/app/routes/api/v2/pre_submission_checks.py +3 -3
  15. fractal_server/app/routes/api/v2/task_collection.py +8 -18
  16. fractal_server/app/routes/api/v2/task_collection_custom.py +2 -2
  17. fractal_server/app/routes/api/v2/task_collection_pixi.py +219 -0
  18. fractal_server/app/routes/api/v2/task_group.py +3 -0
  19. fractal_server/app/routes/api/v2/task_group_lifecycle.py +26 -10
  20. fractal_server/app/runner/executors/slurm_common/_slurm_config.py +10 -0
  21. fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +39 -14
  22. fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +8 -1
  23. fractal_server/app/runner/executors/slurm_ssh/runner.py +3 -1
  24. fractal_server/app/runner/v2/runner.py +2 -2
  25. fractal_server/app/schemas/v2/__init__.py +1 -1
  26. fractal_server/app/schemas/v2/dumps.py +1 -1
  27. fractal_server/app/schemas/v2/task_collection.py +1 -1
  28. fractal_server/app/schemas/v2/task_group.py +7 -5
  29. fractal_server/config.py +70 -0
  30. fractal_server/images/status_tools.py +80 -75
  31. fractal_server/migrations/versions/791ce783d3d8_add_indices.py +41 -0
  32. fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +53 -0
  33. fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +340 -0
  34. fractal_server/ssh/_fabric.py +29 -0
  35. fractal_server/tasks/v2/local/__init__.py +3 -0
  36. fractal_server/tasks/v2/local/_utils.py +4 -3
  37. fractal_server/tasks/v2/local/collect.py +26 -30
  38. fractal_server/tasks/v2/local/collect_pixi.py +252 -0
  39. fractal_server/tasks/v2/local/deactivate.py +39 -46
  40. fractal_server/tasks/v2/local/deactivate_pixi.py +98 -0
  41. fractal_server/tasks/v2/local/reactivate.py +12 -23
  42. fractal_server/tasks/v2/local/reactivate_pixi.py +184 -0
  43. fractal_server/tasks/v2/ssh/__init__.py +3 -0
  44. fractal_server/tasks/v2/ssh/_utils.py +50 -9
  45. fractal_server/tasks/v2/ssh/collect.py +46 -56
  46. fractal_server/tasks/v2/ssh/collect_pixi.py +315 -0
  47. fractal_server/tasks/v2/ssh/deactivate.py +54 -67
  48. fractal_server/tasks/v2/ssh/deactivate_pixi.py +122 -0
  49. fractal_server/tasks/v2/ssh/reactivate.py +25 -38
  50. fractal_server/tasks/v2/ssh/reactivate_pixi.py +233 -0
  51. fractal_server/tasks/v2/templates/pixi_1_extract.sh +40 -0
  52. fractal_server/tasks/v2/templates/pixi_2_install.sh +52 -0
  53. fractal_server/tasks/v2/templates/pixi_3_post_install.sh +76 -0
  54. fractal_server/tasks/v2/utils_background.py +50 -8
  55. fractal_server/tasks/v2/utils_pixi.py +38 -0
  56. fractal_server/tasks/v2/utils_templates.py +14 -1
  57. {fractal_server-2.14.15.dist-info → fractal_server-2.15.0.dist-info}/METADATA +4 -4
  58. {fractal_server-2.14.15.dist-info → fractal_server-2.15.0.dist-info}/RECORD +61 -47
  59. {fractal_server-2.14.15.dist-info → fractal_server-2.15.0.dist-info}/LICENSE +0 -0
  60. {fractal_server-2.14.15.dist-info → fractal_server-2.15.0.dist-info}/WHEEL +0 -0
  61. {fractal_server-2.14.15.dist-info → fractal_server-2.15.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,184 @@
1
+ import shutil
2
+ import time
3
+ from pathlib import Path
4
+ from tempfile import TemporaryDirectory
5
+
6
+ from ..utils_background import add_commit_refresh
7
+ from ..utils_background import fail_and_cleanup
8
+ from ..utils_background import get_activity_and_task_group
9
+ from ..utils_pixi import SOURCE_DIR_NAME
10
+ from fractal_server.app.db import get_sync_db
11
+ from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
12
+ from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
13
+ from fractal_server.config import get_settings
14
+ from fractal_server.logger import reset_logger_handlers
15
+ from fractal_server.logger import set_logger
16
+ from fractal_server.syringe import Inject
17
+ from fractal_server.tasks.utils import get_log_path
18
+ from fractal_server.tasks.v2.local._utils import _customize_and_run_template
19
+ from fractal_server.tasks.v2.utils_background import get_current_log
20
+ from fractal_server.tasks.v2.utils_templates import SCRIPTS_SUBFOLDER
21
+ from fractal_server.utils import execute_command_sync
22
+ from fractal_server.utils import get_timestamp
23
+
24
+
25
+ def reactivate_local_pixi(
26
+ *,
27
+ task_group_activity_id: int,
28
+ task_group_id: int,
29
+ ) -> None:
30
+ """
31
+ Reactivate a task group venv.
32
+
33
+ This function is run as a background task, therefore exceptions must be
34
+ handled.
35
+
36
+ Arguments:
37
+ task_group_id:
38
+ task_group_activity_id:
39
+ """
40
+
41
+ LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
42
+
43
+ with TemporaryDirectory() as tmpdir:
44
+ log_file_path = get_log_path(Path(tmpdir))
45
+ logger = set_logger(
46
+ logger_name=LOGGER_NAME,
47
+ log_file_path=log_file_path,
48
+ )
49
+ logger.debug("START")
50
+ with next(get_sync_db()) as db:
51
+ db_objects_ok, task_group, activity = get_activity_and_task_group(
52
+ task_group_activity_id=task_group_activity_id,
53
+ task_group_id=task_group_id,
54
+ db=db,
55
+ logger_name=LOGGER_NAME,
56
+ )
57
+ if not db_objects_ok:
58
+ return
59
+
60
+ source_dir = Path(task_group.path, SOURCE_DIR_NAME).as_posix()
61
+ if Path(source_dir).exists():
62
+ error_msg = f"{source_dir} already exists."
63
+ logger.error(error_msg)
64
+ fail_and_cleanup(
65
+ task_group=task_group,
66
+ task_group_activity=activity,
67
+ logger_name=LOGGER_NAME,
68
+ log_file_path=log_file_path,
69
+ exception=FileExistsError(error_msg),
70
+ db=db,
71
+ )
72
+ return
73
+
74
+ try:
75
+ activity.status = TaskGroupActivityStatusV2.ONGOING
76
+ activity = add_commit_refresh(obj=activity, db=db)
77
+
78
+ settings = Inject(get_settings)
79
+ common_args = dict(
80
+ replacements={
81
+ (
82
+ "__PIXI_HOME__",
83
+ settings.pixi.versions[task_group.pixi_version],
84
+ ),
85
+ ("__PACKAGE_DIR__", task_group.path),
86
+ ("__TAR_GZ_PATH__", task_group.archive_path),
87
+ (
88
+ "__IMPORT_PACKAGE_NAME__",
89
+ task_group.pkg_name.replace("-", "_"),
90
+ ),
91
+ ("__SOURCE_DIR_NAME__", SOURCE_DIR_NAME),
92
+ ("__FROZEN_OPTION__", "--frozen"),
93
+ (
94
+ "__TOKIO_WORKER_THREADS__",
95
+ str(settings.pixi.TOKIO_WORKER_THREADS),
96
+ ),
97
+ (
98
+ "__PIXI_CONCURRENT_SOLVES__",
99
+ str(settings.pixi.PIXI_CONCURRENT_SOLVES),
100
+ ),
101
+ (
102
+ "__PIXI_CONCURRENT_DOWNLOADS__",
103
+ str(settings.pixi.PIXI_CONCURRENT_DOWNLOADS),
104
+ ),
105
+ },
106
+ script_dir=Path(
107
+ task_group.path, SCRIPTS_SUBFOLDER
108
+ ).as_posix(),
109
+ prefix=(
110
+ f"{int(time.time())}_"
111
+ f"{TaskGroupActivityActionV2.REACTIVATE}"
112
+ ),
113
+ logger_name=LOGGER_NAME,
114
+ )
115
+
116
+ # Run script 1 - extract tar.gz into `source_dir`
117
+ _customize_and_run_template(
118
+ template_filename="pixi_1_extract.sh",
119
+ **common_args,
120
+ )
121
+ activity.log = get_current_log(log_file_path)
122
+ activity = add_commit_refresh(obj=activity, db=db)
123
+
124
+ # Write pixi.lock into `source_dir`
125
+ logger.debug(f"start - writing {source_dir}/pixi.lock")
126
+ with Path(source_dir, "pixi.lock").open("w") as f:
127
+ f.write(task_group.env_info)
128
+ logger.debug(f"end - writing {source_dir}/pixi.lock")
129
+
130
+ # Run script 2 - run pixi-install command
131
+ _customize_and_run_template(
132
+ template_filename="pixi_2_install.sh",
133
+ **common_args,
134
+ )
135
+ activity.log = get_current_log(log_file_path)
136
+ activity = add_commit_refresh(obj=activity, db=db)
137
+
138
+ # Run script 3 - post-install
139
+ _customize_and_run_template(
140
+ template_filename="pixi_3_post_install.sh",
141
+ **common_args,
142
+ )
143
+ activity.log = get_current_log(log_file_path)
144
+ activity = add_commit_refresh(obj=activity, db=db)
145
+
146
+ # Make task folder 755
147
+ source_dir = Path(task_group.path, SOURCE_DIR_NAME).as_posix()
148
+ command = f"chmod 755 {source_dir} -R"
149
+ execute_command_sync(
150
+ command=command,
151
+ logger_name=LOGGER_NAME,
152
+ )
153
+
154
+ activity.log = get_current_log(log_file_path)
155
+ activity.status = TaskGroupActivityStatusV2.OK
156
+ activity.timestamp_ended = get_timestamp()
157
+ activity = add_commit_refresh(obj=activity, db=db)
158
+ task_group.active = True
159
+ task_group = add_commit_refresh(obj=task_group, db=db)
160
+ logger.debug("END")
161
+
162
+ reset_logger_handlers(logger)
163
+
164
+ except Exception as reactivate_e:
165
+ # Delete corrupted source_dir
166
+ try:
167
+ logger.info(f"Now delete folder {source_dir}")
168
+ shutil.rmtree(source_dir)
169
+ logger.info(f"Deleted folder {source_dir}")
170
+ except Exception as rm_e:
171
+ logger.error(
172
+ "Removing folder failed. "
173
+ f"Original error: {str(rm_e)}"
174
+ )
175
+
176
+ fail_and_cleanup(
177
+ task_group=task_group,
178
+ task_group_activity=activity,
179
+ logger_name=LOGGER_NAME,
180
+ log_file_path=log_file_path,
181
+ exception=reactivate_e,
182
+ db=db,
183
+ )
184
+ return
@@ -1,3 +1,6 @@
1
1
  from .collect import collect_ssh # noqa
2
+ from .collect_pixi import collect_ssh_pixi # noqa
2
3
  from .deactivate import deactivate_ssh # noqa
4
+ from .deactivate_pixi import deactivate_ssh_pixi # noqa
3
5
  from .reactivate import reactivate_ssh # noqa
6
+ from .reactivate_pixi import reactivate_ssh_pixi # noqa
@@ -1,6 +1,10 @@
1
1
  import os
2
2
  from pathlib import Path
3
3
 
4
+ from sqlalchemy.ext.asyncio import AsyncSession
5
+
6
+ from ..utils_background import fail_and_cleanup
7
+ from fractal_server.app.models.v2 import TaskGroupActivityV2
4
8
  from fractal_server.app.models.v2 import TaskGroupV2
5
9
  from fractal_server.logger import get_logger
6
10
  from fractal_server.ssh._fabric import FractalSSH
@@ -10,7 +14,7 @@ from fractal_server.tasks.v2.utils_templates import customize_template
10
14
  def _customize_and_run_template(
11
15
  *,
12
16
  template_filename: str,
13
- replacements: list[tuple[str, str]],
17
+ replacements: set[tuple[str, str]],
14
18
  script_dir_local: str,
15
19
  prefix: str,
16
20
  fractal_ssh: FractalSSH,
@@ -66,22 +70,59 @@ def _customize_and_run_template(
66
70
 
67
71
 
68
72
  def _copy_wheel_file_ssh(
69
- *, task_group: TaskGroupV2, fractal_ssh: FractalSSH, logger_name: str
73
+ *,
74
+ task_group: TaskGroupV2,
75
+ fractal_ssh: FractalSSH,
76
+ logger_name: str,
70
77
  ) -> str:
71
78
  """
72
- Handle the situation where `task_group.wheel_path` is not part of
73
- `task_group.path`, by copying `wheel_path` into `path`.
79
+ Handle the situation where `task_group.archive_path` is not part of
80
+ `task_group.path`, by copying `archive_path` into `path`.
74
81
 
75
82
  Returns:
76
- The new `wheel_path`.
83
+ The new `archive_path`.
77
84
  """
78
85
  logger = get_logger(logger_name=logger_name)
79
- source = task_group.wheel_path
86
+ source = task_group.archive_path
80
87
  dest = (
81
- Path(task_group.path) / Path(task_group.wheel_path).name
88
+ Path(task_group.path) / Path(task_group.archive_path).name
82
89
  ).as_posix()
83
90
  cmd = f"cp {source} {dest}"
84
- logger.debug(f"[_copy_wheel_file] START {source=} {dest=}")
91
+ logger.debug(f"[_copy_wheel_file_ssh] START {source=} {dest=}")
85
92
  fractal_ssh.run_command(cmd=cmd)
86
- logger.debug(f"[_copy_wheel_file] END {source=} {dest=}")
93
+ logger.debug(f"[_copy_wheel_file_ssh] END {source=} {dest=}")
87
94
  return dest
95
+
96
+
97
+ def check_ssh_or_fail_and_cleanup(
98
+ *,
99
+ fractal_ssh: FractalSSH,
100
+ task_group: TaskGroupV2,
101
+ task_group_activity: TaskGroupActivityV2,
102
+ logger_name: str,
103
+ log_file_path: Path,
104
+ db: AsyncSession,
105
+ ) -> bool:
106
+ """
107
+ Check SSH connection.
108
+
109
+ Returns:
110
+ Whether SSH connection is OK.
111
+ """
112
+ try:
113
+ fractal_ssh.check_connection()
114
+ return True
115
+ except Exception as e:
116
+ logger = get_logger(logger_name=logger_name)
117
+ logger.error(
118
+ "Cannot establish SSH connection. " f"Original error: {str(e)}"
119
+ )
120
+ fail_and_cleanup(
121
+ task_group=task_group,
122
+ task_group_activity=task_group_activity,
123
+ logger_name=logger_name,
124
+ log_file_path=log_file_path,
125
+ exception=e,
126
+ db=db,
127
+ )
128
+ return False
@@ -1,21 +1,20 @@
1
- import logging
2
1
  import time
3
2
  from pathlib import Path
4
3
  from tempfile import TemporaryDirectory
5
4
 
6
- from ....ssh._fabric import SingleUseFractalSSH
7
- from ..utils_background import _prepare_tasks_metadata
8
5
  from ..utils_background import fail_and_cleanup
6
+ from ..utils_background import get_activity_and_task_group
7
+ from ..utils_background import prepare_tasks_metadata
9
8
  from ..utils_database import create_db_tasks_and_update_task_group_sync
9
+ from ._utils import check_ssh_or_fail_and_cleanup
10
10
  from fractal_server.app.db import get_sync_db
11
- from fractal_server.app.models.v2 import TaskGroupActivityV2
12
- from fractal_server.app.models.v2 import TaskGroupV2
11
+ from fractal_server.app.schemas.v2 import FractalUploadedFile
13
12
  from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
14
13
  from fractal_server.app.schemas.v2 import TaskGroupActivityStatusV2
15
- from fractal_server.app.schemas.v2 import WheelFile
16
14
  from fractal_server.app.schemas.v2.manifest import ManifestV2
17
15
  from fractal_server.logger import reset_logger_handlers
18
16
  from fractal_server.logger import set_logger
17
+ from fractal_server.ssh._fabric import SingleUseFractalSSH
19
18
  from fractal_server.ssh._fabric import SSHConfig
20
19
  from fractal_server.tasks.v2.ssh._utils import _customize_and_run_template
21
20
  from fractal_server.tasks.v2.utils_background import add_commit_refresh
@@ -38,7 +37,7 @@ def collect_ssh(
38
37
  task_group_activity_id: int,
39
38
  ssh_config: SSHConfig,
40
39
  tasks_base_dir: str,
41
- wheel_file: WheelFile | None = None,
40
+ wheel_file: FractalUploadedFile | None = None,
42
41
  ) -> None:
43
42
  """
44
43
  Collect a task package over SSH
@@ -70,47 +69,39 @@ def collect_ssh(
70
69
  logger_name=LOGGER_NAME,
71
70
  log_file_path=log_file_path,
72
71
  )
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}")
72
+ logger.info("START")
73
+ with next(get_sync_db()) as db:
74
+ db_objects_ok, task_group, activity = get_activity_and_task_group(
75
+ task_group_activity_id=task_group_activity_id,
76
+ task_group_id=task_group_id,
77
+ db=db,
78
+ logger_name=LOGGER_NAME,
79
+ )
80
+ if not db_objects_ok:
81
+ return
82
+
83
+ with SingleUseFractalSSH(
84
+ ssh_config=ssh_config,
85
+ logger_name=LOGGER_NAME,
86
+ ) as fractal_ssh:
95
87
 
96
- # Check that SSH connection works
97
88
  try:
98
- fractal_ssh.check_connection()
99
- except Exception as e:
100
- logger.error("Cannot establish SSH connection.")
101
- fail_and_cleanup(
89
+ # Check SSH connection
90
+ ssh_ok = check_ssh_or_fail_and_cleanup(
91
+ fractal_ssh=fractal_ssh,
102
92
  task_group=task_group,
103
93
  task_group_activity=activity,
104
94
  logger_name=LOGGER_NAME,
105
95
  log_file_path=log_file_path,
106
- exception=e,
107
96
  db=db,
108
97
  )
109
- return
110
-
111
- try:
98
+ if not ssh_ok:
99
+ return
112
100
 
113
101
  # Check that the (remote) task_group path does not exist
102
+ # NOTE: this is not part of the try/except below, in order
103
+ # to avoid removing the existing folder (as part of the
104
+ # exception-handling).
114
105
  if fractal_ssh.remote_exists(task_group.path):
115
106
  error_msg = f"{task_group.path} already exists."
116
107
  logger.error(error_msg)
@@ -125,9 +116,7 @@ def collect_ssh(
125
116
  return
126
117
 
127
118
  # Create remote `task_group.path` and `script_dir_remote`
128
- # folders (note that because of `parents=True` we are in
129
- # the `no error if existing, make parent directories as
130
- # needed` scenario for `mkdir`)
119
+ # folders
131
120
  script_dir_remote = (
132
121
  Path(task_group.path) / SCRIPTS_SUBFOLDER
133
122
  ).as_posix()
@@ -135,25 +124,25 @@ def collect_ssh(
135
124
  fractal_ssh.mkdir(folder=script_dir_remote, parents=True)
136
125
 
137
126
  # Write wheel file locally and send it to remote path,
138
- # and set task_group.wheel_path
127
+ # and set task_group.archive_path
139
128
  if wheel_file is not None:
140
129
  wheel_filename = wheel_file.filename
141
- wheel_path = (
130
+ archive_path = (
142
131
  Path(task_group.path) / wheel_filename
143
132
  ).as_posix()
144
- tmp_wheel_path = (
133
+ tmp_archive_path = (
145
134
  Path(tmpdir) / wheel_filename
146
135
  ).as_posix()
147
136
  logger.info(
148
- f"Write wheel-file contents into {tmp_wheel_path}"
137
+ f"Write wheel file into {tmp_archive_path}"
149
138
  )
150
- with open(tmp_wheel_path, "wb") as f:
139
+ with open(tmp_archive_path, "wb") as f:
151
140
  f.write(wheel_file.contents)
152
141
  fractal_ssh.send_file(
153
- local=tmp_wheel_path,
154
- remote=wheel_path,
142
+ local=tmp_archive_path,
143
+ remote=archive_path,
155
144
  )
156
- task_group.wheel_path = wheel_path
145
+ task_group.archive_path = archive_path
157
146
  task_group = add_commit_refresh(obj=task_group, db=db)
158
147
 
159
148
  replacements = get_collection_replacements(
@@ -166,8 +155,8 @@ def collect_ssh(
166
155
  # Prepare common arguments for _customize_and_run_template
167
156
  common_args = dict(
168
157
  replacements=replacements,
169
- script_dir_local=(
170
- Path(tmpdir) / SCRIPTS_SUBFOLDER
158
+ script_dir_local=Path(
159
+ tmpdir, SCRIPTS_SUBFOLDER
171
160
  ).as_posix(),
172
161
  script_dir_remote=script_dir_remote,
173
162
  prefix=(
@@ -192,6 +181,7 @@ def collect_ssh(
192
181
  )
193
182
  activity.log = get_current_log(log_file_path)
194
183
  activity = add_commit_refresh(obj=activity, db=db)
184
+
195
185
  # Run script 2
196
186
  stdout = _customize_and_run_template(
197
187
  template_filename="2_pip_install.sh",
@@ -263,7 +253,7 @@ def collect_ssh(
263
253
  logger.info("Manifest is a valid ManifestV2")
264
254
 
265
255
  logger.info("_prepare_tasks_metadata - start")
266
- task_list = _prepare_tasks_metadata(
256
+ task_list = prepare_tasks_metadata(
267
257
  package_manifest=pkg_manifest,
268
258
  package_version=task_group.version,
269
259
  package_root=Path(package_root_remote),
@@ -283,15 +273,15 @@ def collect_ssh(
283
273
 
284
274
  # Update task_group data
285
275
  logger.info(
286
- "Add pip_freeze, venv_size and venv_file_number "
276
+ "Add env_info, venv_size and venv_file_number "
287
277
  "to TaskGroupV2 - start"
288
278
  )
289
- task_group.pip_freeze = pip_freeze_stdout
279
+ task_group.env_info = pip_freeze_stdout
290
280
  task_group.venv_size_in_kB = int(venv_size)
291
281
  task_group.venv_file_number = int(venv_file_number)
292
282
  task_group = add_commit_refresh(obj=task_group, db=db)
293
283
  logger.info(
294
- "Add pip_freeze, venv_size and venv_file_number "
284
+ "Add env_info, venv_size and venv_file_number "
295
285
  "to TaskGroupV2 - end"
296
286
  )
297
287
 
@@ -320,7 +310,7 @@ def collect_ssh(
320
310
  except Exception as e_rm:
321
311
  logger.error(
322
312
  "Removing folder failed. "
323
- f"Original error:\n{str(e_rm)}"
313
+ f"Original error: {str(e_rm)}"
324
314
  )
325
315
  fail_and_cleanup(
326
316
  task_group=task_group,