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
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)
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