#4545 koji kiwi-build --repo= does not handle priorities for repos
Opened by davidlt. Modified

In Fedora/RISCV land we build some board/vendor/unified-specific kernels. We build them in Koji in a separate tag (e.g., f43-spacemit, f43-p550). In the past we used to have full repos per each custom need, but these days we incremental repos which basically constains only kernel. We layer them on top of generic Fedora/RISCV repos in Kiwi with repository priorities to make sure the right kernel is picked. Some of these have an older kernel version (LTS) and thus NVR is lower. We have no problems with Kiwi locally as those repo descriptions have priorities. I tried to layer repos and use Koji instead.

So the final Kiwi description contained:

<repository type="rpm-md">
<source path="https://riscv-koji.fedoraproject.org/repos-dist/f43-p550/latest/$arch/"/>
</repository>
<repository type="rpm-md">
<source path="https://riscv-koji.fedoraproject.org/repos-dist/f43-staging/latest/$arch/"/>
</repository>
<repository type="rpm-md">
<source path="https://riscv-koji.fedoraproject.org/repos-dist/f43/latest/$arch/"/>
</repository>

These repos have no priorities set and thus the highest NVR wins. In this cases it fails to pull a special kernel.

Suggestion would be to teach --repo=REPO about priorities. For example, --repo=[PRIORITY,]REPO

Then set that for Kiwi in:

<repository type="rpm-md" [..] priority="96">

After having a quick look at the code it was clear that didn't require much work. I wanted to play latest Gemini Pro thus I gave it the required code snippets (instead of allowing to read full repo). It didn't better than me in general (and faster).

Tested in Fedora/RISCV Koji.

Builder part:

--- /usr/lib/koji-builder-plugins/kiwi.py.orig  2026-02-19 07:57:40.723541436 +0000
+++ /usr/lib/koji-builder-plugins/kiwi.py       2026-02-19 08:17:50.299351232 +0000
@@ -220,12 +220,29 @@
         for old_repo in image.getElementsByTagName('repository'):
             image.removeChild(old_repo)
+        ## add koji ones
+        #for repo in sorted(set(repos)):
+        #    repo_node = newxml.createElement('repository')
+        #    repo_node.setAttribute('type', 'rpm-md')
+        #    source = newxml.createElement('source')
+        #    source.setAttribute('path', repo)
+        #    repo_node.appendChild(source)
+        #    image.appendChild(repo_node)
+
         # add koji ones
-        for repo in sorted(set(repos)):
+        # Normalize to (priority, url) tuples so sorting and set() work correctly
+        norm_repos = [tuple(r) if isinstance(r, list) else (None, r) for r in repos]
+
+        for priority, repo_url in sorted(set(norm_repos), key=lambda x: (str(x[0] or ''), x[1])):
             repo_node = newxml.createElement('repository')
             repo_node.setAttribute('type', 'rpm-md')
+
+            # Add the priority attribute if it was provided
+            if priority is not None:
+                repo_node.setAttribute('priority', str(priority))
+
             source = newxml.createElement('source')
-            source.setAttribute('path', repo)
+            source.setAttribute('path', repo_url)
             repo_node.appendChild(source)
             image.appendChild(repo_node)

CLI part:

--- /usr/lib/python3.14/site-packages/koji_cli_plugins/kiwi.py.orig     2026-02-19 09:47:17.784307049 +0200
+++ /usr/lib/python3.14/site-packages/koji_cli_plugins/kiwi.py  2026-02-19 09:53:24.322316747 +0200
@@ -24,7 +24,8 @@
     parser.add_option("--repo", action="append",
                       help="Specify a repo that will override the repo used to install "
                            "RPMs in the image. May be used multiple times. The "
-                           "build tag repo associated with the target is the default.")
+                           "build tag repo associated with the target is the default. "
+                           "Format: [PRIORITY,]REPO")
     parser.add_option("--repo-releasever", help="Override default releasever of the output image")
     parser.add_option("--noprogress", action="store_true",
                       help="Do not display progress of the upload")
@@ -87,8 +88,25 @@
         kwargs['result_bundle_name_format'] = options.result_bundle_name_format
     if options.arches:
         kwargs['arches'] = [canonArch(arch) for arch in options.arches]
+#    if options.repo:
+#        kwargs['repos'] = options.repo
+
     if options.repo:
-        kwargs['repos'] = options.repo
+        kwargs['repos'] = []
+        for r in options.repo:
+            if ',' in r:
+                # Split once to separate priority from the URL
+                priority, url = r.split(',', 1)
+                try:
+                    # Pass as a tuple (priority, url) which Koji APIs typically expect
+                    kwargs['repos'].append((int(priority), url))
+                except ValueError:
+                    # Fallback if the first part isn't a valid integer
+                    kwargs['repos'].append(r)
+            else:
+                kwargs['repos'].append(r)
+        print(kwargs['repos'])
+
     if options.repo_releasever:
         kwargs['repo_releasever'] = options.repo_releasever

Builds:
https://riscv-koji.fedoraproject.org/koji/buildinfo?buildID=62791
https://riscv-koji.fedoraproject.org/koji/buildinfo?buildID=62793
https://riscv-koji.fedoraproject.org/koji/buildinfo?buildID=62794

From one of Kiwi files:

[..]
<repository type="rpm-md" priority="96">
<source path="https://riscv-koji.fedoraproject.org/repos-dist/f43-p550/latest/$arch/"/>
</repository>
<repository type="rpm-md" priority="98">
<source path="https://riscv-koji.fedoraproject.org/repos-dist/f43-staging/latest/$arch/"/>
</repository>
<repository type="rpm-md" priority="99">
<source path="https://riscv-koji.fedoraproject.org/repos-dist/f43/latest/$arch/"/>
</repository>
[..]

Metadata Update from @tkopecek:
- Custom field Size adjusted to None
- Issue set to the milestone: 1.37

This issue has been migrated to Fedora Forge:
https://forge.fedoraproject.org/koji/koji/issues/4545

Please continue any further discussion there.

Metadata