Ejemplo n.º 1
0
    def test_mark_handled_even_if_no_modules_in_ursine_content(
            self, get_modulemds_from_ursine_content):
        xmd = {
            "mbs": {
                "buildrequires": {
                    "modulea": {
                        "stream": "master"
                    },
                    "platform": {
                        "stream": "master",
                        "koji_tag": "module-rhel-8.0-build"
                    },
                }
            }
        }
        fake_mmd = make_module("name1:s:2020:c", xmd=xmd)
        expected_xmd = fake_mmd.get_xmd()

        get_modulemds_from_ursine_content.return_value = []

        with patch.object(ursine, "log") as log:
            ursine.handle_stream_collision_modules(fake_mmd)
            assert 2 == log.info.call_count

        # Ensure stream_collision_modules is set.
        expected_xmd["mbs"]["buildrequires"]["platform"][
            "stream_collision_modules"] = ""
        expected_xmd["mbs"]["buildrequires"]["platform"]["ursine_rpms"] = ""
        assert expected_xmd == fake_mmd.get_xmd()
Ejemplo n.º 2
0
    def test_nothing_changed_if_no_base_module_is_in_buildrequires(
            self, find_stream_collision_modules):
        xmd = {"mbs": {"buildrequires": {"modulea": {"stream": "master"}}}}
        fake_mmd = make_module("name1:s:2020:c", xmd=xmd)
        original_xmd = fake_mmd.get_xmd()

        with patch.object(ursine, "log") as log:
            ursine.handle_stream_collision_modules(fake_mmd)
            assert 2 == log.info.call_count
            find_stream_collision_modules.assert_not_called()

        assert original_xmd == fake_mmd.get_xmd()
Ejemplo n.º 3
0
    def test_add_collision_modules(self, ClientSession, resolver_create,
                                   get_modulemds_from_ursine_content):
        xmd = {
            "mbs": {
                "buildrequires": {
                    "modulea": {
                        "stream": "master"
                    },
                    "foo": {
                        "stream": "1"
                    },
                    "bar": {
                        "stream": "2"
                    },
                    "platform": {
                        "stream": "master",
                        "koji_tag": "module-rhel-8.0-build"
                    },
                    "project-platform": {
                        "stream": "master",
                        "koji_tag": "module-project-1.0-build",
                    },
                }
            }
        }
        fake_mmd = make_module("name1:s:2020:c", xmd=xmd)

        def mock_get_ursine_modulemds(koji_tag):
            if koji_tag == "module-rhel-8.0-build":
                return [
                    # This is the one
                    make_module("modulea:10:20180813041838:5ea3b708"),
                    make_module("moduleb:1.0:20180113042038:6ea3b105"),
                ]
            if koji_tag == "module-project-1.0-build":
                return [
                    # Both of them are the collided modules
                    make_module("bar:6:20181013041838:817fa3a8"),
                    make_module("foo:2:20180113041838:95f078a1"),
                ]

        get_modulemds_from_ursine_content.side_effect = mock_get_ursine_modulemds

        # Mock for finding out built rpms
        def mock_get_module(name, stream, version, context, strict=True):
            return {
                "modulea:10:20180813041838:5ea3b708": {
                    "koji_tag": "module-modulea-10-20180813041838-5ea3b708"
                },
                "bar:6:20181013041838:817fa3a8": {
                    "koji_tag": "module-bar-6-20181013041838-817fa3a8"
                },
                "foo:2:20180113041838:95f078a1": {
                    "koji_tag": "module-foo-2-20180113041838-95f078a1"
                },
            }["{}:{}:{}:{}".format(name, stream, version, context)]

        resolver = resolver_create.return_value
        resolver.get_module.side_effect = mock_get_module

        def mock_listTaggedRPMS(tag, latest):
            return {
                "module-modulea-10-20180813041838-5ea3b708": [[{
                    "name": "pkg1",
                    "version": "1.0",
                    "release": "1.fc28",
                    "epoch": None
                }]],
                "module-bar-6-20181013041838-817fa3a8": [[{
                    "name": "pkg2",
                    "version": "2.0",
                    "release": "1.fc28",
                    "epoch": None
                }]],
                "module-foo-2-20180113041838-95f078a1": [[{
                    "name": "pkg3",
                    "version": "3.0",
                    "release": "1.fc28",
                    "epoch": None
                }]],
            }[tag]

        koji_session = ClientSession.return_value
        koji_session.listTaggedRPMS.side_effect = mock_listTaggedRPMS

        ursine.handle_stream_collision_modules(fake_mmd)

        xmd = fake_mmd.get_xmd()
        buildrequires = xmd["mbs"]["buildrequires"]

        modules = buildrequires["platform"]["stream_collision_modules"]
        assert ["modulea:10:20180813041838:5ea3b708"] == modules
        assert ["pkg1-0:1.0-1.fc28"
                ] == buildrequires["platform"]["ursine_rpms"]

        modules = sorted(
            buildrequires["project-platform"]["stream_collision_modules"])
        expected_modules = [
            "bar:6:20181013041838:817fa3a8", "foo:2:20180113041838:95f078a1"
        ]
        assert expected_modules == modules

        rpms = sorted(buildrequires["project-platform"]["ursine_rpms"])
        assert ["pkg2-0:2.0-1.fc28", "pkg3-0:3.0-1.fc28"] == rpms
Ejemplo n.º 4
0
def init(msg_id, module_build_id, module_build_state):
    """Called whenever a module enters the 'init' state.

    :param str msg_id: the original id of the message being handled, which is
        received from message bus.
    :param int module_build_id: the module build id.
    :param int module_build_state: the module build state.
    """
    build = models.ModuleBuild.get_by_id(db_session, module_build_id)

    state_init = models.BUILD_STATES["init"]
    if module_build_state == state_init and build.state != state_init:
        log.warning("Module build %r has moved to %s state already.", build,
                    models.INVERSE_BUILD_STATES[build.state])
        log.warning(
            "Ignore this message %s. Is there something wrong with the frontend"
            " that sends duplicate messages?", msg_id)
        return

    # for MockModuleBuilder, set build logs dir to mock results dir
    # before build_logs start
    if conf.system == "mock":
        build_tag_name = generate_module_build_koji_tag(build)
        mock_resultsdir = os.path.join(conf.mock_resultsdir, build_tag_name)
        if not os.path.exists(mock_resultsdir):
            os.makedirs(mock_resultsdir)
        build_logs.build_logs_dir = mock_resultsdir

    build_logs.start(db_session, build)
    log.info("Start to handle %s which is in init state.",
             build.mmd().get_nsvc())

    error_msg = ""
    failure_reason = "unspec"
    try:
        mmd = build.mmd()
        record_module_build_arches(mmd, build)
        arches = [arch.name for arch in build.arches]
        defaults_added = add_default_modules(mmd)

        # Get map of packages that have SRPM overrides
        srpm_overrides = get_module_srpm_overrides(build)
        # Format the modulemd by putting in defaults and replacing streams that
        # are branches with commit hashes
        format_mmd(mmd, build.scmurl, build, db_session, srpm_overrides)
        record_component_builds(mmd, build)

        # The ursine.handle_stream_collision_modules is Koji specific.
        # It is also run only when Ursa Prime is not enabled for the base
        # module (`if not defaults_added`).
        if conf.system in ["koji", "test"] and not defaults_added:
            handle_stream_collision_modules(mmd)

        # Sets xmd["mbs"]["ursine_rpms"] with RPMs from the buildrequired base modules which
        # conflict with the RPMs from other buildrequired modules. This is done to prefer modular
        # RPMs over base module RPMs even if their NVR is lower.
        if conf.system in ("koji", "test"):
            handle_collisions_with_base_module_rpms(mmd, arches)
        else:
            log.warning(
                "The necessary conflicts could not be generated due to RHBZ#1693683. "
                "Some RPMs from the base modules (%s) may end up being used over modular RPMs. "
                "This may result in different behavior than a production build.",
                ", ".join(conf.base_module_names))

        mmd = record_filtered_rpms(mmd)
        build.modulemd = mmd_to_str(mmd)
        build.transition(db_session, conf, models.BUILD_STATES["wait"])
    # Catch custom exceptions that we can expose to the user
    except (UnprocessableEntity, Forbidden, ValidationError,
            RuntimeError) as e:
        log.exception(str(e))
        error_msg = str(e)
        failure_reason = "user"
    except (xmlrpclib.ProtocolError, koji.GenericError) as e:
        log.exception(str(e))
        error_msg = 'Koji communication error: "{0}"'.format(str(e))
        failure_reason = "infra"
    except Exception as e:
        log.exception(str(e))
        error_msg = "An unknown error occurred while validating the modulemd"
        failure_reason = "user"
    else:
        db_session.add(build)
        db_session.commit()
    finally:
        if error_msg:
            # Rollback changes underway
            db_session.rollback()
            build.transition(
                db_session,
                conf,
                models.BUILD_STATES["failed"],
                state_reason=error_msg,
                failure_type=failure_reason,
            )
            db_session.commit()