Skip to content
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

3.14.6 cherrypicks #2142

Merged
merged 1 commit into from Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES/9487.bugfix
@@ -0,0 +1,2 @@
Fixed an issue where some repositories were unnecessarily prevented from using mirror-mode sync.
(backported from #9486)
32 changes: 24 additions & 8 deletions pulp_rpm/app/tasks/synchronizing.py
Expand Up @@ -467,6 +467,7 @@ def get_treeinfo_data(remote, remote_url):
mirror,
skip_types=skip_types,
new_url=new_url,
namespace=directory,
)
dv = RpmDeclarativeVersion(first_stage=stage, repository=sub_repo)
subrepo_version = dv.create()
Expand Down Expand Up @@ -549,6 +550,7 @@ def __init__(
skip_types=None,
new_url=None,
treeinfo=None,
namespace=None,
):
"""
The first stage of a pulp_rpm sync pipeline.
Expand All @@ -563,6 +565,7 @@ def __init__(
skip_types (list): List of content to skip
new_url(str): URL to replace remote url
treeinfo(dict): Treeinfo data
namespace(str): Path where this repo is located relative to some parent repo.

"""
super().__init__()
Expand All @@ -572,6 +575,11 @@ def __init__(
self.deferred_download = deferred_download
self.mirror = mirror

# How many directories deep this repo is nested within another repo (if at all).
# Backwards relative paths that are shallower than this depth are permitted (in mirror
# mode), to accomodate sub-repos which re-use packages from the parent repo.
self.namespace_depth = 0 if not namespace else len(namespace.strip("/").split("/"))

self.treeinfo = treeinfo
self.skip_types = [] if skip_types is None else skip_types

Expand All @@ -580,6 +588,10 @@ def __init__(
self.nevra_to_module = defaultdict(dict)
self.pkgname_to_groups = defaultdict(list)

def is_illegal_relative_path(self, path):
"""Whether a relative path points outside the repository being synced."""
return path.count("../") > self.namespace_depth

@staticmethod
async def parse_updateinfo(updateinfo_xml_path):
"""
Expand Down Expand Up @@ -643,12 +655,12 @@ async def run_repomdrecord_download(name, location_href, downloader):
checksum_types[record.type] = record_checksum_type
record.checksum_type = record_checksum_type

if self.mirror and (
record.location_base
or ".." in record.location_href
or record.type == "prestodelta"
):
raise ValueError(MIRROR_INCOMPATIBLE_REPO_ERR_MSG)
if self.mirror:
uses_base_url = record.location_base
illegal_relative_path = self.is_illegal_relative_path(record.location_href)

if uses_base_url or illegal_relative_path or record.type == "prestodelta":
raise ValueError(MIRROR_INCOMPATIBLE_REPO_ERR_MSG)

if not self.mirror and record.type not in types_to_download:
continue
Expand Down Expand Up @@ -1036,8 +1048,12 @@ async def on_package(pkg):
Args:
pkg (createrepo_c.Package): A completed createrepo_c package.
"""
if self.mirror and (pkg.location_base or ".." in pkg.location_href):
raise ValueError(MIRROR_INCOMPATIBLE_REPO_ERR_MSG)
if self.mirror:
uses_base_url = pkg.location_base
illegal_relative_path = self.is_illegal_relative_path(pkg.location_href)

if uses_base_url or illegal_relative_path:
raise ValueError(MIRROR_INCOMPATIBLE_REPO_ERR_MSG)

package = Package(**Package.createrepo_to_dict(pkg))
base_url = pkg.location_base or self.remote_url
Expand Down