Skip to content

Commit 57d2518

Browse files
author
Andrei Neagu
committed
decompressing legacy state path
1 parent a365ef8 commit 57d2518

File tree

4 files changed

+92
-16
lines changed

4 files changed

+92
-16
lines changed

Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,6 @@ down: ## Stops and removes stack
423423
ifneq ($(wildcard .stack-*), )
424424
-@rm $(wildcard .stack-*)
425425
endif
426-
# Removing local registry if any
427-
-@docker ps --all --quiet --filter "name=$(LOCAL_REGISTRY_HOSTNAME)" | xargs --no-run-if-empty docker rm --force
428426

429427
leave: ## Forces to stop all services, networks, etc by the node leaving the swarm
430428
-docker swarm leave -f

packages/simcore-sdk/src/simcore_sdk/node_data/data_manager.py

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from models_library.projects import ProjectID
66
from models_library.projects_nodes_io import NodeID, StorageFileID
7+
from models_library.service_settings_labels import LegacyState
78
from models_library.users import UserID
89
from pydantic import TypeAdapter
910
from servicelib.archiving_utils import unarchive_dir
@@ -101,14 +102,16 @@ async def _pull_legacy_archive(
101102
*,
102103
io_log_redirect_cb: LogRedirectCB,
103104
progress_bar: ProgressBarData,
105+
legacy_destination_path: Path | None = None,
104106
) -> None:
105107
# NOTE: the legacy way of storing states was as zip archives
108+
archive_path = legacy_destination_path or destination_path
106109
async with progress_bar.sub_progress(
107-
steps=2, description=f"pulling {destination_path.name}"
110+
steps=2, description=f"pulling {archive_path.name}"
108111
) as sub_prog:
109112
with TemporaryDirectory() as tmp_dir_name:
110113
archive_file = Path(tmp_dir_name) / __get_s3_name(
111-
destination_path, is_archive=True
114+
archive_path, is_archive=True
112115
)
113116

114117
s3_object = __create_s3_object_key(project_id, node_uuid, archive_file)
@@ -124,7 +127,7 @@ async def _pull_legacy_archive(
124127
progress_bar=sub_prog,
125128
aws_s3_cli_settings=None,
126129
)
127-
_logger.info("completed pull of %s.", destination_path)
130+
_logger.info("completed pull of %s.", archive_path)
128131

129132
if io_log_redirect_cb:
130133
await io_log_redirect_cb(
@@ -194,6 +197,7 @@ async def push(
194197
exclude_patterns: set[str] | None = None,
195198
progress_bar: ProgressBarData,
196199
aws_s3_cli_settings: AwsS3CliSettings | None,
200+
legacy_state: LegacyState | None,
197201
) -> None:
198202
"""pushes and removes the legacy archive if present"""
199203

@@ -208,23 +212,39 @@ async def push(
208212
progress_bar=progress_bar,
209213
aws_s3_cli_settings=aws_s3_cli_settings,
210214
)
215+
211216
archive_exists = await _state_metadata_entry_exists(
212217
user_id=user_id,
213218
project_id=project_id,
214219
node_uuid=node_uuid,
215220
path=source_path,
216221
is_archive=True,
217222
)
223+
if archive_exists:
224+
with log_context(_logger, logging.INFO, "removing legacy archive"):
225+
await _delete_legacy_archive(
226+
project_id=project_id,
227+
node_uuid=node_uuid,
228+
path=source_path,
229+
)
218230

219-
if not archive_exists:
220-
return
221-
222-
with log_context(_logger, logging.INFO, "removing legacy data archive"):
223-
await _delete_legacy_archive(
231+
if legacy_state:
232+
legacy_archive_exists = await _state_metadata_entry_exists(
233+
user_id=user_id,
224234
project_id=project_id,
225235
node_uuid=node_uuid,
226-
path=source_path,
236+
path=legacy_state.old_state_path,
237+
is_archive=True,
227238
)
239+
if legacy_archive_exists:
240+
with log_context(
241+
_logger, logging.INFO, f"removing legacy archive in {legacy_state}"
242+
):
243+
await _delete_legacy_archive(
244+
project_id=project_id,
245+
node_uuid=node_uuid,
246+
path=legacy_state.old_state_path,
247+
)
228248

229249

230250
async def pull(
@@ -237,9 +257,41 @@ async def pull(
237257
r_clone_settings: RCloneSettings,
238258
progress_bar: ProgressBarData,
239259
aws_s3_cli_settings: AwsS3CliSettings | None,
260+
legacy_state: LegacyState | None,
240261
) -> None:
241262
"""restores the state folder"""
242263

264+
if legacy_state and legacy_state.new_state_path == destination_path:
265+
_logger.info(
266+
"trying to restore from legacy_state=%s, destination_path=%s",
267+
legacy_state,
268+
destination_path,
269+
)
270+
legacy_state_exists = await _state_metadata_entry_exists(
271+
user_id=user_id,
272+
project_id=project_id,
273+
node_uuid=node_uuid,
274+
path=legacy_state.old_state_path,
275+
is_archive=True,
276+
)
277+
_logger.info("legacy_state_exists=%s", legacy_state_exists)
278+
if legacy_state_exists:
279+
with log_context(
280+
_logger,
281+
logging.INFO,
282+
f"restoring data from legacy archive in {legacy_state}",
283+
):
284+
await _pull_legacy_archive(
285+
user_id=user_id,
286+
project_id=project_id,
287+
node_uuid=node_uuid,
288+
destination_path=legacy_state.new_state_path,
289+
io_log_redirect_cb=io_log_redirect_cb,
290+
progress_bar=progress_bar,
291+
legacy_destination_path=legacy_state.old_state_path,
292+
)
293+
return
294+
243295
state_archive_exists = await _state_metadata_entry_exists(
244296
user_id=user_id,
245297
project_id=project_id,
@@ -248,7 +300,7 @@ async def pull(
248300
is_archive=True,
249301
)
250302
if state_archive_exists:
251-
with log_context(_logger, logging.INFO, "restoring legacy data archive"):
303+
with log_context(_logger, logging.INFO, "restoring data from legacy archive"):
252304
await _pull_legacy_archive(
253305
user_id=user_id,
254306
project_id=project_id,

packages/simcore-sdk/tests/unit/test_node_data_data_manager.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ async def test_push_file(
172172
mock_filemanager.reset_mock()
173173

174174

175+
@pytest.mark.parametrize("create_legacy_archive", [False, True])
175176
async def test_pull_legacy_archive(
176177
user_id: int,
177178
project_id: ProjectID,
@@ -181,6 +182,7 @@ async def test_pull_legacy_archive(
181182
create_files: Callable[..., list[Path]],
182183
mock_io_log_redirect_cb: LogRedirectCB,
183184
faker: Faker,
185+
create_legacy_archive: bool,
184186
):
185187
assert tmpdir.exists()
186188
# create a folder to compress from
@@ -200,7 +202,13 @@ async def test_pull_legacy_archive(
200202
create_files(files_number, test_control_folder)
201203
compressed_file_name = test_compression_folder / test_folder.stem
202204
archive_file = make_archive(
203-
f"{compressed_file_name}", "zip", root_dir=test_control_folder
205+
(
206+
f"{compressed_file_name}_legacy"
207+
if create_legacy_archive
208+
else f"{compressed_file_name}"
209+
),
210+
"zip",
211+
root_dir=test_control_folder,
204212
)
205213
assert Path(archive_file).exists()
206214
# create mock downloaded folder
@@ -229,13 +237,16 @@ async def test_pull_legacy_archive(
229237
test_folder,
230238
io_log_redirect_cb=mock_io_log_redirect_cb,
231239
progress_bar=progress_bar,
240+
legacy_destination_path=(
241+
Path(f"{test_folder}_legacy") if create_legacy_archive else None
242+
),
232243
)
233244
assert progress_bar._current_steps == pytest.approx(1) # noqa: SLF001
234245
mock_temporary_directory.assert_called_once()
235246
mock_filemanager.download_path_from_s3.assert_called_once_with(
236247
user_id=user_id,
237248
local_path=test_compression_folder,
238-
s3_object=f"{project_id}/{node_uuid}/{test_folder.stem}.zip",
249+
s3_object=f"{project_id}/{node_uuid}/{f'{test_folder.stem}_legacy' if create_legacy_archive else test_folder.stem}.zip",
239250
store_id=SIMCORE_LOCATION,
240251
store_name=None,
241252
io_log_redirect_cb=mock_io_log_redirect_cb,

services/dynamic-sidecar/src/simcore_service_dynamic_sidecar/modules/long_running_tasks.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
post_progress_message,
4444
post_sidecar_log_message,
4545
)
46-
from ..core.settings import ApplicationSettings
46+
from ..core.settings import ApplicationSettings, LegacyState
4747
from ..core.utils import CommandResult
4848
from ..core.validation import parse_compose_spec
4949
from ..models.schemas.application_health import ApplicationHealth
@@ -337,6 +337,19 @@ def _get_satate_folders_size(paths: list[Path]) -> int:
337337
return total_size
338338

339339

340+
def _get_legacy_state_with_dy_volumes_path(
341+
settings: ApplicationSettings,
342+
) -> LegacyState | None:
343+
legacy_state = settings.DY_SIDECAR_LEGACY_STATE
344+
if legacy_state is None:
345+
return None
346+
dy_volumes = settings.DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR
347+
return LegacyState(
348+
old_state_path=dy_volumes / legacy_state.old_state_path.relative_to("/"),
349+
new_state_path=dy_volumes / legacy_state.new_state_path.relative_to("/"),
350+
)
351+
352+
340353
async def _restore_state_folder(
341354
app: FastAPI,
342355
*,
@@ -348,13 +361,14 @@ async def _restore_state_folder(
348361
user_id=settings.DY_SIDECAR_USER_ID,
349362
project_id=settings.DY_SIDECAR_PROJECT_ID,
350363
node_uuid=settings.DY_SIDECAR_NODE_ID,
351-
destination_path=state_path,
364+
destination_path=Path(state_path),
352365
io_log_redirect_cb=functools.partial(
353366
post_sidecar_log_message, app, log_level=logging.INFO
354367
),
355368
r_clone_settings=settings.DY_SIDECAR_R_CLONE_SETTINGS,
356369
progress_bar=progress_bar,
357370
aws_s3_cli_settings=settings.DY_SIDECAR_AWS_S3_CLI_SETTINGS,
371+
legacy_state=_get_legacy_state_with_dy_volumes_path(settings),
358372
)
359373

360374

@@ -429,6 +443,7 @@ async def _save_state_folder(
429443
),
430444
progress_bar=progress_bar,
431445
aws_s3_cli_settings=settings.DY_SIDECAR_AWS_S3_CLI_SETTINGS,
446+
legacy_state=_get_legacy_state_with_dy_volumes_path(settings),
432447
)
433448

434449

0 commit comments

Comments
 (0)