fractal-server 2.14.16__py3-none-any.whl → 2.15.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/models/v2/task_group.py +17 -5
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +2 -2
- fractal_server/app/routes/api/v2/__init__.py +6 -0
- fractal_server/app/routes/api/v2/task_collection.py +3 -3
- fractal_server/app/routes/api/v2/task_collection_custom.py +2 -2
- fractal_server/app/routes/api/v2/task_collection_pixi.py +236 -0
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +26 -7
- fractal_server/app/schemas/v2/__init__.py +2 -1
- fractal_server/app/schemas/v2/dumps.py +1 -1
- fractal_server/app/schemas/v2/task_collection.py +1 -1
- fractal_server/app/schemas/v2/task_group.py +16 -5
- fractal_server/config.py +42 -0
- fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +53 -0
- fractal_server/ssh/_fabric.py +26 -0
- fractal_server/tasks/v2/local/__init__.py +3 -0
- fractal_server/tasks/v2/local/_utils.py +7 -2
- fractal_server/tasks/v2/local/collect.py +23 -24
- fractal_server/tasks/v2/local/collect_pixi.py +234 -0
- fractal_server/tasks/v2/local/deactivate.py +36 -39
- fractal_server/tasks/v2/local/deactivate_pixi.py +102 -0
- fractal_server/tasks/v2/local/reactivate.py +9 -16
- fractal_server/tasks/v2/local/reactivate_pixi.py +146 -0
- fractal_server/tasks/v2/ssh/__init__.py +3 -0
- fractal_server/tasks/v2/ssh/_utils.py +5 -5
- fractal_server/tasks/v2/ssh/collect.py +23 -28
- fractal_server/tasks/v2/ssh/collect_pixi.py +306 -0
- fractal_server/tasks/v2/ssh/deactivate.py +39 -45
- fractal_server/tasks/v2/ssh/deactivate_pixi.py +128 -0
- fractal_server/tasks/v2/ssh/reactivate.py +8 -15
- fractal_server/tasks/v2/ssh/reactivate_pixi.py +108 -0
- fractal_server/tasks/v2/templates/pixi_1_extract.sh +40 -0
- fractal_server/tasks/v2/templates/pixi_2_install.sh +48 -0
- fractal_server/tasks/v2/templates/pixi_3_post_install.sh +80 -0
- fractal_server/tasks/v2/utils_background.py +43 -8
- fractal_server/tasks/v2/utils_pixi.py +38 -0
- {fractal_server-2.14.16.dist-info → fractal_server-2.15.0a1.dist-info}/METADATA +1 -1
- {fractal_server-2.14.16.dist-info → fractal_server-2.15.0a1.dist-info}/RECORD +41 -29
- {fractal_server-2.14.16.dist-info → fractal_server-2.15.0a1.dist-info}/LICENSE +0 -0
- {fractal_server-2.14.16.dist-info → fractal_server-2.15.0a1.dist-info}/WHEEL +0 -0
- {fractal_server-2.14.16.dist-info → fractal_server-2.15.0a1.dist-info}/entry_points.txt +0 -0
@@ -1,16 +1,14 @@
|
|
1
|
-
import logging
|
2
1
|
import time
|
3
2
|
from pathlib import Path
|
4
3
|
from tempfile import TemporaryDirectory
|
5
4
|
|
6
5
|
from ..utils_background import add_commit_refresh
|
7
6
|
from ..utils_background import fail_and_cleanup
|
7
|
+
from ..utils_background import get_activity_and_task_group
|
8
8
|
from ..utils_templates import get_collection_replacements
|
9
9
|
from ._utils import _copy_wheel_file_ssh
|
10
10
|
from ._utils import _customize_and_run_template
|
11
11
|
from fractal_server.app.db import get_sync_db
|
12
|
-
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
13
|
-
from fractal_server.app.models.v2 import TaskGroupV2
|
14
12
|
from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
|
15
13
|
from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
|
16
14
|
from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
|
@@ -61,17 +59,12 @@ def deactivate_ssh(
|
|
61
59
|
) as fractal_ssh:
|
62
60
|
|
63
61
|
with next(get_sync_db()) as db:
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
logging.error(
|
71
|
-
"Cannot find database rows with "
|
72
|
-
f"{task_group_id=} and {task_group_activity_id=}:\n"
|
73
|
-
f"{task_group=}\n{activity=}. Exit."
|
74
|
-
)
|
62
|
+
success, task_group, activity = get_activity_and_task_group(
|
63
|
+
task_group_activity_id=task_group_activity_id,
|
64
|
+
task_group_id=task_group_id,
|
65
|
+
db=db,
|
66
|
+
)
|
67
|
+
if not success:
|
75
68
|
return
|
76
69
|
|
77
70
|
# Log some info
|
@@ -113,10 +106,10 @@ def deactivate_ssh(
|
|
113
106
|
activity.status = TaskGroupActivityStatusV2.ONGOING
|
114
107
|
activity = add_commit_refresh(obj=activity, db=db)
|
115
108
|
|
116
|
-
if task_group.
|
109
|
+
if task_group.env_info is None:
|
117
110
|
logger.warning(
|
118
111
|
"Recreate pip-freeze information, since "
|
119
|
-
f"{task_group.
|
112
|
+
f"{task_group.env_info=}. NOTE: this should "
|
120
113
|
"only happen for task groups created before 2.9.0."
|
121
114
|
)
|
122
115
|
|
@@ -161,7 +154,7 @@ def deactivate_ssh(
|
|
161
154
|
)
|
162
155
|
activity.log = get_current_log(log_file_path)
|
163
156
|
activity = add_commit_refresh(obj=activity, db=db)
|
164
|
-
task_group.
|
157
|
+
task_group.env_info = pip_freeze_stdout
|
165
158
|
task_group = add_commit_refresh(obj=task_group, db=db)
|
166
159
|
logger.info(
|
167
160
|
"Add pip freeze stdout to TaskGroupV2 - end"
|
@@ -174,18 +167,19 @@ def deactivate_ssh(
|
|
174
167
|
f"Handle specific cases for {task_group.origin=}."
|
175
168
|
)
|
176
169
|
|
177
|
-
# Blocking situation: `
|
178
|
-
# to a missing path
|
170
|
+
# Blocking situation: `archive_path` is not set or
|
171
|
+
# points to a missing path
|
179
172
|
if (
|
180
|
-
task_group.
|
173
|
+
task_group.archive_path is None
|
181
174
|
or not fractal_ssh.remote_exists(
|
182
|
-
task_group.
|
175
|
+
task_group.archive_path
|
183
176
|
)
|
184
177
|
):
|
185
178
|
error_msg = (
|
186
179
|
"Invalid wheel path for task group with "
|
187
|
-
f"{task_group_id=}.
|
188
|
-
"is unset or
|
180
|
+
f"{task_group_id=}. "
|
181
|
+
f"{task_group.archive_path=} is unset or "
|
182
|
+
"does not exist."
|
189
183
|
)
|
190
184
|
logger.error(error_msg)
|
191
185
|
fail_and_cleanup(
|
@@ -198,58 +192,58 @@ def deactivate_ssh(
|
|
198
192
|
)
|
199
193
|
return
|
200
194
|
|
201
|
-
# Recoverable situation: `
|
195
|
+
# Recoverable situation: `archive_path` was not yet
|
202
196
|
# copied over to the correct server-side folder
|
203
|
-
|
204
|
-
task_group.
|
197
|
+
archive_path_parent_dir = Path(
|
198
|
+
task_group.archive_path
|
205
199
|
).parent
|
206
|
-
if
|
200
|
+
if archive_path_parent_dir != Path(task_group.path):
|
207
201
|
logger.warning(
|
208
|
-
f"{
|
209
|
-
f"from {task_group.path}.
|
210
|
-
"only happen for task
|
211
|
-
"2.9.0."
|
202
|
+
f"{archive_path_parent_dir.as_posix()} "
|
203
|
+
f"differs from {task_group.path}. "
|
204
|
+
"NOTE: this should only happen for task "
|
205
|
+
"groups created before 2.9.0."
|
212
206
|
)
|
213
207
|
|
214
208
|
if (
|
215
|
-
task_group.
|
216
|
-
not in task_group.
|
209
|
+
task_group.archive_path
|
210
|
+
not in task_group.env_info
|
217
211
|
):
|
218
212
|
raise ValueError(
|
219
|
-
f"Cannot find {task_group.
|
220
|
-
"pip-freeze data. Exit."
|
213
|
+
f"Cannot find {task_group.archive_path=} "
|
214
|
+
"in pip-freeze data. Exit."
|
221
215
|
)
|
222
216
|
|
223
217
|
logger.info(
|
224
218
|
f"Now copy wheel file into {task_group.path}."
|
225
219
|
)
|
226
|
-
|
220
|
+
new_archive_path = _copy_wheel_file_ssh(
|
227
221
|
task_group=task_group,
|
228
222
|
fractal_ssh=fractal_ssh,
|
229
223
|
logger_name=LOGGER_NAME,
|
230
224
|
)
|
231
225
|
logger.info(
|
232
|
-
f"Copied wheel file to {
|
226
|
+
f"Copied wheel file to {new_archive_path}."
|
233
227
|
)
|
234
228
|
|
235
|
-
task_group.
|
236
|
-
new_pip_freeze = task_group.
|
237
|
-
task_group.
|
238
|
-
|
229
|
+
task_group.archive_path = new_archive_path
|
230
|
+
new_pip_freeze = task_group.env_info.replace(
|
231
|
+
task_group.archive_path,
|
232
|
+
new_archive_path,
|
239
233
|
)
|
240
|
-
task_group.
|
234
|
+
task_group.env_info = new_pip_freeze
|
241
235
|
task_group = add_commit_refresh(
|
242
236
|
obj=task_group, db=db
|
243
237
|
)
|
244
238
|
logger.info(
|
245
|
-
"Updated `
|
239
|
+
"Updated `archive_path` and `env_info` "
|
246
240
|
"task-group attributes."
|
247
241
|
)
|
248
242
|
|
249
|
-
# Fail if `
|
243
|
+
# Fail if `env_info` includes "github", see
|
250
244
|
# https://github.com/fractal-analytics-platform/fractal-server/issues/2142
|
251
245
|
for forbidden_string in FORBIDDEN_DEPENDENCY_STRINGS:
|
252
|
-
if forbidden_string in task_group.
|
246
|
+
if forbidden_string in task_group.env_info:
|
253
247
|
raise ValueError(
|
254
248
|
"Deactivation and reactivation of task "
|
255
249
|
f"packages with direct {forbidden_string} "
|
@@ -0,0 +1,128 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from tempfile import TemporaryDirectory
|
3
|
+
|
4
|
+
from ..utils_background import add_commit_refresh
|
5
|
+
from ..utils_background import fail_and_cleanup
|
6
|
+
from ..utils_background import get_activity_and_task_group
|
7
|
+
from ..utils_pixi import SOURCE_DIR_NAME
|
8
|
+
from fractal_server.app.db import get_sync_db
|
9
|
+
from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
|
10
|
+
from fractal_server.logger import reset_logger_handlers
|
11
|
+
from fractal_server.logger import set_logger
|
12
|
+
from fractal_server.ssh._fabric import SingleUseFractalSSH
|
13
|
+
from fractal_server.ssh._fabric import SSHConfig
|
14
|
+
from fractal_server.tasks.utils import get_log_path
|
15
|
+
from fractal_server.tasks.v2.utils_background import get_current_log
|
16
|
+
from fractal_server.utils import get_timestamp
|
17
|
+
|
18
|
+
|
19
|
+
def deactivate_ssh_pixi(
|
20
|
+
*,
|
21
|
+
task_group_activity_id: int,
|
22
|
+
task_group_id: int,
|
23
|
+
ssh_config: SSHConfig,
|
24
|
+
tasks_base_dir: str,
|
25
|
+
) -> None:
|
26
|
+
"""
|
27
|
+
Deactivate a pixi task group venv.
|
28
|
+
|
29
|
+
This function is run as a background task, therefore exceptions must be
|
30
|
+
handled.
|
31
|
+
|
32
|
+
Arguments:
|
33
|
+
task_group_id:
|
34
|
+
task_group_activity_id:
|
35
|
+
ssh_config:
|
36
|
+
tasks_base_dir:
|
37
|
+
Only used as a `safe_root` in `remove_dir`, and typically set to
|
38
|
+
`user_settings.ssh_tasks_dir`.
|
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
|
+
with SingleUseFractalSSH(
|
50
|
+
ssh_config=ssh_config,
|
51
|
+
logger_name=LOGGER_NAME,
|
52
|
+
) as fractal_ssh:
|
53
|
+
|
54
|
+
with next(get_sync_db()) as db:
|
55
|
+
success, task_group, activity = get_activity_and_task_group(
|
56
|
+
task_group_activity_id=task_group_activity_id,
|
57
|
+
task_group_id=task_group_id,
|
58
|
+
db=db,
|
59
|
+
)
|
60
|
+
if not success:
|
61
|
+
return
|
62
|
+
|
63
|
+
# Log some info
|
64
|
+
logger.debug("START")
|
65
|
+
for key, value in task_group.model_dump().items():
|
66
|
+
logger.debug(f"task_group.{key}: {value}")
|
67
|
+
|
68
|
+
# Check that SSH connection works
|
69
|
+
try:
|
70
|
+
fractal_ssh.check_connection()
|
71
|
+
except Exception as e:
|
72
|
+
logger.error("Cannot establish SSH connection.")
|
73
|
+
fail_and_cleanup(
|
74
|
+
task_group=task_group,
|
75
|
+
task_group_activity=activity,
|
76
|
+
logger_name=LOGGER_NAME,
|
77
|
+
log_file_path=log_file_path,
|
78
|
+
exception=e,
|
79
|
+
db=db,
|
80
|
+
)
|
81
|
+
return
|
82
|
+
|
83
|
+
try:
|
84
|
+
# Check that the (remote) task_group venv_path does exist
|
85
|
+
source_dir = Path(
|
86
|
+
task_group.path, SOURCE_DIR_NAME
|
87
|
+
).as_posix()
|
88
|
+
if not fractal_ssh.remote_exists(source_dir):
|
89
|
+
error_msg = f"{source_dir} does not exist."
|
90
|
+
logger.error(error_msg)
|
91
|
+
fail_and_cleanup(
|
92
|
+
task_group=task_group,
|
93
|
+
task_group_activity=activity,
|
94
|
+
logger_name=LOGGER_NAME,
|
95
|
+
log_file_path=log_file_path,
|
96
|
+
exception=FileNotFoundError(error_msg),
|
97
|
+
db=db,
|
98
|
+
)
|
99
|
+
return
|
100
|
+
|
101
|
+
# Actually mark the task group as non-active
|
102
|
+
logger.info("Now setting `active=False`.")
|
103
|
+
task_group.active = False
|
104
|
+
task_group = add_commit_refresh(obj=task_group, db=db)
|
105
|
+
|
106
|
+
# Proceed with deactivation
|
107
|
+
logger.info(f"Now removing {source_dir}.")
|
108
|
+
fractal_ssh.remove_folder(
|
109
|
+
folder=source_dir,
|
110
|
+
safe_root=tasks_base_dir,
|
111
|
+
)
|
112
|
+
logger.info(f"All good, {source_dir} removed.")
|
113
|
+
activity.status = TaskGroupActivityStatusV2.OK
|
114
|
+
activity.log = get_current_log(log_file_path)
|
115
|
+
activity.timestamp_ended = get_timestamp()
|
116
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
117
|
+
|
118
|
+
reset_logger_handlers(logger)
|
119
|
+
|
120
|
+
except Exception as e:
|
121
|
+
fail_and_cleanup(
|
122
|
+
task_group=task_group,
|
123
|
+
task_group_activity=activity,
|
124
|
+
logger_name=LOGGER_NAME,
|
125
|
+
log_file_path=log_file_path,
|
126
|
+
exception=e,
|
127
|
+
db=db,
|
128
|
+
)
|
@@ -1,15 +1,13 @@
|
|
1
|
-
import logging
|
2
1
|
import time
|
3
2
|
from pathlib import Path
|
4
3
|
from tempfile import TemporaryDirectory
|
5
4
|
|
6
5
|
from ..utils_background import add_commit_refresh
|
7
6
|
from ..utils_background import fail_and_cleanup
|
7
|
+
from ..utils_background import get_activity_and_task_group
|
8
8
|
from ..utils_templates import get_collection_replacements
|
9
9
|
from ._utils import _customize_and_run_template
|
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
|
13
11
|
from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
|
14
12
|
from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
|
15
13
|
from fractal_server.logger import reset_logger_handlers
|
@@ -62,17 +60,12 @@ def reactivate_ssh(
|
|
62
60
|
) as fractal_ssh:
|
63
61
|
|
64
62
|
with next(get_sync_db()) as db:
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
logging.error(
|
72
|
-
"Cannot find database rows with "
|
73
|
-
f"{task_group_id=} and {task_group_activity_id=}:\n"
|
74
|
-
f"{task_group=}\n{activity=}. Exit."
|
75
|
-
)
|
63
|
+
success, task_group, activity = get_activity_and_task_group(
|
64
|
+
task_group_activity_id=task_group_activity_id,
|
65
|
+
task_group_id=task_group_id,
|
66
|
+
db=db,
|
67
|
+
)
|
68
|
+
if not success:
|
76
69
|
return
|
77
70
|
|
78
71
|
# Log some info
|
@@ -128,7 +121,7 @@ def reactivate_ssh(
|
|
128
121
|
Path(task_group.path) / "_tmp_pip_freeze.txt"
|
129
122
|
).as_posix()
|
130
123
|
with open(pip_freeze_file_local, "w") as f:
|
131
|
-
f.write(task_group.
|
124
|
+
f.write(task_group.env_info)
|
132
125
|
fractal_ssh.send_file(
|
133
126
|
local=pip_freeze_file_local,
|
134
127
|
remote=pip_freeze_file_remote,
|
@@ -0,0 +1,108 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from tempfile import TemporaryDirectory
|
3
|
+
|
4
|
+
from ..utils_background import fail_and_cleanup
|
5
|
+
from ..utils_background import get_activity_and_task_group
|
6
|
+
from fractal_server.app.db import get_sync_db
|
7
|
+
from fractal_server.logger import reset_logger_handlers
|
8
|
+
from fractal_server.logger import set_logger
|
9
|
+
from fractal_server.ssh._fabric import SingleUseFractalSSH
|
10
|
+
from fractal_server.ssh._fabric import SSHConfig
|
11
|
+
from fractal_server.tasks.utils import get_log_path
|
12
|
+
|
13
|
+
|
14
|
+
def reactivate_ssh_pixi(
|
15
|
+
*,
|
16
|
+
task_group_activity_id: int,
|
17
|
+
task_group_id: int,
|
18
|
+
ssh_config: SSHConfig,
|
19
|
+
tasks_base_dir: str,
|
20
|
+
) -> None:
|
21
|
+
"""
|
22
|
+
Reactivate a task group venv.
|
23
|
+
|
24
|
+
This function is run as a background task, therefore exceptions must be
|
25
|
+
handled.
|
26
|
+
|
27
|
+
Arguments:
|
28
|
+
task_group_id:
|
29
|
+
task_group_activity_id:
|
30
|
+
ssh_config:
|
31
|
+
tasks_base_dir:
|
32
|
+
Only used as a `safe_root` in `remove_dir`, and typically set to
|
33
|
+
`user_settings.ssh_tasks_dir`.
|
34
|
+
"""
|
35
|
+
|
36
|
+
LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
|
37
|
+
|
38
|
+
with TemporaryDirectory() as tmpdir:
|
39
|
+
log_file_path = get_log_path(Path(tmpdir))
|
40
|
+
logger = set_logger(
|
41
|
+
logger_name=LOGGER_NAME,
|
42
|
+
log_file_path=log_file_path,
|
43
|
+
)
|
44
|
+
|
45
|
+
with SingleUseFractalSSH(
|
46
|
+
ssh_config=ssh_config,
|
47
|
+
logger_name=LOGGER_NAME,
|
48
|
+
) as fractal_ssh:
|
49
|
+
|
50
|
+
with next(get_sync_db()) as db:
|
51
|
+
success, 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
|
+
)
|
56
|
+
if not success:
|
57
|
+
return
|
58
|
+
|
59
|
+
# Log some info
|
60
|
+
logger.info("START")
|
61
|
+
for key, value in task_group.model_dump().items():
|
62
|
+
logger.debug(f"task_group.{key}: {value}")
|
63
|
+
|
64
|
+
# Check that SSH connection works
|
65
|
+
try:
|
66
|
+
fractal_ssh.check_connection()
|
67
|
+
except Exception as e:
|
68
|
+
logger.error("Cannot establish SSH connection.")
|
69
|
+
fail_and_cleanup(
|
70
|
+
task_group=task_group,
|
71
|
+
task_group_activity=activity,
|
72
|
+
logger_name=LOGGER_NAME,
|
73
|
+
log_file_path=log_file_path,
|
74
|
+
exception=e,
|
75
|
+
db=db,
|
76
|
+
)
|
77
|
+
return
|
78
|
+
|
79
|
+
try:
|
80
|
+
raise NotImplementedError("pixi-task reactivation FIXME")
|
81
|
+
|
82
|
+
reset_logger_handlers(logger)
|
83
|
+
|
84
|
+
except Exception as reactivate_e:
|
85
|
+
# Delete corrupted venv_path
|
86
|
+
try:
|
87
|
+
logger.info(
|
88
|
+
f"Now delete folder {task_group.venv_path}"
|
89
|
+
)
|
90
|
+
fractal_ssh.remove_folder(
|
91
|
+
folder=task_group.venv_path,
|
92
|
+
safe_root=tasks_base_dir,
|
93
|
+
)
|
94
|
+
logger.info(f"Deleted folder {task_group.venv_path}")
|
95
|
+
except Exception as rm_e:
|
96
|
+
logger.error(
|
97
|
+
"Removing folder failed.\n"
|
98
|
+
f"Original error:\n{str(rm_e)}"
|
99
|
+
)
|
100
|
+
|
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=reactivate_e,
|
107
|
+
db=db,
|
108
|
+
)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
set -e
|
2
|
+
|
3
|
+
write_log(){
|
4
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
5
|
+
echo "[collect-task-pixi, ${TIMESTAMP}] ${1}"
|
6
|
+
}
|
7
|
+
|
8
|
+
# Replacements
|
9
|
+
PACKAGE_DIR="__PACKAGE_DIR__"
|
10
|
+
TAR_GZ_PATH="__TAR_GZ_PATH__"
|
11
|
+
SOURCE_DIR_NAME="__SOURCE_DIR_NAME__"
|
12
|
+
|
13
|
+
# Strip trailing `/` from `PACKAGE_DIR`
|
14
|
+
PACKAGE_DIR=${PACKAGE_DIR%/}
|
15
|
+
|
16
|
+
# Known paths
|
17
|
+
SOURCE_DIR="${PACKAGE_DIR}/${SOURCE_DIR_NAME}"
|
18
|
+
TAR_GZ_BASENAME=$(basename "${TAR_GZ_PATH}" ".tar.gz")
|
19
|
+
|
20
|
+
TIME_START=$(date +%s)
|
21
|
+
|
22
|
+
cd "${PACKAGE_DIR}"
|
23
|
+
write_log "Changed working directory to ${PACKAGE_DIR}"
|
24
|
+
|
25
|
+
# -----------------------------------------------------------------------------
|
26
|
+
|
27
|
+
write_log "START 'tar xz -f ${TAR_GZ_PATH} ${TAR_GZ_BASENAME}'"
|
28
|
+
tar xz -f "${TAR_GZ_PATH}" "${TAR_GZ_BASENAME}"
|
29
|
+
write_log "END 'tar xz -f ${TAR_GZ_PATH} ${TAR_GZ_BASENAME}'"
|
30
|
+
echo
|
31
|
+
|
32
|
+
write_log "START 'mv ${PACKAGE_DIR}/${TAR_GZ_BASENAME} ${SOURCE_DIR}'"
|
33
|
+
mv "${PACKAGE_DIR}/${TAR_GZ_BASENAME}" "${SOURCE_DIR}"
|
34
|
+
write_log "END 'mv ${PACKAGE_DIR}/${TAR_GZ_BASENAME} ${SOURCE_DIR}'"
|
35
|
+
echo
|
36
|
+
|
37
|
+
TIME_END=$(date +%s)
|
38
|
+
write_log "Elapsed: $((TIME_END - TIME_START)) seconds"
|
39
|
+
write_log "All ok, exit."
|
40
|
+
echo
|
@@ -0,0 +1,48 @@
|
|
1
|
+
set -e
|
2
|
+
|
3
|
+
write_log(){
|
4
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
5
|
+
echo "[collect-task-pixi, ${TIMESTAMP}] ${1}"
|
6
|
+
}
|
7
|
+
|
8
|
+
# Replacements
|
9
|
+
PIXI_HOME="__PIXI_HOME__"
|
10
|
+
PACKAGE_DIR="__PACKAGE_DIR__"
|
11
|
+
SOURCE_DIR_NAME="__SOURCE_DIR_NAME__"
|
12
|
+
FROZEN_OPTION="__FROZEN_OPTION__"
|
13
|
+
|
14
|
+
# Strip trailing `/` from `PACKAGE_DIR`
|
15
|
+
PIXI_HOME=${PIXI_HOME%/}
|
16
|
+
PACKAGE_DIR=${PACKAGE_DIR%/}
|
17
|
+
|
18
|
+
# Known paths
|
19
|
+
PIXI_EXECUTABLE="${PIXI_HOME}/bin/pixi"
|
20
|
+
SOURCE_DIR="${PACKAGE_DIR}/${SOURCE_DIR_NAME}"
|
21
|
+
PYPROJECT_TOML="${SOURCE_DIR}/pyproject.toml"
|
22
|
+
|
23
|
+
# Pixi env variable
|
24
|
+
export PIXI_HOME="${PIXI_HOME}"
|
25
|
+
export PIXI_CACHE_DIR="${PIXI_HOME}/cache"
|
26
|
+
export RATTLER_AUTH_FILE="${PIXI_HOME}/credentials.json"
|
27
|
+
|
28
|
+
TIME_START=$(date +%s)
|
29
|
+
|
30
|
+
cd "${PACKAGE_DIR}"
|
31
|
+
write_log "Changed working directory to ${PACKAGE_DIR}"
|
32
|
+
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
|
35
|
+
FROZEN_FLAG=""
|
36
|
+
if [[ "${FROZEN_OPTION}" == "true" ]]; then
|
37
|
+
FROZEN_FLAG="--frozen"
|
38
|
+
fi
|
39
|
+
|
40
|
+
write_log "START '${PIXI_EXECUTABLE} install ${FROZEN_FLAG} --manifest-path ${PYPROJECT_TOML}'"
|
41
|
+
${PIXI_EXECUTABLE} install ${FROZEN_FLAG} --manifest-path "${PYPROJECT_TOML}"
|
42
|
+
write_log "END '${PIXI_EXECUTABLE} install ${FROZEN_FLAG} --manifest-path ${PYPROJECT_TOML}'"
|
43
|
+
echo
|
44
|
+
|
45
|
+
TIME_END=$(date +%s)
|
46
|
+
write_log "Elapsed: $((TIME_END - TIME_START)) seconds"
|
47
|
+
write_log "All ok, exit."
|
48
|
+
echo
|
@@ -0,0 +1,80 @@
|
|
1
|
+
set -e
|
2
|
+
|
3
|
+
write_log(){
|
4
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
5
|
+
echo "[collect-task-pixi, ${TIMESTAMP}] ${1}"
|
6
|
+
}
|
7
|
+
|
8
|
+
# Replacements
|
9
|
+
PIXI_HOME="__PIXI_HOME__"
|
10
|
+
PACKAGE_DIR="__PACKAGE_DIR__"
|
11
|
+
SOURCE_DIR_NAME="__SOURCE_DIR_NAME__"
|
12
|
+
IMPORT_PACKAGE_NAME="__IMPORT_PACKAGE_NAME__"
|
13
|
+
|
14
|
+
# Strip trailing `/` from `PACKAGE_DIR`
|
15
|
+
PIXI_HOME=${PIXI_HOME%/}
|
16
|
+
PACKAGE_DIR=${PACKAGE_DIR%/}
|
17
|
+
|
18
|
+
# Known paths
|
19
|
+
PIXI_EXECUTABLE="${PIXI_HOME}/bin/pixi"
|
20
|
+
SOURCE_DIR="${PACKAGE_DIR}/${SOURCE_DIR_NAME}"
|
21
|
+
PYPROJECT_TOML="${SOURCE_DIR}/pyproject.toml"
|
22
|
+
ACTIVATION_FILE="${SOURCE_DIR}/activate_project.sh"
|
23
|
+
PROJECT_PYTHON_WRAPPER="${SOURCE_DIR}/project_python.sh"
|
24
|
+
|
25
|
+
# Pixi env variable
|
26
|
+
export PIXI_HOME="${PIXI_HOME}"
|
27
|
+
export PIXI_CACHE_DIR="${PIXI_HOME}/cache"
|
28
|
+
export RATTLER_AUTH_FILE="${PIXI_HOME}/credentials.json"
|
29
|
+
|
30
|
+
|
31
|
+
TIME_START=$(date +%s)
|
32
|
+
|
33
|
+
cd "${PACKAGE_DIR}"
|
34
|
+
write_log "Changed working directory to ${PACKAGE_DIR}"
|
35
|
+
|
36
|
+
# -----------------------------------------------------------------------------
|
37
|
+
|
38
|
+
write_log "START '${PIXI_EXECUTABLE} shell-hook --manifest-path ${PYPROJECT_TOML}'"
|
39
|
+
${PIXI_EXECUTABLE} shell-hook --manifest-path "${PYPROJECT_TOML}" > "${ACTIVATION_FILE}"
|
40
|
+
write_log "END '${PIXI_EXECUTABLE} shell-hook --manifest-path ${PYPROJECT_TOML}'"
|
41
|
+
echo
|
42
|
+
|
43
|
+
PROJECT_PYTHON_BIN=$(${PIXI_EXECUTABLE} run --manifest-path "${PYPROJECT_TOML}" which python)
|
44
|
+
write_log "Found PROJECT_PYTHON_BIN=${PROJECT_PYTHON_BIN}"
|
45
|
+
|
46
|
+
# Write project-scoped Python wrapper
|
47
|
+
cat <<EOF > "${PROJECT_PYTHON_WRAPPER}"
|
48
|
+
#!/bin/bash
|
49
|
+
source ${ACTIVATION_FILE}
|
50
|
+
${PROJECT_PYTHON_BIN} "\$@"
|
51
|
+
EOF
|
52
|
+
|
53
|
+
chmod 755 "${PROJECT_PYTHON_WRAPPER}"
|
54
|
+
write_log "Written ${PROJECT_PYTHON_WRAPPER} with 755 permissions"
|
55
|
+
write_log "Project Python wrapper: ${PROJECT_PYTHON_WRAPPER}"
|
56
|
+
write_log "Project-Python version: $(${PROJECT_PYTHON_WRAPPER} --version)"
|
57
|
+
echo
|
58
|
+
|
59
|
+
# Find PACKAGE_FOLDER
|
60
|
+
FIND_PACKAGE_FOLDER_SCRIPT="${SOURCE_DIR}/find_package_folder.sh"
|
61
|
+
echo "source ${ACTIVATION_FILE}" > "${FIND_PACKAGE_FOLDER_SCRIPT}"
|
62
|
+
echo "${PROJECT_PYTHON_BIN} -c \"import ${IMPORT_PACKAGE_NAME} as p, os; print(os.path.dirname(p.__file__))\"" >> "${FIND_PACKAGE_FOLDER_SCRIPT}"
|
63
|
+
PACKAGE_FOLDER=$(bash "${FIND_PACKAGE_FOLDER_SCRIPT}")
|
64
|
+
write_log "Package folder: ${PACKAGE_FOLDER}"
|
65
|
+
echo
|
66
|
+
|
67
|
+
ENV_DISK_USAGE=$(du -sk "${PACKAGE_DIR}" | cut -f1)
|
68
|
+
ENV_FILE_NUMBER=$(find "${PACKAGE_DIR}" -type f | wc -l)
|
69
|
+
write_log "Disk usage: ${ENV_DISK_USAGE}"
|
70
|
+
write_log "Number of files: ${ENV_FILE_NUMBER}"
|
71
|
+
echo
|
72
|
+
|
73
|
+
write_log "START chmod 755 ${SOURCE_DIR} -R"
|
74
|
+
chmod 755 "${SOURCE_DIR}" -R
|
75
|
+
write_log "END chmod 755 ${SOURCE_DIR} -R"
|
76
|
+
|
77
|
+
TIME_END=$(date +%s)
|
78
|
+
write_log "Elapsed: $((TIME_END - TIME_START)) seconds"
|
79
|
+
write_log "All ok, exit."
|
80
|
+
echo
|