-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
manifest,sources: add librepo support to Serialize/GenSources #1142
base: main
Are you sure you want to change the base?
Conversation
6ae0a5f
to
01c6fd2
Compare
01c6fd2
to
6e472e1
Compare
This commit enables librepo sources generation via a new osbuild.RpmDownloader iota that is passed to to `manifest.Serialize()` and `osbuild.GenSources()`. We also need to pass the resolved repoConfig to `manifest.Serialize()`. This is currently not type-safe, ideally we would look into how to do this in a type-safe way. Serialize should also take less args ideally.
6e472e1
to
4e2567a
Compare
Something about this approach doesn't sit well with me. It's getting a bit confusing, I think. I think part of (or maybe the source of) the issue is that we carry around repo configs alongside the content (depsolved RPMs) but so far it was only used for creating the rpm stage options (GPG keys). Now, we're (optionally) swapping out the curl source for a librepo source, which changes both the associated sources and the stage options. This all makes sense. Where it gets confusing is how everything interacts, where information on one argument needs to line up with things from the other. Here's what I mean by that:
This is simple enough for the RPMs themselves, it's pretty much just requiring either
What I'm getting at here is that it might be cleaner to bundle the RPMs with the repositories from their creation in the depsolver and carry them around as one. This would change the following (fake-ish) code: // init manifest
manifest := imgType.Manifest(bp, options, repos)
// resolve content
packageSets := manifest.GetPackageSetChains()
packageSpecs, repos := depsolve(packageSets)
containers := manifest.GetContainerSourceSpecs()
containerSpecs := resolveContainers(containers)
commits := manifest.GetOSTreeSourceSpecs()
commitSpecs := resolveCommits(commits)
// serialise with content
// NOTE: passing `nil` instead of `repos` might have no effect here, because
// the pipelines have the repo configs with the GPG keys already; we don't need
// resolved repos
serializedManifest := manifest.Serialize(packageSpecs, containerSpecs, commitSpecs, repos) to // init manifest
manifest := imgType.Manifest(bp, options, repos)
// resolve content
packageSets := manifest.GetPackageSetChains()
packageRepoSpecs := depsolve(packageSets) // *** NOTE: NEW STUFF HERE *** //
containers := manifest.GetContainerSourceSpecs()
containerSpecs := resolveContainers(containers)
commits := manifest.GetOSTreeSourceSpecs()
commitSpecs := resolveCommits(commits)
// serialise with content
serializedManifest := manifest.Serialize(packageRepoSpecs, containerSpecs, commitSpecs)
type PkgRepos struct {
rpms []rpmmd.PackageSpec
repos []rpmmd.RepoConfig
} The librepo vs curl option can be part of the One benefit here is that we can contain the consistency validation inside ¹ Source/stage option creation should be left to
The details aren't completely clear in my mind, so maybe ignore any issues with some of the specifics. What I think is the good idea here is having a single entity that we can be reasonably certain is internally consistent (because it comes straight from the depsolver) and provides conveniences for pulling out the data we need for stages and sources in a way that we don't need to verify or worry about outside of the entity itself. |
I second @achilleas-k's comment. Bundling RPMs and repos into a single input type makes a lot of sense. I don't have a strong opinion on adding the Would it make sense to use librepo implicitly (if not forced) in cases when the repo configuration uses mirrorlist? I expect that we may end up using a mix of (3rd party) repos that use just |
Thanks for the feedback, those are good thoughts and they align well with my plans - I am happy to change the types, fwiw, the TODOs about type-safety in this PR align well with the ideas there. I went this way to land librepo in bib/ibcli asap to fix the issue that we see in CI and that our users have with flaky mirror and then I wanted to get the manifestgen code in images so that there is a single place accross the projects to change when changing how depsolve works and then change the types. But I'm happy to flip this around, it is nicer (but will be a bigger diff). About the rpmDownloader argument, I have no strong opinion but I assume eventually we will just sunset the curl backend for package downloading? AIUI librepo is also curl based and can do everything that we do with curl too (i.e. if the repo does not have a mirrorlist or a metalink it will just use the BaseUrls. Or am I missing something? |
You're right, we could use librepo everywhere, even when there's just one repo. I don't mind doing the bigger change in a follow-up though. |
I did a quick test in 6a3ffdb - if that looks reasonable (and not too big) I am happy to merge it in here. Needs some naming tweaks probably and we need to decide if we really want this or a tailored dnfjson.Result (or in a different pkg) but it seems the principle is there (unless I misunderstood some of the above suggestions of course :) |
Yeah, pull that in here too. I was thinking of even bigger things, but that's a good start. |
This looks OK to me at the first glance. What I liked a lot from @achilleas-k 's comment were also the methods for getting data for stage / source generators:
But that can definitely be a follow-up. |
This is a quick draft to show what it make manifest.Serialize() less "floppy", i.e. to make it a) type-safe so that only depsolved pkgs/repos can be passed b) ensure pkg/repos that got depsolved together are grouped together Note that this is reusing `dnfjson.DepsolveResult` for simplicity to how the idea its an open question if we should actually use it. The upside is that it gives us e.g. the sbom everyhwere which might be nice. The downside is that its not tailored and a bit long (dnfjson.Result might be enough for this already).
This commit renames `dnfjson.DepsolveResult` to `dnfjson.Result`. It is slightly less descriptive but shorter and the only kind of result we have in the pacakge is from a depsolve so the meaning should be clear enough.
Thank you! I pulled in the described variant of the suggestion now. It uses the dnfjson.DepsolveResult as input for the serialization. This gives us the coupling that we all want and type-safety (one can no longer pass a non-depsolved rpmmd.RepoConfig. I also renamed dnfjson.DepsolveResult to just Result in a separate commit (so that I can revert again if the feeling is that this is too short/non-descriptive/muddy). I am happy to do followups with more cleanup, my plan is to pull in "manifestgen" into "images" from "image-builder-cli", that might be a good opportunity for more refactor. I will think more about the suggestion for the helpers and how that fits (would love love to hear more of your ideas, maybe in a short call?) |
This commit enables librepo sources generation via a new
osbuild.RpmDownloader iota that is passed to to
manifest.Serialize()
andosbuild.GenSources()
.We also need to pass the resolved repoConfig to
manifest.Serialize()
.This is currently not type-safe, ideally we would look into how to do
this in a type-safe way. Serialize should also take less args
ideally.
Superseeds #1132
With that we can enable
--use-librepo
in--use-librepo
to support librepo downloads image-builder-cli#51--use-librepo
switch bootc-image-builder#786