Support KojiResolver in MBSResolver.

If KojiResolver is enabled for buildrequired base module and
MBSResolver is used, then `MBSResolver.get_buildrequired_modulemds`
will use KojiResolver to get the list of buildrequired module builds.

Otherwise it uses the current behavior.

To implement this, the `KojiResolver.get_buildrequired_modules` was
split into two methods:

- `get_buildrequired_koji_builds` returns buildrequired Koji builds.
- `get_buildrequired_modules` calls `get_buildrequired_koji_builds`
  and finds the corresponding ModuleBuilds in MBS DB.
This commit is contained in:
Jan Kaluza
2019-10-03 14:01:06 +02:00
parent 6e34e50c18
commit 72d2c3daf4
3 changed files with 86 additions and 11 deletions

View File

@@ -59,15 +59,15 @@ class KojiResolver(DBResolver):
return result
def get_buildrequired_modules(self, name, stream, base_module_mmd):
def get_buildrequired_koji_builds(self, name, stream, base_module_mmd):
"""
Returns ModuleBuild objects of all module builds with `name` and `stream` which are tagged
in the Koji tag defined in `base_module_mmd`.
Returns list of Koji build dicts of all module builds with `name` and `stream` which are
tagged in the Koji tag defined in `base_module_mmd`.
:param str name: Name of module to return.
:param str stream: Stream of module to return.
:param Modulemd base_module_mmd: Base module metadata.
:return list: List of ModuleBuilds.
:return list: List of Koji build dicts.
"""
# Get the `koji_tag_with_modules`. If the `koji_tag_with_modules` is not configured for
# the base module, fallback to DBResolver.
@@ -121,6 +121,19 @@ class KojiResolver(DBResolver):
ns_builds, key=lambda x: x["release"].split(".")[0]):
latest_builds += list(nsv_builds)
break
return latest_builds
def get_buildrequired_modules(self, name, stream, base_module_mmd):
"""
Returns ModuleBuild objects of all module builds with `name` and `stream` which are tagged
in the Koji tag defined in `base_module_mmd`.
:param str name: Name of module to return.
:param str stream: Stream of module to return.
:param Modulemd base_module_mmd: Base module metadata.
:return list: List of ModuleBuilds.
"""
latest_builds = self.get_buildrequired_koji_builds(name, stream, base_module_mmd)
# For each latest module build, find the matching ModuleBuild and store it into `ret`.
ret = []
@@ -129,6 +142,7 @@ class KojiResolver(DBResolver):
module = models.ModuleBuild.get_build_from_nsvc(
self.db_session, name, stream, version, context)
if not module:
tag = base_module_mmd.get_xmd().get("mbs", {}).get("koji_tag_with_modules")
raise ValueError(
"Module %s is tagged in the %s Koji tag, but does not exist "
"in MBS DB." % (":".join([name, stream, version, context]), tag))

View File

@@ -8,14 +8,14 @@ import kobo.rpmlib
from module_build_service import conf
from module_build_service import models
from module_build_service.errors import UnprocessableEntity
from module_build_service.resolver.base import GenericResolver
from module_build_service.resolver.KojiResolver import KojiResolver
from module_build_service.utils.general import import_mmd, load_mmd
from module_build_service.utils.request_utils import requests_session
log = logging.getLogger()
class MBSResolver(GenericResolver):
class MBSResolver(KojiResolver):
backend = "mbs"
@@ -234,7 +234,7 @@ class MBSResolver(GenericResolver):
name, stream, stream_version_lte=stream_version_lte, virtual_streams=virtual_streams,
states=states)
def get_buildrequired_modulemds(self, name, stream, base_module_nsvc):
def get_buildrequired_modulemds(self, name, stream, base_module_mmd):
"""
Returns modulemd metadata of all module builds with `name` and `stream` buildrequiring
base module defined by `base_module_nsvc` NSVC.
@@ -252,8 +252,21 @@ class MBSResolver(GenericResolver):
if local_modules:
return [m.mmd() for m in local_modules]
modules = self._get_modules(name, stream, strict=False, base_module_br=base_module_nsvc)
return [load_mmd(module["modulemd"]) for module in modules]
tag = base_module_mmd.get_xmd().get("mbs", {}).get("koji_tag_with_modules")
if tag:
# In case KojiResolver is enabled for this base module, ask Koji for list of
# Koji builds and then get the modulemd file from the MBS running in infra.
koji_builds = self.get_buildrequired_koji_builds(name, stream, base_module_mmd)
ret = []
for build in koji_builds:
version, context = build["release"].split(".")
ret += self.get_module_modulemds(name, stream, version, context, strict=True)
return ret
else:
modules = self._get_modules(
name, stream, strict=False, base_module_br=base_module_mmd.get_nsvc())
return [load_mmd(module["modulemd"]) for module in modules]
def resolve_profiles(self, mmd, keys):
"""

View File

@@ -341,7 +341,8 @@ class TestMBSModule:
request_session.get.return_value = Mock(ok=True)
request_session.get.return_value.json.return_value = {"items": [], "meta": {"next": None}}
result = resolver.get_buildrequired_modulemds("nodejs", "10", "platform:el8:1:00000000")
platform = db_session.query(module_build_service.models.ModuleBuild).filter_by(id=1).one()
result = resolver.get_buildrequired_modulemds("nodejs", "10", platform.mmd())
assert [] == result
@patch("module_build_service.resolver.MBSResolver.requests_session")
@@ -372,7 +373,8 @@ class TestMBSModule:
"meta": {"next": None},
}
result = resolver.get_buildrequired_modulemds("nodejs", "10", "platform:el8:1:00000000")
platform = db_session.query(module_build_service.models.ModuleBuild).filter_by(id=1).one()
result = resolver.get_buildrequired_modulemds("nodejs", "10", platform.mmd())
assert 1 == len(result)
mmd = result[0]
@@ -458,3 +460,49 @@ class TestMBSModule:
assert "master" == mmd.get_stream_name()
assert 20170816080816 == mmd.get_version()
assert "321" == mmd.get_context()
@patch("module_build_service.resolver.MBSResolver.requests_session")
def test_get_buildrequired_modulemds_kojiresolver(self, mock_session, db_session):
"""
Test that MBSResolver uses KojiResolver as input when KojiResolver is enabled for
the base module.
"""
mock_session.get.return_value = Mock(ok=True)
mock_session.get.return_value.json.return_value = {
"items": [
{
"name": "nodejs",
"stream": "10",
"version": 2,
"context": "c1",
"modulemd": mmd_to_str(
tests.make_module("nodejs:10:2:c1"),
),
},
],
"meta": {"next": None},
}
resolver = mbs_resolver.GenericResolver.create(db_session, tests.conf, backend="mbs")
platform = db_session.query(
module_build_service.models.ModuleBuild).filter_by(id=1).one()
platform_mmd = platform.mmd()
platform_xmd = platform_mmd.get_xmd()
platform_xmd["mbs"]["koji_tag_with_modules"] = "module-f29-build"
platform_mmd.set_xmd(platform_xmd)
with patch.object(
resolver, "get_buildrequired_koji_builds") as get_buildrequired_koji_builds:
get_buildrequired_koji_builds.return_value = [{
"build_id": 124, "name": "nodejs", "version": "10",
"release": "2.c1", "tag_name": "foo-test"}]
result = resolver.get_buildrequired_modulemds("nodejs", "10", platform_mmd)
get_buildrequired_koji_builds.assert_called_once()
assert 1 == len(result)
mmd = result[0]
assert "nodejs" == mmd.get_module_name()
assert "10" == mmd.get_stream_name()
assert 2 == mmd.get_version()
assert "c1" == mmd.get_context()