Skip to content

Commit

Permalink
Fixed PRC not getting removed when modifying repositories
Browse files Browse the repository at this point in the history
[noissue]
  • Loading branch information
hstct committed Nov 19, 2024
1 parent eb5c455 commit 2b6fc72
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 2 deletions.
38 changes: 36 additions & 2 deletions pulp_deb/app/viewsets/repository.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
from gettext import gettext as _ # noqa

from django.conf import settings
from drf_spectacular.utils import extend_schema
from rest_framework.decorators import action
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.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 +28,35 @@
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):
# The serializer expects URIs so this is more of a hackish workaround.
base_url = f"{settings.V3_API_ROOT}content/deb/package_release_components/"
package_ids = [href.split("/")[-2] for href in package_hrefs]
matching_packages = Package.objects.filter(pulp_id__in=package_ids)
matching_components = PackageReleaseComponent.objects.filter(package__in=matching_packages)
prc_href = [f"{base_url}{component.pulp_id}/" for component in matching_components]
return prc_href


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
75 changes: 75 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,80 @@ 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], "base_version": repo.latest_version_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,
)

package = deb_get_content_types(
"apt_package_api", DEB_PACKAGE_NAME, repo, repo.latest_version_href
)[0]
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 not any(package.pulp_href == prc.package for prc in prcs)
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 2b6fc72

Please sign in to comment.