Issues with DNF repoclosure

After the recent switch to dnf repoclosure in our tooling to enable EL8 packages to be resolved properly through repoclosure we’ve encountered two situations that appear mutually exclusive in terms of their solutions.

Case #1

Upgrading a dependency in a packaging PR for which a package already in our repositories is set to require a version lower than the update.

Example:

Opening a PR to update rubygem-sprockets to 4.0 when foreman still requires < 4.

DNF repoclosure requires the use of --best to properly detect this break in dependencies.

Case 2

Upgrading a package and one its dependencies at the same time.

Example:

Opening a PR to update pulpcore-container and pulpcore such as this PR.

DNF repoclosure requires the use of --newest to properly detect this break in dependencies.

Problem

Using both --best and --newest break one of the above situations. They appear to be mutually exclusive as best I can tell with the way we check repoclosures today.

Does it make sense to do a run with both and report both results? While ugly and puts the burden on the reviewer to understand the output, it’s better than the current situation. If label them right, it helps.

Am I right that case 1 would check repo dependencies where case 2 checks PR dependencies?

To add further joy, the --best option (which seems to be the best option for not having false positives) breaks repoclosure that is affected by modularity:

https://ci.theforeman.org/job/foreman-plugins-nightly-rpm-pipeline/193/console

I’m starting to question the nature of my reality as to what RPM is detecting with respect to “best” in these cases for dependency resolution.

One thing that came to my mind after a few beers yesterday: is there a way to merge repos before doing closure?

My understanding is that most of our current woes is due to the fact that we have two repos we care about “downloaded_rpms” (aka “whatever has been built by this PR”) and “the target” (aka “the repo the result of this PR will be tagged into”). If we could take the target, fetch all its metadata and inject the stuff we just built, instead of fiddling around with --best, would that help in any way?

I am proposing to revert and drop --best as it seems to cause more false-positives than anything else and breaks EL8 repoclosure where modules are involved:

https://ci.theforeman.org/job/foreman-nightly-rpm-pipeline/554/console