Ejemplo n.º 1
0
    def test_generate_expanded_mmds_static_context(self):
        """
        Tests if generate_expanded_mmds will not change the context of a module if provided
        with a static one.
        """
        module_deps = [{
            "requires": {
                "gtk": ["1"],
                "foo": ["1"]
            },
            "buildrequires": {
                "platform": ["f28"],
                "gtk": ["1"],
                "foo": ["1"]
            },
        }]
        self._generate_default_modules()
        module_build = make_module_in_db("app:1:0:static", module_deps)

        mmds = generate_expanded_mmds(db_session,
                                      module_build.mmd(),
                                      static_context=True)

        assert type(mmds) is list
        assert len(mmds) == 1

        current_context = mmds[0].get_context()

        assert current_context == "static"
Ejemplo n.º 2
0
    def test_generate_expanded_mmds_buildrequires(self, module_deps,
                                                  stream_ambigous,
                                                  expected_xmd,
                                                  expected_buildrequires):
        self._generate_default_modules()
        module_build = make_module_in_db("app:1:0:c1", module_deps)

        # Check that generate_expanded_mmds raises an exception if stream is ambigous
        # and also that it does not raise an exception otherwise.
        if stream_ambigous:
            with pytest.raises(StreamAmbigous):
                generate_expanded_mmds(db_session,
                                       module_build.mmd(),
                                       raise_if_stream_ambigous=True)
        else:
            generate_expanded_mmds(db_session,
                                   module_build.mmd(),
                                   raise_if_stream_ambigous=True)

        # Check that if stream is ambigous and we define the stream, it does not raise
        # an exception.
        if stream_ambigous:
            default_streams = {}
            for ns in list(expected_buildrequires)[0]:
                name, stream = ns.split(":")
                default_streams[name] = stream
            generate_expanded_mmds(
                db_session,
                module_build.mmd(),
                raise_if_stream_ambigous=True,
                default_streams=default_streams,
            )

        mmds = generate_expanded_mmds(db_session, module_build.mmd())

        buildrequires_per_mmd_xmd = set()
        buildrequires_per_mmd_buildrequires = set()
        for mmd in mmds:
            xmd = mmd.get_xmd()
            br_nsvcs = []
            for name, detail in xmd["mbs"]["buildrequires"].items():
                br_nsvcs.append(":".join([
                    name, detail["stream"], detail["version"],
                    detail["context"]
                ]))
            buildrequires_per_mmd_xmd.add(frozenset(br_nsvcs))

            assert len(mmd.get_dependencies()) == 1

            buildrequires = set()
            dep = mmd.get_dependencies()[0]
            for req_name in dep.get_buildtime_modules():
                for req_stream in dep.get_buildtime_streams(req_name):
                    buildrequires.add(":".join([req_name, req_stream]))
            buildrequires_per_mmd_buildrequires.add(frozenset(buildrequires))

        assert buildrequires_per_mmd_xmd == expected_xmd
        assert buildrequires_per_mmd_buildrequires == expected_buildrequires
Ejemplo n.º 3
0
    def test_generate_expanded_mmds_requires(self, module_deps, expected):
        self._generate_default_modules()
        module_build = make_module_in_db("app:1:0:c1", module_deps)
        mmds = generate_expanded_mmds(db_session, module_build.mmd())

        requires_per_mmd = set()
        for mmd in mmds:
            assert len(mmd.get_dependencies()) == 1
            mmd_requires = set()
            dep = mmd.get_dependencies()[0]
            for req_name in dep.get_runtime_modules():
                for req_stream in dep.get_runtime_streams(req_name):
                    mmd_requires.add(":".join([req_name, req_stream]))
            requires_per_mmd.add(frozenset(mmd_requires))

        assert requires_per_mmd == expected
Ejemplo n.º 4
0
 def test_generate_expanded_mmds_context(self):
     self._generate_default_modules()
     module_build = make_module_in_db(
         "app:1:0:c1",
         [{
             "requires": {
                 "gtk": ["1", "2"]
             },
             "buildrequires": {
                 "platform": ["f28"],
                 "gtk": ["1", "2"]
             },
         }],
     )
     mmds = generate_expanded_mmds(db_session, module_build.mmd())
     contexts = {mmd.get_context() for mmd in mmds}
     assert {"e1e005fb", "ce132a1e"} == contexts
Ejemplo n.º 5
0
def submit_module_build(db_session, username, mmd, params):
    """
    Submits new module build.

    :param db_session: SQLAlchemy session object.
    :param str username: Username of the build's owner.
    :param Modulemd.ModuleStream mmd: Modulemd defining the build.
    :param dict params: the API parameters passed in by the user
    :rtype: list with ModuleBuild
    :return: List with submitted module builds.
    """
    log.debug(
        "Submitted %s module build for %s:%s:%s",
        ("scratch" if params.get("scratch", False) else "normal"),
        mmd.get_module_name(),
        mmd.get_stream_name(),
        mmd.get_version(),
    )

    raise_if_stream_ambigous = False
    default_streams = {}
    # For local builds, we want the user to choose the exact stream using the default_streams
    # in case there are multiple streams to choose from and raise an exception otherwise.
    if "local_build" in params:
        raise_if_stream_ambigous = True
    # Get the default_streams if set.
    if "default_streams" in params:
        default_streams = params["default_streams"]

    xmd = mmd.get_xmd()
    # we check if static contexts are enabled by the `contexts` property defined by the user i
    # as an build option.
    static_context = "mbs_options" in xmd and "contexts" in xmd["mbs_options"]
    input_mmds = generate_mmds_from_static_contexts(mmd) if static_context else [mmd]

    mmds = []
    for mmd in input_mmds:
        validate_mmd(mmd)
        _apply_dep_overrides(mmd, params)
        _modify_buildtime_streams(db_session, mmd, resolve_base_module_virtual_streams)
        _process_support_streams(db_session, mmd, params)
        mmds += generate_expanded_mmds(db_session, mmd, raise_if_stream_ambigous,
                                       default_streams, static_context=static_context)

    if not mmds:
        raise ValidationError(
            "No dependency combination was satisfied. Please verify the "
            "buildrequires in your modulemd have previously been built."
        )
    modules = []

    # True if all module builds are skipped so MBS will actually not rebuild
    # anything. To keep the backward compatibility, we need to raise an exception
    # later in the end of this method.
    all_modules_skipped = True

    for mmd in mmds:
        # Prefix the version of the modulemd based on the base module it buildrequires
        version = get_prefixed_version(mmd)
        mmd.set_version(version)
        nsvc = mmd.get_nsvc()

        log.debug("Checking whether module build already exists: %s.", nsvc)
        module = models.ModuleBuild.get_build_from_nsvc(db_session, *nsvc.split(":"))
        if module and not params.get("scratch", False):
            if module.state != models.BUILD_STATES["failed"]:
                log.info(
                    "Skipping rebuild of %s, only rebuild of modules in failed state is allowed.",
                    nsvc,
                )
                modules.append(module)
                continue

            rebuild_strategy = params.get("rebuild_strategy")
            if rebuild_strategy and module.rebuild_strategy != rebuild_strategy:
                raise ValidationError(
                    'You cannot change the module\'s "rebuild_strategy" when '
                    "resuming a module build"
                )

            log.debug("Resuming existing module build %r" % module)
            # Reset all component builds that didn't complete
            for component in module.component_builds:
                if not component.is_waiting_for_build and not component.is_completed:
                    component.state = None
                    component.state_reason = None
                    db_session.add(component)
            module.username = username
            prev_state = module.previous_non_failed_state
            if prev_state == models.BUILD_STATES["init"]:
                transition_to = models.BUILD_STATES["init"]
            else:
                transition_to = models.BUILD_STATES["wait"]
                module.batch = 0
            module.transition(db_session, conf, transition_to, "Resubmitted by %s" % username)
            db_session.commit()
            log.info("Resumed existing module build in previous state %s" % module.state)
        else:
            # make NSVC unique for every scratch build
            context_suffix = ""
            if params.get("scratch", False):
                log.debug("Checking for existing scratch module builds by NSVC")
                scrmods = models.ModuleBuild.get_scratch_builds_from_nsvc(
                    db_session, *nsvc.split(":"))
                scrmod_contexts = [scrmod.context for scrmod in scrmods]
                log.debug(
                    "Found %d previous scratch module build context(s): %s",
                    len(scrmods), ",".join(scrmod_contexts),
                )
                # append incrementing counter to context
                context_suffix = "_" + str(len(scrmods) + 1)
                mmd.set_context(mmd.get_context() + context_suffix)
            else:
                # In case the branch is defined, check whether user is allowed to submit
                # non-scratch build from this branch. Note that the branch is always defined
                # for official builds from SCM, because it is requested in views.py.
                branch = params.get("branch")
                if branch:
                    for regex in conf.scratch_build_only_branches:
                        branch_search = re.search(regex, branch)
                        if branch_search:
                            raise ValidationError(
                                "Only scratch module builds can be built from this branch."
                            )

            log.debug("Creating new module build")
            module = models.ModuleBuild.create(
                db_session,
                conf,
                name=mmd.get_module_name(),
                stream=mmd.get_stream_name(),
                version=str(mmd.get_version()),
                modulemd=mmd_to_str(mmd),
                scmurl=params.get("scmurl"),
                username=username,
                rebuild_strategy=params.get("rebuild_strategy"),
                reused_module_id=params.get("reuse_components_from"),
                scratch=params.get("scratch"),
                srpms=params.get("srpms"),
            )
            module.build_context, module.runtime_context, module.context, \
                module.build_context_no_bms = module.contexts_from_mmd(module.modulemd)

            xmd = mmd.get_xmd()
            if xmd["mbs"].get("static_context"):
                module.context = mmd.get_context()

            module.context += context_suffix
            db_session.commit()

            notify_on_module_state_change(
                # Note the state is "init" here...
                module.json(db_session, show_tasks=False)
            )

        all_modules_skipped = False
        modules.append(module)
        log.info('The user "%s" submitted the build "%s"', username, nsvc)

    if all_modules_skipped:
        err_msg = (
            "Module (state=%s) already exists. Only a new build, resubmission of "
            "a failed build or build against new buildrequirements is "
            "allowed." % module.state
        )
        log.error(err_msg)
        raise Conflict(err_msg)

    return modules