diff --git a/module_build_service/scheduler/submit.py b/module_build_service/scheduler/submit.py index 06c7ee00..4aa4c4d8 100644 --- a/module_build_service/scheduler/submit.py +++ b/module_build_service/scheduler/submit.py @@ -23,13 +23,19 @@ def get_build_arches(mmd, config): :param mmd: Module MetaData :param config: config (module_build_service.common.config.Config instance) - :return list of architectures + :return: list of architectures """ # Imported here to allow import of utils in GenericBuilder. from module_build_service.builder import GenericBuilder nsvc = mmd.get_nsvc() + def _conditional_log(msg, arches, new_arches): + # Checks if the arch list returned by _check_buildopts_arches is the same one passed to it + # If it is, it outputs the message + if arches is new_arches: + log.info(msg) + # At first, handle BASE_MODULE_ARCHES - this overrides any other option. # Find out the base modules in buildrequires section of XMD and # set the Koji tag arches according to it. @@ -38,17 +44,21 @@ def get_build_arches(mmd, config): ns = ":".join([req_name, req_data["stream"]]) if ns in config.base_module_arches: arches = config.base_module_arches[ns] - log.info("Setting build arches of %s to %r based on the BASE_MODULE_ARCHES." % ( - nsvc, arches)) - return arches + new_arches = _check_buildopts_arches(mmd, arches) + msg = "Setting build arches of %s to %r based on the BASE_MODULE_ARCHES." % ( + nsvc, new_arches) + _conditional_log(msg, arches, new_arches) + return new_arches # Check whether the module contains the `koji_tag_arches`. This is used only # by special modules defining the layered products. try: arches = mmd.get_xmd()["mbs"]["koji_tag_arches"] - log.info("Setting build arches of %s to %r based on the koji_tag_arches." % ( - nsvc, arches)) - return arches + new_arches = _check_buildopts_arches(mmd, arches) + msg = "Setting build arches of %s to %r based on the koji_tag_arches." % ( + nsvc, new_arches) + _conditional_log(msg, arches, new_arches) + return new_arches except KeyError: pass @@ -81,13 +91,45 @@ def get_build_arches(mmd, config): continue arches = GenericBuilder.get_module_build_arches(module_obj) if arches: - log.info("Setting build arches of %s to %r based on the buildrequired " - "module %r." % (nsvc, arches, module_obj)) - return arches + new_arches = _check_buildopts_arches(mmd, arches) + msg = "Setting build arches of %s to %r based on the buildrequired module %r." % ( + nsvc, new_arches, module_obj) + _conditional_log(msg, arches, new_arches) + return new_arches # As a last resort, return just the preconfigured list of arches. arches = config.arches - log.info("Setting build arches of %s to %r based on default ARCHES." % (nsvc, arches)) + new_arches = _check_buildopts_arches(mmd, arches) + msg = "Setting build arches of %s to %r based on default ARCHES." % (nsvc, new_arches) + _conditional_log(msg, arches, new_arches) + return new_arches + + +def _check_buildopts_arches(mmd, arches): + """ + Returns buildopts arches if valid, or otherwise the arches provided. + + :param mmd: Module MetaData + :param arches: list of architectures + :return: list of architectures + """ + buildopts = mmd.get_buildopts() + if not buildopts: + return arches + try: + buildopts_arches = buildopts.get_arches() + except AttributeError: + # libmodulemd version < 2.8.3 + return arches + # Must be a subset of the input module arches + unsupported_arches = set(buildopts_arches) - set(arches) + if unsupported_arches: + raise ValidationError("The following buildopts arches are not supported with these " + "buildrequires: %r" % unsupported_arches) + if buildopts_arches: + log.info("Setting build arches of %s to %r based on the buildopts arches." % ( + mmd.get_nsvc(), buildopts_arches)) + return buildopts_arches return arches diff --git a/tests/test_scheduler/test_submit.py b/tests/test_scheduler/test_submit.py index 5127d6bc..2f3b13cb 100644 --- a/tests/test_scheduler/test_submit.py +++ b/tests/test_scheduler/test_submit.py @@ -9,6 +9,7 @@ import pytest from module_build_service import app from module_build_service.common import conf, models from module_build_service.common.errors import UnprocessableEntity +from module_build_service.common.modulemd import Modulemd from module_build_service.common.utils import load_mmd, load_mmd_file, mmd_to_str from module_build_service.scheduler.db_session import db_session import module_build_service.scheduler.handlers.components @@ -76,6 +77,26 @@ class TestSubmit: r = get_build_arches(mmd, conf) assert r == ["x86_64", "i686"] + @mock.patch.object(conf, "base_module_arches", new={"platform:xx": ["x86_64", "i686"]}) + def test_get_build_arches_set_in_mmd(self): + mmd = load_mmd(read_staged_data("formatted_testmodule")) + xmd = mmd.get_xmd() + mbs_options = xmd.get("mbs", {}) + mbs_options["buildrequires"] = {"platform": {"stream": "xx"}} + xmd["mbs"] = mbs_options + mmd.set_xmd(xmd) + try: + opts = Modulemd.Buildopts() + opts.add_arch("x86_64") + mmd.set_buildopts(opts) + expected_result = ["x86_64"] + except AttributeError: + # libmodulemd version < 2.8.3 + expected_result = ["x86_64", "i686"] + + r = get_build_arches(mmd, conf) + assert r == expected_result + @mock.patch("module_build_service.scheduler.submit.get_build_arches") def test_record_module_build_arches(self, get_build_arches): get_build_arches.return_value = ["x86_64", "i686"]