From 4b8ba057e1dcb25d70b5c7e3af073554c932ac49 Mon Sep 17 00:00:00 2001 From: Grant Gainey Date: Wed, 2 Feb 2022 08:32:37 -0500 Subject: [PATCH] Corrected PulpImport/Export handling of sub-content. fixes #2192. [nocoverage] --- CHANGES/2192.bugfix | 5 +++++ pulpcore/app/importexport.py | 8 ++++---- pulpcore/app/modelresource.py | 19 ++++++++++++++++--- 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 CHANGES/2192.bugfix diff --git a/CHANGES/2192.bugfix b/CHANGES/2192.bugfix new file mode 100644 index 0000000000..f6af0c7a04 --- /dev/null +++ b/CHANGES/2192.bugfix @@ -0,0 +1,5 @@ +Fixed import/export of repositories with sub-content. + +An example would be the sub-repositories in pulp_rpm +DistributionTrees. + diff --git a/pulpcore/app/importexport.py b/pulpcore/app/importexport.py index 002100a1a7..e493112e62 100644 --- a/pulpcore/app/importexport.py +++ b/pulpcore/app/importexport.py @@ -144,10 +144,6 @@ def _combine_content_mappings(map1, map2): ) ) - # Export the connection between content and artifacts - resource = ContentArtifactResource(repository_version) - _write_export(export.tarfile, resource, dest_dir) - # content mapping is used by repo versions with subrepos (eg distribution tree repos) content_mapping = {} @@ -164,6 +160,10 @@ def _combine_content_mappings(map1, map2): content_mapping, resource.content_mapping ) + # Export the connection between content and artifacts + resource = ContentArtifactResource(repository_version, content_mapping) + _write_export(export.tarfile, resource, dest_dir) + msg = ( f"Exporting content for {plugin_name} " f"repository-version {repository_version.repository.name}/{repository_version.number}" diff --git a/pulpcore/app/modelresource.py b/pulpcore/app/modelresource.py index 684504036a..98c344b362 100644 --- a/pulpcore/app/modelresource.py +++ b/pulpcore/app/modelresource.py @@ -66,12 +66,19 @@ class ContentArtifactResource(QueryModelResource): ContentArtifact is different from other import-export entities because it has no 'natural key' other than a pulp_id, which aren't shared across instances. We do some magic to link up ContentArtifacts to their matching (already-imported) Content. + + Some plugin-models have sub-repositories. We take advantage of the content-mapping + machinery to account for those contentartifacts as well. """ artifact = fields.Field( column_name="artifact", attribute="artifact", widget=ForeignKeyWidget(Artifact, "sha256") ) + def __init__(self, repo_version=None, content_mapping=None): + self.content_mapping = content_mapping + super().__init__(repo_version) + def before_import_row(self, row, **kwargs): """ Fixes the content-ptr of an incoming content-artifact row at import time. @@ -92,9 +99,15 @@ def before_import_row(self, row, **kwargs): row["content"] = str(linked_content.pulp_id) def set_up_queryset(self): - return ContentArtifact.objects.filter(content__in=self.repo_version.content).order_by( - "content", "relative_path" - ) + vers_content = ContentArtifact.objects.filter(content__in=self.repo_version.content) + if self.content_mapping: + all_content = [] + for content_ids in self.content_mapping.values(): + all_content.extend(content_ids) + vers_content = vers_content.union( + ContentArtifact.objects.filter(content__in=all_content) + ) + return vers_content.order_by("content", "relative_path") class Meta: model = ContentArtifact