From 67ee1761bb4744f956e329b8d720963404cdf4b8 Mon Sep 17 00:00:00 2001 From: Emily Zheng Date: Mon, 23 Dec 2024 14:27:28 +0800 Subject: [PATCH] Add additional tag to merged manifest list [CLOUDDST-25217] Merged manifest list had only floating tags on it. Its digest was garbage collected when tags floated. This made workflows which reference image by digest fail to get image. Add additional tag to ensure digest exists. --- src/pubtools/_quay/container_image_pusher.py | 9 +++++++++ tests/test_container_pusher.py | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/pubtools/_quay/container_image_pusher.py b/src/pubtools/_quay/container_image_pusher.py index 4c57d55c..48b2bd58 100644 --- a/src/pubtools/_quay/container_image_pusher.py +++ b/src/pubtools/_quay/container_image_pusher.py @@ -14,6 +14,7 @@ get_internal_container_repo_name, log_step, run_with_retries, + timestamp, ) from .quay_client import QuayClient from .tag_images import tag_images @@ -216,6 +217,14 @@ def run_merge_workflow(self, source_ref: str, dest_refs: List[str]) -> None: merger.set_quay_clients(self.src_quay_client, self.dest_quay_client) merger.merge_manifest_lists() + # add additional tag to merged manifest lists so that they won't be garbage collected + dest_repos = [] + for ref in dest_refs: + repo = ref.split(":")[0] + if repo not in dest_repos: + dest_repos.append(repo) + self.run_tag_images(ref, [f"{ref}-{timestamp()}"], True, self.target_settings) + def copy_multiarch_push_item(self, push_item: Any, source_ml: ManifestList) -> None: """ Evaluate the correct tagging and manifest list merging strategy of multiarch push item. diff --git a/tests/test_container_pusher.py b/tests/test_container_pusher.py index 5bedb292..b4adc457 100644 --- a/tests/test_container_pusher.py +++ b/tests/test_container_pusher.py @@ -180,6 +180,7 @@ def test_copy_v1_item( ) +@mock.patch("pubtools._quay.container_image_pusher.timestamp") @mock.patch("pubtools._quay.container_image_pusher.ManifestListMerger") @mock.patch("pubtools._quay.container_image_pusher.tag_images") @mock.patch("pubtools._quay.container_image_pusher.QuayClient") @@ -187,12 +188,14 @@ def test_merge_workflow( mock_quay_client, mock_tag_images, mock_ml_merger, + mock_timestamp, target_settings, container_multiarch_push_item, ): mock_get_manifest = mock.MagicMock() mock_get_manifest.return_value = {"manifests": [{"digest": "digest1"}, {"digest": "digest2"}]} mock_quay_client.return_value.get_manifest = mock_get_manifest + mock_timestamp.return_value = "timestamp" pusher = container_image_pusher.ContainerImagePusher( [container_multiarch_push_item], target_settings @@ -212,6 +215,10 @@ def test_merge_workflow( "registry/dest1/image@digest2", "registry/dest2/image@digest2", ] + assert mock_tag_images.call_args_list[2][0][0] == "registry/dest1/image:1" + assert mock_tag_images.call_args_list[2][0][1] == ["registry/dest1/image:1-timestamp"] + assert mock_tag_images.call_args_list[3][0][0] == "registry/dest2/image:2" + assert mock_tag_images.call_args_list[3][0][1] == ["registry/dest2/image:2-timestamp"] assert mock_ml_merger.call_args_list == [ mock.call("registry/src/image:1", "registry/dest1/image:1", host="quay.io"),