diff --git a/CHANGES/889.bugfix b/CHANGES/889.bugfix new file mode 100644 index 000000000..34bbebc0b --- /dev/null +++ b/CHANGES/889.bugfix @@ -0,0 +1 @@ +Fix a bug where when a collection version is removed from a repository, it's associated signatures and deprecated content remains in the repository. \ No newline at end of file diff --git a/pulp_ansible/app/models.py b/pulp_ansible/app/models.py index 0974accda..3df98b90f 100644 --- a/pulp_ansible/app/models.py +++ b/pulp_ansible/app/models.py @@ -315,6 +315,38 @@ class Meta: permissions = (("modify_ansible_repo_content", "Can modify ansible repository content"),) + def finalize_new_version(self, new_version): + """Finalize repo version.""" + removed_collection_versions = new_version.removed( + base_version=new_version.base_version + ).filter(pulp_type=CollectionVersion.get_pulp_type()) + + # Remove any deprecated and signature content associated with the removed collection + # versions + for version in removed_collection_versions: + version = version.cast() + + signatures = new_version.get_content( + content_qs=CollectionVersionSignature.objects.filter(signed_collection=version) + ) + new_version.remove_content(signatures) + + other_collection_versions = new_version.get_content( + content_qs=CollectionVersion.objects.filter(collection=version.collection) + ) + + # AnsibleCollectionDeprecated applies to all collection versions in a repository, + # so only remove it if there are no more collection versions for the specified + # collection present. + if not other_collection_versions.exists(): + deprecations = new_version.get_content( + content_qs=AnsibleCollectionDeprecated.objects.filter( + namespace=version.namespace, name=version.name + ) + ) + + new_version.remove_content(deprecations) + class AnsibleDistribution(Distribution): """ diff --git a/pulp_ansible/tests/functional/api/collection/v3/test_deletion.py b/pulp_ansible/tests/functional/api/collection/v3/test_deletion.py index 6ae97f6d8..003899acf 100644 --- a/pulp_ansible/tests/functional/api/collection/v3/test_deletion.py +++ b/pulp_ansible/tests/functional/api/collection/v3/test_deletion.py @@ -1,5 +1,9 @@ -from pulp_ansible.tests.functional.utils import gen_collection_in_distribution -from pulp_ansible.tests.functional.utils import SyncHelpersMixin, TestCaseUsingBindings +from pulp_ansible.tests.functional.utils import ( + gen_collection_in_distribution, + SyncHelpersMixin, + TestCaseUsingBindings, + create_signing_service, +) from pulpcore.client.pulp_ansible.exceptions import ApiException from pulp_smash.pulp3.bindings import monitor_task @@ -192,3 +196,53 @@ def test_invalid_deletion(self): ) resp = monitor_task(resp.task) + + def test_delete_deprecated_content(self): + """Test that deprecated content is removed correctly.""" + # Deprecate the collection + result = self.collections_v3api.update( + path=self.distribution.base_path, + name=self.collection_name, + namespace=self.collection_namespace, + body={"deprecated": True}, + ) + monitor_task(result.task) + + resp = self.collections_v3api.delete( + path=self.distribution.base_path, + name=self.collection_name, + namespace=self.collection_namespace, + ) + monitor_task(resp.task) + + # Verify that all the content is gone + repo = self.repo_api.read(self.repo.pulp_href) + latest_version = self.repo_version_api.read(repo.latest_version_href) + + assert len(latest_version.content_summary.present) == 0 + + def test_delete_signed_content(self): + """Test that signature content is removed correctly.""" + sign_service = create_signing_service() + + # Sign the collections + body = { + "content_units": [ + "*", + ], + "signing_service": sign_service.pulp_href, + } + monitor_task(self.repo_api.sign(self.repo.pulp_href, body).task) + + resp = self.collections_v3api.delete( + path=self.distribution.base_path, + name=self.collection_name, + namespace=self.collection_namespace, + ) + monitor_task(resp.task) + + # Verify that all the content is gone + repo = self.repo_api.read(self.repo.pulp_href) + latest_version = self.repo_version_api.read(repo.latest_version_href) + + assert len(latest_version.content_summary.present) == 0 diff --git a/pulp_ansible/tests/functional/utils.py b/pulp_ansible/tests/functional/utils.py index 9e1398aeb..28db22c0f 100644 --- a/pulp_ansible/tests/functional/utils.py +++ b/pulp_ansible/tests/functional/utils.py @@ -46,6 +46,7 @@ RemotesRoleApi, AnsibleRepositorySyncURL, PulpAnsibleArtifactsCollectionsV3Api, + RepositoriesAnsibleVersionsApi, ) from orionutils.generator import build_collection, randstr @@ -221,6 +222,7 @@ def setUpClass(cls): """Create class-wide variables.""" cls.client = gen_ansible_client() cls.repo_api = RepositoriesAnsibleApi(cls.client) + cls.repo_version_api = RepositoriesAnsibleVersionsApi(cls.client) cls.remote_collection_api = RemotesCollectionApi(cls.client) cls.remote_git_api = RemotesGitApi(cls.client) cls.remote_role_api = RemotesRoleApi(cls.client)