diff --git a/apollo/server/routes/api_updateinfo.py b/apollo/server/routes/api_updateinfo.py index fd03d89..2844005 100644 --- a/apollo/server/routes/api_updateinfo.py +++ b/apollo/server/routes/api_updateinfo.py @@ -156,13 +156,12 @@ async def get_updateinfo( # Add packages packages = ET.SubElement(update, "pkglist") - # Create collection - collection = ET.SubElement(packages, "collection") - collection_short = slugify(f"{product_name}-{repo}-rpms") - collection.set("short", collection_short) - - # Set short to name as well - ET.SubElement(collection, "name").text = collection_short + suffixes_to_skip = [ + "-debuginfo", + "-debugsource", + "-debuginfo-common", + "-debugsource-common", + ] pkg_name_map = {} for pkg in advisory.packages: @@ -174,86 +173,124 @@ async def get_updateinfo( pkg_src_rpm = {} for top_pkg in advisory.packages: if top_pkg.package_name not in pkg_src_rpm: - top_nvra_no_epoch = EPOCH_RE.sub("", top_pkg.nevra) - top_nvra = NVRA_RE.search(top_nvra_no_epoch) - top_arch = top_nvra.group(4) - for pkg in pkg_name_map[top_pkg.package_name]: nvra_no_epoch = EPOCH_RE.sub("", pkg.nevra) nvra = NVRA_RE.search(nvra_no_epoch) if nvra: name = nvra.group(1) arch = nvra.group(4) - if pkg.package_name == name and top_arch == arch: + if pkg.package_name == name and arch == "src": src_rpm = nvra_no_epoch if not src_rpm.endswith(".rpm"): src_rpm += ".rpm" pkg_src_rpm[pkg.package_name] = src_rpm - # If we encounter modules, we need to add them to the collection later - modules = {} + # Collection list, may be more than one if module RPMs are involved + collections = {} + no_default_collection = False + default_collection_short = slugify(f"{product_name}-{repo}-rpms") + # Check if this is an actual module advisory, if so we need to split the + # collections, and module RPMs need to go into their own collection based on + # module name, while non-module RPMs go into the main collection (if any) for pkg in advisory.packages: - if pkg.nevra.endswith(".src.rpm"): - continue - - name = pkg.package_name - epoch = "0" - if NEVRA_RE.match(pkg.nevra): - nevra = NEVRA_RE.search(pkg.nevra) - name = nevra.group(1) - epoch = nevra.group(2) - version = nevra.group(3) - release = nevra.group(4) - arch = nevra.group(5) - elif NVRA_RE.match(pkg.nevra): - nvra = NVRA_RE.search(pkg.nevra) - name = nvra.group(1) - version = nvra.group(2) - release = nvra.group(3) - arch = nvra.group(4) - else: - continue - - if pkg.package_name not in pkg_src_rpm: - continue - - package = ET.SubElement(collection, "package") - package.set("name", name) - package.set("arch", arch) - package.set("epoch", epoch) - package.set("version", version) - package.set("release", release) - package.set("src", pkg_src_rpm[pkg.package_name]) - - # Add filename element - ET.SubElement(package, - "filename").text = EPOCH_RE.sub("", pkg.nevra) - - # Add checksum - ET.SubElement( - package, "sum", type=pkg.checksum_type - ).text = pkg.checksum - - # Check if module if pkg.module_name: - modules[pkg.module_name] = { - "name": pkg.module_name, - "context": pkg.module_context, - "stream": pkg.module_stream, - "version": pkg.module_version, - "arch": product_arch, - } + collection_short = f"{default_collection_short}__{pkg.module_name}" + if collection_short not in collections: + collections[collection_short] = { + "packages": [], + "module_context": pkg.module_context, + "module_name": pkg.module_name, + "module_stream": pkg.module_stream, + "module_version": pkg.module_version, + } + no_default_collection = True + collections[collection_short]["packages"].append(pkg) + else: + if no_default_collection: + continue + if collection_short not in collections: + collections[collection_short] = { + "packages": [], + } + collections[collection_short]["packages"].append(pkg) - # Add modules - for module in modules.values(): - module_element = ET.Element("module") - module_element.set("name", module["name"]) - module_element.set("stream", module["stream"]) - module_element.set("version", module["version"]) - module_element.set("context", module["context"]) - module_element.set("arch", module["arch"]) - collection.insert(1, module_element) + if no_default_collection and default_collection_short in collections: + del collections[default_collection_short] + + for collection_short, info in collections.items(): + # Create collection + collection = ET.Element("collection") + collection.set("short", collection_short) + + # Set short to name as well + ET.SubElement(collection, "name").text = collection_short + + if "module_name" in info: + module_element = ET.SubElement(collection, "module") + module_element.set("name", info["module_name"]) + module_element.set("stream", info["module_stream"]) + module_element.set("version", info["module_version"]) + module_element.set("context", info["module_context"]) + module_element.set("arch", product_arch) + + added_pkg_count = 0 + for pkg in info["packages"]: + if pkg.nevra.endswith(".src.rpm"): + continue + + name = pkg.package_name + epoch = "0" + if NEVRA_RE.match(pkg.nevra): + nevra = NEVRA_RE.search(pkg.nevra) + name = nevra.group(1) + epoch = nevra.group(2) + version = nevra.group(3) + release = nevra.group(4) + arch = nevra.group(5) + elif NVRA_RE.match(pkg.nevra): + nvra = NVRA_RE.search(pkg.nevra) + name = nvra.group(1) + version = nvra.group(2) + release = nvra.group(3) + arch = nvra.group(4) + else: + continue + + if pkg.package_name not in pkg_src_rpm: + continue + if arch != product_arch: + continue + + skip = False + for suffix in suffixes_to_skip: + if name.endswith(suffix): + skip = True + break + if skip: + continue + + package = ET.SubElement(collection, "package") + package.set("name", name) + package.set("arch", arch) + package.set("epoch", epoch) + package.set("version", version) + package.set("release", release) + package.set("src", pkg_src_rpm[pkg.package_name]) + + # Add filename element + ET.SubElement(package, + "filename").text = EPOCH_RE.sub("", pkg.nevra) + + # Add checksum + ET.SubElement( + package, "sum", type=pkg.checksum_type + ).text = pkg.checksum + + added_pkg_count += 1 + + if added_pkg_count > 0: + packages.append(collection) ET.indent(tree) xml_str = ET.tostring(tree, encoding="unicode", method="xml")