Support xml:base in repodata <location> elements#568
Open
oliverkurth wants to merge 2 commits intodevfrom
Open
Support xml:base in repodata <location> elements#568oliverkurth wants to merge 2 commits intodevfrom
oliverkurth wants to merge 2 commits intodevfrom
Conversation
Signed-off-by: Oliver Kurth <oliver.kurth@broadcom.com>
Signed-off-by: Oliver Kurth <oliver.kurth@broadcom.com>
8a73c09 to
7e8f824
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Support
xml:basein repodata<location>elementsBackground
The RPM repodata format allows a
<location>element inprimary.xmlto carryan
xml:baseattribute that overrides the base URL used to locate the actual RPMfile:
This is used in "merged repo" scenarios where multiple repositories share a common
RPM pool but each maintain their own repodata. Without
xml:basesupport, theonly way to achieve this with tdnf was to use symlinks from each repo directory
into the shared pool — which is not always possible (e.g. on servers that don't
support symlinks).
xml:basemay be:file:///srv/poolorhttp://host/pool: the RPM location isindependent of the repo's configured base URL
pool/: resolved against the repo's base URL at runtime,keeping the repodata relocatable
What was broken
libsolv correctly parses
xml:baseand stores it asSOLVABLE_MEDIABASEon thesolvable. However,
solvable_get_location()only returnsSOLVABLE_MEDIADIR/SOLVABLE_MEDIAFILE(thehrefcomponents) — it never consultsSOLVABLE_MEDIABASE. As a result, tdnf would ignorexml:baseentirely andconstruct wrong URLs by joining the repo's configured base URL with just the bare
hreffilename, losing the path specified inxml:base.This affected all tdnf operations:
list,repoquery --location,install,install --downloadonly, and--urls.Changes
solv/tdnfpackage.c,solv/prototypes.hAdded
SolvGetPkgMediaBaseFromId()to readSOLVABLE_MEDIABASEfrom a solvable.Returns
NULL(not an error) when absent, so normal repos withoutxml:basearecompletely unaffected.
client/packageutils.cAdded a static helper
GetPkgLocationWithMediaBase()which replaces all four callsites of
SolvGetPkgLocationFromId()that populatepPkgInfo->pszLocation. WhenSOLVABLE_MEDIABASEis present it usesTDNFJoinPath(mediabase, href)to composethe effective location. Since
mediabaseis always the first argument, URL schemessuch as
file:///are preserved correctly byTDNFJoinPath. The composed value is:file:///srv/pool/pkg.rpm) whenxml:baseis absolute —all downstream code then uses it directly
pool/pkg.rpm) whenxml:baseis relative — joined withthe repo base URL by existing downstream code as normal
client/remoterepo.cTDNFDownloadFileFromRepo: whenpszLocationalready contains a://scheme(absolute
xml:basecase), skip joining with the repo base URL and pass itdirectly to
TDNFDownloadFile.TDNFCreatePackageUrl: same guard for the same reason, used byrepoquery --locationand--urls.client/rpmtrans.cAdded an early check in the package fetch path: when
pszLocationstarts withfile://(absolutexml:base), strip the scheme and tryaccess()directly touse the file in-place, before falling through to the existing loop that tries
joining base URLs.
pytests/tests/test_xmlbase.pyNew test module covering all
xml:basevariants against bothfile://andhttp://repositories:TestNoBasexml:base— regression guard, existing behaviour unchangedTestRelativeBasexml:base(e.g.pool/)TestAbsoluteFileBasexml:basewithfile://URLTestAbsoluteHttpBasexml:basewithhttp://URL; also tests repodata via HTTP with packages from a different HTTP locationEach class exercises:
list --available,repoquery --location,install, andinstall --downloadonly.Repos are built on-the-fly using
createrepo_c --baseurl(to setxml:base) and--outputdir(to separate repodata from the RPM pool), with no new test packagesor spec files required.
Note
The changes, including the description above, were entirely generated by Cursor, using the Claude Sonnet 4.6 agent, but with human feedback.