diff --git a/module_build_service/utils/submit.py b/module_build_service/utils/submit.py index 6822c786..93f62875 100644 --- a/module_build_service/utils/submit.py +++ b/module_build_service/utils/submit.py @@ -32,6 +32,7 @@ from datetime import datetime import kobo.rpmlib import requests +from gi.repository import GLib import module_build_service.scm import module_build_service.resolver @@ -207,6 +208,70 @@ def format_mmd(mmd, scmurl, session=None): mmd.set_xmd(glib.dict_values(xmd)) +def get_prefixed_version(mmd): + """ + Return the prefixed version of the module based on the buildrequired base module stream. + + :param mmd: the Modulemd.Module object to format + :return: the prefixed version + :rtype: int + """ + xmd = mmd.get_xmd() + version = mmd.get_version() + base_module_stream = None + for base_module in conf.base_module_names: + # xmd is a GLib Variant and doesn't support .get() syntax + try: + base_module_stream = xmd['mbs']['buildrequires'].get(base_module, {}).get('stream') + if base_module_stream: + # Break after finding the first base module that is buildrequired + break + except KeyError: + log.warning('The module\'s mmd is missing information in the xmd section') + return version + else: + log.warning('This module does not buildrequire a base module ({0})' + .format(' or '.join(conf.base_module_names))) + return version + + # The platform version (e.g. prefix1.2.0 => 010200) + version_prefix = '' + for char in base_module_stream: + try: + # See if the current character is an integer, signifying the version + # has started + int(char) + version_prefix += char + except ValueError: + # If version_prefix isn't set, then a digit hasn't been encountered + if version_prefix: + # If the character is a period and the version_prefix is set, then + # the loop is still processing the version part of the stream + if char == '.': + version_prefix += '.' + # If the version_prefix is set and the character is not a period or + # digit, then the remainder of the stream is a suffix like "-beta" + else: + break + + # Remove the periods and pad the numbers if necessary + version_prefix = ''.join([section.zfill(2) for section in version_prefix.split('.')]) + + if not version_prefix: + log.warning('The "{0}" stream "{1}" couldn\'t be used to prefix the module\'s ' + 'version'.format(base_module, base_module_stream)) + return version + + # Since the version must be stored as a number, we convert the string back to + # an integer which consequently drops the leading zero if there is one + new_version = int(version_prefix + str(version)) + if new_version > GLib.MAXUINT64: + log.warning('The "{0}" stream "{1}" caused the module\'s version prefix to be ' + 'too long'.format(base_module, base_module_stream)) + return version + return new_version + + def validate_mmd(mmd): """Validate module metadata @@ -397,12 +462,15 @@ def submit_module_build(username, url, mmd, scm, optional_params=None): modules = [] for mmd in mmds: + # Prefix the version of the modulemd based on the platform it buildrequires + version = get_prefixed_version(mmd) + mmd.set_version(version) + version_str = str(version) + log.debug('Checking whether module build already exists: %s.', - ":".join([mmd.get_name(), mmd.get_stream(), - str(mmd.get_version()), mmd.get_context()])) + ":".join([mmd.get_name(), mmd.get_stream(), version_str, mmd.get_context()])) module = models.ModuleBuild.get_build_from_nsvc( - db.session, mmd.get_name(), mmd.get_stream(), str(mmd.get_version()), - mmd.get_context()) + db.session, mmd.get_name(), mmd.get_stream(), version_str, mmd.get_context()) if module: if module.state != models.BUILD_STATES['failed']: err_msg = ('Module (state=%s) already exists. Only a new build or resubmission of ' @@ -438,7 +506,7 @@ def submit_module_build(username, url, mmd, scm, optional_params=None): conf, name=mmd.get_name(), stream=mmd.get_stream(), - version=str(mmd.get_version()), + version=version_str, modulemd=mmd.dumps(), scmurl=url, username=username, @@ -451,7 +519,7 @@ def submit_module_build(username, url, mmd, scm, optional_params=None): db.session.commit() modules.append(module) log.info("%s submitted build of %s, stream=%s, version=%s, context=%s", username, - mmd.get_name(), mmd.get_stream(), mmd.get_version(), mmd.get_context()) + mmd.get_name(), mmd.get_stream(), version_str, mmd.get_context()) return modules diff --git a/tests/test_build/test_build.py b/tests/test_build/test_build.py index 0603d6e0..c626e4f0 100644 --- a/tests/test_build/test_build.py +++ b/tests/test_build/test_build.py @@ -869,7 +869,7 @@ class TestBuild: build_one = models.ModuleBuild() build_one.name = 'testmodule' build_one.stream = 'master' - build_one.version = 20180205135154 + build_one.version = '2820180205135154' build_one.build_context = 'return_runtime_context' build_one.ref_build_context = 'return_runtime_context' build_one.runtime_context = '9c690d0e' @@ -994,7 +994,7 @@ class TestBuild: build_one = models.ModuleBuild() build_one.name = 'testmodule' build_one.stream = 'master' - build_one.version = 20180205135154 + build_one.version = '2820180205135154' build_one.build_context = 'return_runtime_context' build_one.ref_build_context = 'return_runtime_context' build_one.runtime_context = '9c690d0e' diff --git a/tests/test_utils/test_utils.py b/tests/test_utils/test_utils.py index 21ce8744..57c0c6d5 100644 --- a/tests/test_utils/test_utils.py +++ b/tests/test_utils/test_utils.py @@ -29,7 +29,8 @@ import module_build_service.scm from module_build_service import models, conf from module_build_service.errors import ProgrammingError, ValidationError, UnprocessableEntity from tests import ( - reuse_component_init_data, db, reuse_shared_userspace_init_data, clean_database, init_data) + reuse_component_init_data, db, reuse_shared_userspace_init_data, clean_database, init_data, + scheduler_init_data) import mock import koji import pytest @@ -579,6 +580,22 @@ class TestUtils: is_eol = module_build_service.utils.submit._is_eol_in_pdc('mariadb', '10.1') assert is_eol + def test_get_prefixed_version_f28(self): + scheduler_init_data(1) + build_one = models.ModuleBuild.query.get(2) + v = module_build_service.utils.submit.get_prefixed_version(build_one.mmd()) + assert v == 2820180205135154 + + def test_get_prefixed_version_fl701(self): + scheduler_init_data(1) + build_one = models.ModuleBuild.query.get(2) + mmd = build_one.mmd() + xmd = glib.from_variant_dict(mmd.get_xmd()) + xmd['mbs']['buildrequires']['platform']['stream'] = 'fl7.0.1-beta' + mmd.set_xmd(glib.dict_values(xmd)) + v = module_build_service.utils.submit.get_prefixed_version(mmd) + assert v == 7000120180205135154 + class DummyModuleBuilder(GenericBuilder): """ diff --git a/tests/test_views/test_views.py b/tests/test_views/test_views.py index 4788e49f..4fdb9a13 100644 --- a/tests/test_views/test_views.py +++ b/tests/test_views/test_views.py @@ -685,7 +685,7 @@ class TestViews: assert data['name'] == 'testmodule' assert data['scmurl'] == ('git://pkgs.stg.fedoraproject.org/modules/testmodule.git' '?#68931c90de214d9d13feefbd35246a81b6cb8d49') - assert data['version'] == '1' + assert data['version'] == '281' assert data['time_submitted'] is not None assert data['time_modified'] is not None assert data['time_completed'] is None