Skip to content

Commit

Permalink
Merge pull request #1185 from ATIX-AG/fix_repo_modify_with_structured…
Browse files Browse the repository at this point in the history
…_content

Fixed PRC not getting removed when modifying repositories
  • Loading branch information
hstct authored Nov 21, 2024
2 parents dcec23c + 630c38b commit 5551dfe
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGES/1190.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Removing packages from a repository using the modify API endpoint now also removes all associated PackageReleaseComponents.
37 changes: 34 additions & 3 deletions pulp_deb/app/viewsets/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
from rest_framework import viewsets
from rest_framework.serializers import ValidationError as DRFValidationError

from pulp_deb.app.models.content.content import Package
from pulp_deb.app.models.content.structure_content import PackageReleaseComponent
from pulp_deb.app.serializers import AptRepositorySyncURLSerializer

from pulpcore.plugin.util import extract_pk
from pulpcore.plugin.util import extract_pk, get_url
from pulpcore.plugin.actions import ModifyRepositoryActionMixin
from pulpcore.plugin.serializers import AsyncOperationResponseSerializer
from pulpcore.plugin.serializers import (
AsyncOperationResponseSerializer,
RepositoryAddRemoveContentSerializer,
)
from pulpcore.plugin.models import RepositoryVersion
from pulpcore.plugin.tasking import dispatch
from pulpcore.plugin.viewsets import (
Expand All @@ -22,7 +27,33 @@
from pulp_deb.app import models, serializers, tasks


class AptRepositoryViewSet(RepositoryViewSet, ModifyRepositoryActionMixin):
class AptModifyRepositoryActionMixin(ModifyRepositoryActionMixin):
@extend_schema(
description="Trigger an asynchronous task to create a new repository version.",
summary="Modify Repository Content",
responses={202: AsyncOperationResponseSerializer},
)
@action(detail=True, methods=["post"], serializer_class=RepositoryAddRemoveContentSerializer)
def modify(self, request, pk):
remove_content_units = request.data.get("remove_content_units", [])
package_hrefs = [href for href in remove_content_units if "/packages/" in href]

if package_hrefs:
prc_hrefs = self._get_matching_prc_hrefs(package_hrefs)
remove_content_units.extend(prc_hrefs)
request.data["remove_content_units"] = remove_content_units

return super().modify(request, pk)

def _get_matching_prc_hrefs(self, package_hrefs):
package_ids = [extract_pk(href) for href in package_hrefs]
matching_packages = Package.objects.filter(pulp_id__in=package_ids)
matching_prcs = PackageReleaseComponent.objects.filter(package__in=matching_packages)
prc_hrefs = [get_url(component) for component in matching_prcs]
return prc_hrefs


class AptRepositoryViewSet(AptModifyRepositoryActionMixin, RepositoryViewSet):
# The doc string is a top level element of the user facing REST API documentation:
"""
An AptRepository is the locally stored, Pulp-internal representation of a APT repository.
Expand Down
71 changes: 71 additions & 0 deletions pulp_deb/tests/functional/api/test_publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
DEB_FIXTURE_SINGLE_DIST,
DEB_PACKAGE_INDEX_NAME,
DEB_PACKAGE_NAME,
DEB_PACKAGE_RELEASE_COMPONENT_NAME,
DEB_PUBLICATION_ARGS_ALL,
DEB_PUBLICATION_ARGS_ONLY_SIMPLE,
DEB_PUBLICATION_ARGS_ONLY_STRUCTURED,
Expand Down Expand Up @@ -475,6 +476,76 @@ def test_publish_complex_dists(
assert_equal_package_index(remote, published)


@pytest.mark.parallel
def test_remove_package_from_repository(
create_publication_and_verify_repo_version,
deb_get_content_types,
deb_modify_repository,
deb_get_repository_by_href,
):
"""Test whether removing content in a structured publication removes all relevant content."""
remote_args = {"distributions": DEB_FIXTURE_DISTRIBUTIONS}
_, repo, _, _ = create_publication_and_verify_repo_version(
remote_args,
publication_args=DEB_PUBLICATION_ARGS_ONLY_STRUCTURED,
is_modified=False,
)

package = deb_get_content_types(
"apt_package_api", DEB_PACKAGE_NAME, repo, repo.latest_version_href
)[0]
prcs = deb_get_content_types(
"apt_package_release_components_api",
DEB_PACKAGE_RELEASE_COMPONENT_NAME,
repo,
repo.latest_version_href,
)
deb_modify_repository(
repo,
{"remove_content_units": [package.pulp_href]},
)
repo = deb_get_repository_by_href(repo.pulp_href)
prcs_new = deb_get_content_types(
"apt_package_release_components_api",
DEB_PACKAGE_RELEASE_COMPONENT_NAME,
repo,
repo.latest_version_href,
)

assert not any(package.pulp_href == prc.package for prc in prcs_new)
assert len(prcs_new) == len(prcs) - 1


@pytest.mark.parallel
def test_remove_all_content_from_repository(
create_publication_and_verify_repo_version,
deb_get_content_types,
deb_modify_repository,
deb_get_repository_by_href,
):
"""Test whether removing all content from a structured publication removes relevant content."""
remote_args = {"distributions": DEB_FIXTURE_DISTRIBUTIONS}
_, repo, _, _ = create_publication_and_verify_repo_version(
remote_args,
publication_args=DEB_PUBLICATION_ARGS_ONLY_STRUCTURED,
is_modified=False,
)

deb_modify_repository(
repo,
{"remove_content_units": ["*"]},
)
repo = deb_get_repository_by_href(repo.pulp_href)
prcs = deb_get_content_types(
"apt_package_release_components_api",
DEB_PACKAGE_RELEASE_COMPONENT_NAME,
repo,
repo.latest_version_href,
)

assert len(prcs) == 0


def assert_equal_package_index(orig, new):
"""In-detail check of two PackageIndex file-strings"""
parsed_orig = parse_package_index(orig)
Expand Down

0 comments on commit 5551dfe

Please sign in to comment.