From db70560d2d9062017d642ef20f7fae19d3a4480a Mon Sep 17 00:00:00 2001 From: Brendan Reilly Date: Mon, 15 Jun 2020 14:55:57 -0400 Subject: [PATCH] Add API call to get final modulemds of builds --- .../builder/KojiContentGenerator.py | 11 ++++++++ module_build_service/web/views.py | 28 +++++++++++++++++++ tests/test_builder/test_content_generator.py | 10 +++++++ tests/test_web/test_views.py | 15 ++++++++++ 4 files changed, 64 insertions(+) diff --git a/module_build_service/builder/KojiContentGenerator.py b/module_build_service/builder/KojiContentGenerator.py index d7f65dd7..5477d8a3 100644 --- a/module_build_service/builder/KojiContentGenerator.py +++ b/module_build_service/builder/KojiContentGenerator.py @@ -843,6 +843,17 @@ class KojiContentGenerator(object): self.rpms = self._koji_rpms_in_tag(self.module.koji_tag) self.rpms_dict = {kobo.rpmlib.make_nvra(rpm, force_epoch=True): rpm for rpm in self.rpms} + def get_final_mmds(self): + # Returns dict of finalized mmds. Used to generate final modulemd files for scratch builds. + session = get_session(self.config) + self._load_koji_tag(session) + + finalmmds = {} + for arch in self.arches: + finalmmds[arch] = self._finalize_mmd(arch) + + return finalmmds + def koji_import(self, devel=False): """This method imports given module into the configured koji instance as a content generator based build diff --git a/module_build_service/web/views.py b/module_build_service/web/views.py index d5ab4d42..30a66f06 100644 --- a/module_build_service/web/views.py +++ b/module_build_service/web/views.py @@ -81,6 +81,10 @@ api_routes = { "url": "/module-build-service//component-builds//messages", "options": {"methods": ["GET"], "defaults": {"model": models.ComponentBuild}}, }, + "final_modulemd": { + "url": "/module-build-service//final-modulemd/", + "options": {"methods": ["GET"]}, + }, } @@ -340,6 +344,27 @@ class LogMessageAPI(MethodView): return jsonify(json_data), 200 +class FinalModulemdAPI(MethodView): + + @validate_api_version() + def get(self, api_version, id): + + module = models.ModuleBuild.get_by_id(db.session, id) + if not module: + raise ValidationError("The module could not be found") + + if conf.system == "koji": + # We are importing KojiContentGenerator here so we can generate the final modulemds. + # If we imported this regularly we would have gotten a circular import error. + from module_build_service.builder.KojiContentGenerator import KojiContentGenerator # noqa + cg = KojiContentGenerator(module, conf) + finalmmds = cg.get_final_mmds() + else: + raise ValidationError("Configured builder not able to generate final modulemds!") + + return jsonify(finalmmds), 200 + + class BaseHandler(object): valid_params = { "branch", @@ -559,6 +584,7 @@ def register_api(): rebuild_strategies_view = RebuildStrategies.as_view("rebuild_strategies") import_module = ImportModuleAPI.as_view("import_module") log_message = LogMessageAPI.as_view("log_messages") + final_modulemd = FinalModulemdAPI.as_view("final_modulemd") for key, val in api_routes.items(): if key.startswith("component_build"): app.add_url_rule(val["url"], endpoint=key, view_func=component_view, **val["options"]) @@ -574,6 +600,8 @@ def register_api(): app.add_url_rule(val["url"], endpoint=key, view_func=import_module, **val["options"]) elif key.startswith("log_message"): app.add_url_rule(val["url"], endpoint=key, view_func=log_message, **val["options"]) + elif key.startswith("final_modulemd"): + app.add_url_rule(val["url"], endpoint=key, view_func=final_modulemd, **val["options"]) else: raise NotImplementedError("Unhandled api key.") diff --git a/tests/test_builder/test_content_generator.py b/tests/test_builder/test_content_generator.py index de29407f..fe476c34 100644 --- a/tests/test_builder/test_content_generator.py +++ b/tests/test_builder/test_content_generator.py @@ -1161,3 +1161,13 @@ class TestBuild: mmd = self.cg._fill_in_rpms_list(mmd, "x86_64") assert set(mmd.get_rpm_artifacts()) == set() + + @patch("koji.ClientSession") + @patch("module_build_service.builder.KojiContentGenerator.KojiContentGenerator._load_koji_tag") + @patch("module_build_service.builder.KojiContentGenerator.KojiContentGenerator._finalize_mmd") + def test_get_final_mmds(self, finalize_mmd, tag_loader, ClientSession): + finalize_mmd.return_value = {"x86_64": "finalized mmd"} + self.cg.arches = ["x86_64"] + self.cg.get_final_mmds() + tag_loader.assert_called() + finalize_mmd.assert_called() diff --git a/tests/test_web/test_views.py b/tests/test_web/test_views.py index 2254b38a..e64f9c8d 100644 --- a/tests/test_web/test_views.py +++ b/tests/test_web/test_views.py @@ -2945,3 +2945,18 @@ class TestLogMessageViews: assert "Build-1" not in json_res assert "Build-2" not in json_res assert "Component-1" in json_res + + +@pytest.mark.usefixtures("provide_test_client") +@pytest.mark.usefixtures("provide_test_data") +class TestFinalModulemdViews: + + @patch("module_build_service.builder.KojiContentGenerator.KojiContentGenerator.get_final_mmds") + def test_view_final_modulemd(self, mocked_cg): + mocked_cg.return_value = {'x86_64': 'finalized mmd'} + url = "/module-build-service/1/final-modulemd/2" + res = self.client.get(url) + json_res = str(res.data) + + assert "x86_64" in json_res + assert "finalized mmd" in json_res