From 91f63bcc4e28eadfbe73944f0823e6bad29ca15d Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: May 30 2019 13:30:05 +0000 Subject: Do not mark Beta or Tech Preview images as "latest_released". In case when images with the same name-version but different release appears in the Lightblue result, the deduplication code will choose the latest_released image and replaces the images with lower Release with the one which is marked as latest_released. For example if there is "app" container with "foo-1-1" parent, but latest release of foo is "foo-1-2", the "app" container will be rebuilt against "foo-1-2". This is here, because we cannot release multiple versions of "foo", so we need to use just single one. Before this commit, even Beta or Tech Preview images were marked as "latest_released". That means the "app" could be upgraded from Generally Available image to Beta images which is wrong. In this commit, we do not mark Beta and Tech Preview images as "latest_released" which prevents the deduplication code to use them as a replacement for "app" parent image in our example. --- diff --git a/freshmaker/lightblue.py b/freshmaker/lightblue.py index 0f2b8f3..c8bd25c 100644 --- a/freshmaker/lightblue.py +++ b/freshmaker/lightblue.py @@ -727,6 +727,7 @@ class LightBlue(object): "projection": [ {"field": "repository", "include": True}, {"field": "auto_rebuild_tags", "include": True, "recursive": True}, + {"field": "release_categories", "include": True, "recursive": True}, ] } repo_request = self._set_container_repository_filters( @@ -925,8 +926,10 @@ class LightBlue(object): continue published_repo = repositories[repository["repository"]] tag_names = [tag["name"] for tag in repository["tags"]] + for auto_rebuild_tag in published_repo["auto_rebuild_tags"]: if auto_rebuild_tag in tag_names: + image["release_categories"] = published_repo["release_categories"] new_images.append(image) break images = new_images @@ -1285,9 +1288,14 @@ class LightBlue(object): # We do not set "children" here in resolve_content_sets call, because # published images should have the content_set set. image.resolve(self, None) - # Images returned by this method are latest released images, so - # mark them like that. - image["latest_released"] = True + + # Mark as latest_released only images which are not Beta or Tech Preview. + # This is important, because "latest_released" is used in deduplication + # code to mark the image to which the other images with same name-version + # but lower release can be upgraded. + release_categories = image.get("release_categories", []) + if "Beta" not in release_categories and "Tech Preview" not in release_categories: + image["latest_released"] = True return image resolved_images = [] diff --git a/tests/test_lightblue.py b/tests/test_lightblue.py index d47f34a..5e38f69 100644 --- a/tests/test_lightblue.py +++ b/tests/test_lightblue.py @@ -609,11 +609,13 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase): "content_sets": ["dummy-content-set-1", "dummy-content-set-2"], "auto_rebuild_tags": ["latest", "tag1"], + "release_categories": ["Generally Available"], }, { "repository": "product2/repo2", "content_sets": ["dummy-content-set-1"], "auto_rebuild_tags": ["latest", "tag2"], + "release_categories": ["Generally Available"], } ] @@ -933,6 +935,7 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase): "projection": [ {"field": "repository", "include": True}, {"field": "auto_rebuild_tags", "include": True, "recursive": True}, + {"field": "release_categories", "include": True, "recursive": True}, ] } cont_repos.assert_called_with(expected_repo_request) @@ -1133,6 +1136,7 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase): }, 'content_sets': ["dummy-content-set-1"], 'content_sets_source': 'lightblue_container_image', + "release_categories": ["Generally Available"], 'repositories': [ {'repository': 'product2/repo2', 'published': True, 'tags': [{"name": "latest"}]} @@ -1166,6 +1170,33 @@ class TestQueryEntityFromLightBlue(helpers.FreshmakerTestCase): }, ]) + @patch('freshmaker.lightblue.LightBlue.find_container_repositories') + @patch('freshmaker.lightblue.LightBlue.find_container_images') + @patch('freshmaker.kojiservice.KojiService.get_build') + @patch('freshmaker.kojiservice.KojiService.get_task_request') + @patch('os.path.exists') + def test_images_with_content_set_packages_beta( + self, exists, koji_task_request, koji_get_build, cont_images, cont_repos): + exists.return_value = True + cont_repos.return_value = self.fake_repositories_with_content_sets + cont_repos.return_value[1]["release_categories"] = ["Beta"] + cont_images.return_value = self.fake_container_images + koji_task_request.side_effect = self.fake_koji_task_requests + koji_get_build.side_effect = self.fake_koji_builds + + lb = LightBlue(server_url=self.fake_server_url, + cert=self.fake_cert_file, + private_key=self.fake_private_key) + ret = lb.find_images_with_packages_from_content_set( + set(["openssl-1.2.3-3"]), ["dummy-content-set-1"], filter_fnc=self._filter_fnc) + + # Only the first image should be returned, because the first one + # is in repository "product1/repo1", but we have asked for images + # in repository "product/repo1". + self.assertEqual(1, len(ret)) + self.assertTrue("latest_released" not in ret[0]) + self.assertEqual(ret[0]["release_categories"], ["Beta"]) + @patch('freshmaker.lightblue.ContainerImage.resolve_published') @patch('freshmaker.lightblue.LightBlue.find_container_images') @patch('os.path.exists')