From 27a612059ea36e9d9f6a95104425ad22921cde92 Mon Sep 17 00:00:00 2001 From: yuqei Date: Sun, 27 Sep 2026 14:43:37 +0800 Subject: [PATCH] fix(release): bind backup runtime image identity --- yuqei-infra/backup/run-production-backup.py | 24 +++++++++++++------ .../tests/test_production_release_tools.py | 6 +++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/yuqei-infra/backup/run-production-backup.py b/yuqei-infra/backup/run-production-backup.py index d80eb763..fedbae8a 100644 --- a/yuqei-infra/backup/run-production-backup.py +++ b/yuqei-infra/backup/run-production-backup.py @@ -599,19 +599,29 @@ def _inspect_object_storage_runtime( ).stdout.decode("utf-8", errors="strict").strip() if not re.fullmatch(r"[0-9a-f]{12,64}", container): raise RuntimeError("Running object-storage container identity is invalid.") - runtime = _run( + engine_runtime_image = _run( [ "docker", "inspect", "--format", - "{{.Config.Image}}\n{{.Image}}", + "{{.Config.Image}}", container, ], stdout=subprocess.PIPE, - ).stdout.decode("utf-8", errors="strict").splitlines() - if len(runtime) != 2 or runtime[0] != values["MINIO_IMAGE"]: + ).stdout.decode("utf-8", errors="strict").strip() + if engine_runtime_image != values["MINIO_IMAGE"]: raise RuntimeError("Running object-storage image differs from MINIO_IMAGE.") - if not IMAGE_ID_PATTERN.fullmatch(runtime[1]): + engine_resolved_image_id = _run( + [ + "docker", + "inspect", + "--format", + "{{.Image}}", + container, + ], + stdout=subprocess.PIPE, + ).stdout.decode("utf-8", errors="strict").strip() + if not IMAGE_ID_PATTERN.fullmatch(engine_resolved_image_id): raise RuntimeError("Running object-storage image ID is invalid.") client_image_id = _run( [ @@ -627,8 +637,8 @@ def _inspect_object_storage_runtime( if not IMAGE_ID_PATTERN.fullmatch(client_image_id): raise RuntimeError("Object-storage backup client image ID is invalid.") return { - "engine_runtime_image": runtime[0], - "engine_resolved_image_id": runtime[1], + "engine_runtime_image": engine_runtime_image, + "engine_resolved_image_id": engine_resolved_image_id, "client_resolved_image_id": client_image_id, } diff --git a/yuqei-infra/tests/test_production_release_tools.py b/yuqei-infra/tests/test_production_release_tools.py index 9158bc1d..58d4a040 100644 --- a/yuqei-infra/tests/test_production_release_tools.py +++ b/yuqei-infra/tests/test_production_release_tools.py @@ -829,7 +829,8 @@ def test_object_storage_runtime_identity_is_bound_to_running_and_client_images( outputs = iter( ( b"a" * 64 + b"\n", - values["MINIO_IMAGE"].encode("utf-8") + b"\nsha256:" + b"b" * 64 + b"\n", + values["MINIO_IMAGE"].encode("utf-8") + b"\n", + b"sha256:" + b"b" * 64 + b"\n", b"sha256:" + b"c" * 64 + b"\n", ) ) @@ -851,7 +852,8 @@ def test_object_storage_runtime_identity_is_bound_to_running_and_client_images( "client_resolved_image_id": "sha256:" + "c" * 64, } assert commands[1][:3] == ["docker", "inspect", "--format"] - assert commands[2][:3] == ["docker", "image", "inspect"] + assert commands[2][:3] == ["docker", "inspect", "--format"] + assert commands[3][:3] == ["docker", "image", "inspect"] @pytest.mark.parametrize("field", ("backup_id", "created_at", "release_id", "images"))