Skip to content

Make dnf_get_repos dnf5-compatible #556

@comps

Description

@comps

Per the

# TODO RHEL-11+ (RHEL-30615): the dnf4 API will change (confirmed by developers)
def get_repos_dnf5():
    pass

in https://github.com/RHSecurityCompliance/contest/blob/main/lib/dnf_get_repos, dnf5 uses a completely different API.


I've done some initial digging, so these are are my random notes:

  • The package name is python3-libdnf5 and the python module name is libdnf5, not dnf (like for dnf4).
  • Dnf5 no longer has a dictionary of parsed repositories that we can just dump & send to VM & reassemble, we need to go over *.conf in /etc/yum.repos.d ourselves, parse them into dicts, and only use libdnf5 to resolve metalink into baseurl (for installation).
    • This is because, otherwise, we would need to output every possible config value for every repo, since dnf5 doesn't keep track of what was configured vs what was the default. It just has 30 get_blabla_option() functions, ie. get_enabled_option().

A basic PoC for resolving repo IDs to fastest mirror or baseurl (depending on whether metalink or baseurl is specified) looks like:

import libdnf5

def get_baseurl():
    base = libdnf5.base.Base()
    base.load_config()
    base.setup()
    repo_sack = base.get_repo_sack()
    repo_sack.create_repos_from_system_configuration()
    repo_sack.load_repos(libdnf5.repo.Repo.Type_AVAILABLE)
    query = libdnf5.repo.RepoQuery(base)
    query.filter_enabled(True)  # enabled repos only ?
    for repo in query:
        repo_id = repo.get_id()  # the identifier inside INI [ ], not name=
        mirrors = repo.get_mirrors()
        if mirrors:
            yield (repo_id, mirrors[0])
        else:
            config = repo.get_config()
            yield (repo_id, config.get_baseurl_option().get_value() or None)

but, as mentioned, this will need to be just "side code", the primary algorithm will need to parse /etc/yum.repos.d INI files itself and just call the above to get a baseurl for Anaconda.

Also note we might need a new file for the above, because RHEL-8 needs the existing get_dnf_repos script to run via platform-python to run with python 3.6 (because that's what python-dnf (dnf4) needs to communicate with the C-based API), but we deliberately install higher pythons for Contest.
At the same time platform-python won't be on RHEL-11 at all, so the script would fail to run.

We could maybe have one file compatible with Pythons from 3.6 to 3.14 (3.15?), but we need to launch it differently from other code (and not just ./get_dnf_repos).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions