예제 #1
0
    def post(self, api_version):
        # disable this API endpoint if no groups are defined
        if not conf.allowed_groups_to_import_module:
            log.error(
                "Import module API is disabled. Set 'ALLOWED_GROUPS_TO_IMPORT_MODULE'"
                " configuration value first.")
            raise Forbidden("Import module API is disabled.")

        # auth checks
        username, groups = module_build_service.web.auth.get_user(request)
        ModuleBuildAPI.check_groups(
            username,
            groups,
            allowed_groups=conf.allowed_groups_to_import_module)

        # process request using SCM handler
        handler = SCMHandler(request)
        handler.validate(skip_branch=True, skip_optional_params=True)

        mmd, _ = fetch_mmd(handler.data["scmurl"], mandatory_checks=False)
        build, messages = import_mmd(db.session, mmd)
        json_data = {
            "module": build.json(db.session, show_tasks=False),
            "messages": messages
        }

        # return 201 Created if we reach this point
        return jsonify(json_data), 201
예제 #2
0
def submit_module_build_from_scm(db_session, username, params, allow_local_url=False):
    url = params["scmurl"]
    branch = params["branch"]
    # Translate local paths into file:// URL
    if allow_local_url and not _url_check_re.match(url):
        log.info("'{}' is not a valid URL, assuming local path".format(url))
        url = os.path.abspath(url)
        url = "file://" + url
    mmd, scm = fetch_mmd(url, branch, allow_local_url)

    return submit_module_build(db_session, username, mmd, params)
예제 #3
0
def record_component_builds(mmd,
                            module,
                            initial_batch=1,
                            previous_buildorder=None,
                            main_mmd=None):
    # Imported here to allow import of utils in GenericBuilder.
    from module_build_service.builder import GenericBuilder

    # When main_mmd is set, merge the metadata from this mmd to main_mmd,
    # otherwise our current mmd is main_mmd.
    if main_mmd:
        # Check for components that are in both MMDs before merging since MBS
        # currently can't handle that situation.
        main_mmd_rpms = main_mmd.get_rpm_component_names()
        mmd_rpms = mmd.get_rpm_component_names()
        duplicate_components = [
            rpm for rpm in main_mmd_rpms if rpm in mmd_rpms
        ]
        if duplicate_components:
            error_msg = (
                'The included module "{0}" in "{1}" have the following '
                "conflicting components: {2}".format(
                    mmd.get_module_name(), main_mmd.get_module_name(),
                    ", ".join(duplicate_components)))
            raise UnprocessableEntity(error_msg)
        merge_included_mmd(main_mmd, mmd)
    else:
        main_mmd = mmd

    # If the modulemd yaml specifies components, then submit them for build
    rpm_components = [
        mmd.get_rpm_component(name) for name in mmd.get_rpm_component_names()
    ]
    module_components = [
        mmd.get_module_component(name)
        for name in mmd.get_module_component_names()
    ]
    all_components = list(rpm_components) + list(module_components)
    if not all_components:
        return

    # Get map of packages that have SRPM overrides
    srpm_overrides = get_module_srpm_overrides(module)

    rpm_weights = GenericBuilder.get_build_weights(
        [c.get_name() for c in rpm_components])
    all_components.sort(key=lambda x: x.get_buildorder())
    # We do not start with batch = 0 here, because the first batch is
    # reserved for module-build-macros. First real components must be
    # planned for batch 2 and following.
    batch = initial_batch

    for component in all_components:
        # Increment the batch number when buildorder increases.
        if previous_buildorder != component.get_buildorder():
            previous_buildorder = component.get_buildorder()
            batch += 1

        # If the component is another module, we fetch its modulemd file
        # and record its components recursively with the initial_batch
        # set to our current batch, so the components of this module
        # are built in the right global order.
        if isinstance(component, Modulemd.ComponentModule):
            full_url = component.get_repository() + "?#" + component.get_ref()
            # It is OK to whitelist all URLs here, because the validity
            # of every URL have been already checked in format_mmd(...).
            included_mmd = fetch_mmd(full_url, whitelist_url=True)[0]
            format_mmd(included_mmd, module.scmurl, module, db_session,
                       srpm_overrides)
            batch = record_component_builds(included_mmd, module, batch,
                                            previous_buildorder, main_mmd)
            continue

        package = component.get_name()
        if package in srpm_overrides:
            component_ref = None
            full_url = srpm_overrides[package]
            log.info('Building custom SRPM "{0}"'
                     " for package {1}".format(full_url, package))
        else:
            component_ref = mmd.get_xmd()["mbs"]["rpms"][package]["ref"]
            full_url = component.get_repository() + "?#" + component_ref

        # Skip the ComponentBuild if it already exists in database. This can happen
        # in case of module build resubmition.
        existing_build = models.ComponentBuild.from_component_name(
            db_session, package, module.id)
        if existing_build:
            # Check that the existing build has the same most important attributes.
            # This should never be a problem, but it's good to be defensive here so
            # we do not mess things during resubmition.
            if (existing_build.batch != batch
                    or existing_build.scmurl != full_url
                    or existing_build.ref != component_ref):
                raise ValidationError(
                    "Component build %s of module build %s (id: %d) already "
                    "exists in database, but its attributes are different from"
                    " resubmitted one." %
                    (component.get_name(), module.name, module.id))
            continue

        build = models.ComponentBuild(module_id=module.id,
                                      package=package,
                                      format="rpms",
                                      scmurl=full_url,
                                      batch=batch,
                                      ref=component_ref,
                                      weight=rpm_weights[package],
                                      buildonly=component.get_buildonly())
        db_session.add(build)

    return batch