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 #1275
  • Loading branch information
lubosmj committed Nov 1, 2023
1 parent eab1797 commit 13906c8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 30 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.
49 changes: 21 additions & 28 deletions pulp_container/app/registry_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from django.core.files.storage import default_storage as storage
from django.core.files.base import ContentFile, File
from django.core.exceptions import ObjectDoesNotExist
from django.db import IntegrityError, transaction
from django.shortcuts import get_object_or_404

Expand All @@ -25,14 +26,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 +291,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 Down Expand Up @@ -349,6 +324,24 @@ def get_dr_push(self, request, path, create=False):
raise RepositoryNotFound(name=path)
return distribution, repository

def create_dr(self, path, request):
try:
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)}
)
except ObjectDoesNotExist:
raise RepositoryInvalid(name=path)

repository = repository.cast()
if not repository.PUSH_ENABLED:
raise RepositoryInvalid(name=path, message="Repository is read-only.")

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

0 comments on commit 13906c8

Please sign in to comment.