Skip to content

Commit

Permalink
Refactor the repository retrieval in get_dr_push
Browse files Browse the repository at this point in the history
closes pulp#1275
closes pulp#489
  • Loading branch information
lubosmj committed Nov 9, 2023
1 parent 4eee143 commit afe751c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 50 deletions.
2 changes: 2 additions & 0 deletions CHANGES/1275.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Ensured repositories are correctly retrieved or initialized when handling client's parallel blob
uploading.
1 change: 1 addition & 0 deletions CHANGES/489.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Refactored ``get_dr_push()`` to be more readable.
72 changes: 25 additions & 47 deletions pulp_container/app/registry_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@
from pulpcore.plugin.models import Artifact, ContentArtifact, UploadChunk
from pulpcore.plugin.files import PulpTemporaryUploadedFile
from pulpcore.plugin.tasking import add_and_remove, dispatch
from pulpcore.plugin.util import get_objects_for_user
from pulpcore.plugin.util import get_objects_for_user, get_url
from rest_framework.exceptions import (
AuthenticationFailed,
NotAuthenticated,
PermissionDenied,
ParseError,
Throttled,
ValidationError,
)
from rest_framework.generics import ListAPIView
from rest_framework.pagination import BasePagination
Expand Down Expand Up @@ -291,32 +290,7 @@ def get_dr_push(self, request, path, create=False):
distribution = models.ContainerDistribution.objects.get(base_path=path)
except models.ContainerDistribution.DoesNotExist:
if create:
try:
with transaction.atomic():
repo_serializer = serializers.ContainerPushRepositorySerializer(
data={"name": path}, context={"request": request}
)
repo_serializer.is_valid(raise_exception=True)
repository = repo_serializer.create(repo_serializer.validated_data)
repo_href = serializers.ContainerPushRepositorySerializer(
repository, context={"request": request}
).data["pulp_href"]

dist_serializer = serializers.ContainerDistributionSerializer(
data={"base_path": path, "name": path, "repository": repo_href}
)
dist_serializer.is_valid(raise_exception=True)
distribution = dist_serializer.create(dist_serializer.validated_data)
except ValidationError:
raise RepositoryInvalid(name=path)
except IntegrityError:
# Seems like another process created our stuff already. Retry fetching it.
distribution = models.ContainerDistribution.objects.get(base_path=path)
repository = distribution.repository
if repository:
repository = repository.cast()
if not repository.PUSH_ENABLED:
raise RepositoryInvalid(name=path, message="Repository is read-only.")
distribution, repository = self.create_dr(path, request)
else:
raise RepositoryNotFound(name=path)
else:
Expand All @@ -326,29 +300,33 @@ def get_dr_push(self, request, path, create=False):
if not repository.PUSH_ENABLED:
raise RepositoryInvalid(name=path, message="Repository is read-only.")
elif create:
try:
with transaction.atomic():
repo_serializer = serializers.ContainerPushRepositorySerializer(
data={"name": path}, context={"request": request}
)
repo_serializer.is_valid(raise_exception=True)
repository = repo_serializer.create(repo_serializer.validated_data)
distribution.repository = repository
distribution.save()
except IntegrityError:
# Seems like another process created our stuff already. Retry fetching it.
distribution = models.ContainerDistribution.objects.get(pk=distribution.pk)
repository = distribution.repository
if repository:
repository = repository.cast()
if not repository.PUSH_ENABLED:
raise RepositoryInvalid(name=path, message="Repository is read-only.")
else:
raise RepositoryNotFound(name=path)
with transaction.atomic():
repository = serializers.ContainerPushRepositorySerializer.get_or_create(
{"name": path}
)
distribution.repository = repository
distribution.save()
else:
raise RepositoryNotFound(name=path)
return distribution, repository

def create_dr(self, path, request):
with transaction.atomic():
repository = serializers.ContainerPushRepositorySerializer.get_or_create({"name": path})
distribution = serializers.ContainerDistributionSerializer.get_or_create(
{"base_path": path, "name": path}, {"repository": get_url(repository)}
)

if distribution.repository:
dist_repository = distribution.repository.cast()
if not dist_repository.PUSH_ENABLED or repository != dist_repository:
raise RepositoryInvalid(name=path, message="Repository is read-only.")
else:
distribution.repository = repository
distribution.save()

return distribution, repository


class BearerTokenView(APIView):
"""
Expand Down
4 changes: 2 additions & 2 deletions pulp_container/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class Meta:
model = models.ContainerRepository


class ContainerPushRepositorySerializer(RepositorySerializer):
class ContainerPushRepositorySerializer(RepositorySerializer, GetOrCreateSerializerMixin):
"""
Serializer for Container Push Repositories.
"""
Expand Down Expand Up @@ -277,7 +277,7 @@ class Meta:
model = models.ContainerRemote


class ContainerDistributionSerializer(DistributionSerializer):
class ContainerDistributionSerializer(DistributionSerializer, GetOrCreateSerializerMixin):
"""
A serializer for ContainerDistribution.
"""
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ecdsa>=0.14,<=0.18.0
jsonschema>=4.4,<4.20
pulpcore>=3.40.1,<3.55
pulpcore>=3.40.3,<3.55
pyjwkest>=1.4,<=1.4.2
pyjwt[crypto]>=2.4,<2.9

0 comments on commit afe751c

Please sign in to comment.