From 427f71702a6be486c4733b718fd906605be6be10 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Jan 30 2019 09:02:26 +0000 Subject: Store Bob builds as new ArtifactBuildType IMAGE_REPOSITORY and handle Bob response. The artifacts we pass to Bob are not really particular container images, but they are the names of the container image repositories. Bob then finds out the latest image in the repository and rebuilds it. Therefore we should have new ArtifactBuildType for them - IMAGE_REPOSITORY. This will also fix issues with Botas handling Bob events, because Botas would think the IMAGE artifacts are real images and try to create advisories for them. In this commit, Freshmaker also handles the Bob response with list of 'impacted' container repositories and store the repositories into the database, so they can appear in the API and in the future in Estuary. --- diff --git a/freshmaker/handlers/bob/rebuild_images_on_image_advisory_change.py b/freshmaker/handlers/bob/rebuild_images_on_image_advisory_change.py index c9f72f1..4b63830 100644 --- a/freshmaker/handlers/bob/rebuild_images_on_image_advisory_change.py +++ b/freshmaker/handlers/bob/rebuild_images_on_image_advisory_change.py @@ -104,11 +104,8 @@ class RebuildImagesOnImageAdvisoryChange(ContainerBuildHandler): for repo_name in docker_repos.keys(): self.log_info("Requesting Bob rebuild of %s", repo_name) - # TODO: The Bob API does not return any useful data, so just mark - # the rebuild as "DONE". If there will be some state sent by - # the API, we could set the build state according to it. - self.record_build( - db_event, repo_name, ArtifactType.IMAGE, + parent_build = self.record_build( + db_event, repo_name, ArtifactType.IMAGE_REPOSITORY, state=ArtifactBuildState.DONE.value) bob_url = "%s/update_children/%s" % ( @@ -120,11 +117,13 @@ class RebuildImagesOnImageAdvisoryChange(ContainerBuildHandler): r = requests.get(bob_url, headers=headers) r.raise_for_status() - # TODO: Once the Bob API is clear here, we can handle the response, - # but for now just log it. This should also be changed to log_debug - # once we are in production, but for now log_info makes debugging - # this new code easier. - self.log_info("Response: %r", r.json()) + resp = r.json() + self.log_info("Response: %r", resp) + if "impacted" in resp: + for external_repo_name in resp["impacted"]: + self.record_build( + db_event, external_repo_name, ArtifactType.IMAGE_REPOSITORY, + state=ArtifactBuildState.DONE.value, dep_on=parent_build) db_event.transition(EventState.COMPLETE) db.session.commit() diff --git a/freshmaker/types.py b/freshmaker/types.py index 918add1..d3e041d 100644 --- a/freshmaker/types.py +++ b/freshmaker/types.py @@ -32,6 +32,7 @@ class ArtifactType(Enum): RPM = 0 IMAGE = 1 MODULE = 2 + IMAGE_REPOSITORY = 3 class ArtifactBuildState(Enum): diff --git a/tests/handlers/bob/test_rebuild_images_on_image_advisory_change.py b/tests/handlers/bob/test_rebuild_images_on_image_advisory_change.py index b2707c0..7f3b89a 100644 --- a/tests/handlers/bob/test_rebuild_images_on_image_advisory_change.py +++ b/tests/handlers/bob/test_rebuild_images_on_image_advisory_change.py @@ -20,7 +20,7 @@ # # Written by Jan Kaluza -from mock import patch +from mock import patch, MagicMock import freshmaker from freshmaker.errata import ErrataAdvisory @@ -96,6 +96,17 @@ class RebuildImagesOnImageAdvisoryChangeTest(helpers.ModelsTestCase): 'bar-container-1-1': {'bar-526': ['5.26', 'latest']}} get_docker_repository_name.side_effect = [ "scl/foo-526", "scl/bar-526"] + + resp1 = MagicMock() + resp1.json.return_value = { + "message": "Foobar", + "impacted": ["bob/repo1", "bob/repo2"]} + resp2 = MagicMock() + resp2.json.return_value = { + "message": "Foobar", + "impacted": ["bob/repo3", "bob/repo4"]} + requests_get.side_effect = [resp1, resp2] + self.handler.rebuild_images_depending_on_advisory(self.db_event, 123) get_docker_repo_tags.assert_called_once_with(123) @@ -108,10 +119,19 @@ class RebuildImagesOnImageAdvisoryChangeTest(helpers.ModelsTestCase): 'http://localhost/update_children/scl/bar-526', headers={'Authorization': 'Bearer x'}) + db.session.refresh(self.db_event) + self.assertEqual(self.db_event.state, models.EventState.COMPLETE.value) builds = set([b.name for b in self.db_event.builds]) - self.assertEqual(builds, set(['scl/foo-526', 'scl/bar-526'])) + self.assertEqual(builds, set(['scl/foo-526', 'scl/bar-526', + 'bob/repo1', 'bob/repo2', + 'bob/repo3', 'bob/repo4'])) + for build in self.db_event.builds: + if build in ['bob/repo1', 'bob/repo2']: + self.assertEqual(build.dep_on.name == "scl/foo-526") + elif build in ['bob/repo3', 'bob/repo4']: + self.assertEqual(build.dep_on.name == "scl/bar-526") @patch("freshmaker.errata.Errata.get_docker_repo_tags") @patch("freshmaker.pulp.Pulp.get_docker_repository_name")