Skip to content
This repository has been archived by the owner on Dec 7, 2022. It is now read-only.

Problem: Publications are not needed for Docker plugin #341

Merged
merged 1 commit into from
Apr 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,24 +178,16 @@ Look at the new Repository Version created
}


Publish a Repository Version and create a Publication
-----------------------------------------------------
Add a Docker Distribution to serve the latest Repository Version
dkliban marked this conversation as resolved.
Show resolved Hide resolved
----------------------------------------------------------------

``$ http POST :24817/pulp/api/v3/docker/publish/ repository=$REPO_HREF``

.. code:: json

{
"task": "/pulp/api/v3/tasks/fd4cbecd-6c6a-4197-9cbe-4e45b0516309/"
}

``$ export PUBLICATION_HREF=$(http :24817/pulp/api/v3/publications/ | jq -r '.results[0] | ._href')``

Add a Docker Distribution to serve your publication
---------------------------------------------------

``$ http POST http://localhost:24817/pulp/api/v3/docker-distributions/ name='baz' base_path='foo' publication=$PUBLICATION_HREF``
The Docker Distribution will serve the latest version of a Repository if the repository is
specified during creation/update of a Docker Distribution. The Docker Distribution will serve
a specific repository version if repository_version is provided when creating a Docker
Distribution. Either repository or repository_version can be set on a Docker Distribution, but not
both.

``$ http POST http://localhost:24817/pulp/api/v3/docker-distributions/ name='baz' base_path='foo' repository=$REPO_HREF``

.. code:: json

Expand Down
15 changes: 14 additions & 1 deletion pulp_docker/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.db import models

from pulpcore.plugin.download import DownloaderFactory
from pulpcore.plugin.models import BaseDistribution, Content, Remote
from pulpcore.plugin.models import BaseDistribution, Content, Remote, RepositoryVersion

from . import downloaders

Expand Down Expand Up @@ -287,5 +287,18 @@ class DockerDistribution(BaseDistribution):
A docker distribution defines how a publication is distributed by Pulp's webserver.
"""

repository_version = models.ForeignKey(RepositoryVersion, null=True, on_delete=models.CASCADE)

class Meta:
default_related_name = 'docker_distributions'

def get_repository_version(self):
"""
Returns the repository version that is supposed to be served by this DockerDistribution.
"""
if self.repository:
return RepositoryVersion.latest(self.repository)
elif self.repository_version:
return self.repository_version
else:
return None
14 changes: 8 additions & 6 deletions pulp_docker/app/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ async def tags_list(request):
path = request.match_info['path']
distribution = await Registry.match_distribution(path)
tags = {'name': path, 'tags': set()}
for c in distribution.publication.repository_version.content:
repository_version = distribution.get_repository_version()
for c in repository_version.content:
c = c.cast()
if isinstance(c, ManifestTag) or isinstance(c, ManifestListTag):
tags['tags'].add(c.name)
Expand All @@ -149,11 +150,12 @@ async def get_tag(request):
path = request.match_info['path']
tag_name = request.match_info['tag_name']
distribution = await Registry.match_distribution(path)
repository_version = distribution.get_repository_version()
accepted_media_types = await Registry.get_accepted_media_types(request)
if MEDIA_TYPE.MANIFEST_LIST in accepted_media_types:
try:
tag = ManifestListTag.objects.get(
pk__in=distribution.publication.repository_version.content,
pk__in=repository_version.content,
name=tag_name
)
# If there is no manifest list tag, try again with manifest tag.
Expand All @@ -166,7 +168,7 @@ async def get_tag(request):
if MEDIA_TYPE.MANIFEST_V2 in accepted_media_types:
try:
tag = ManifestTag.objects.get(
pk__in=distribution.publication.repository_version.content,
pk__in=repository_version.content,
name=tag_name
)
except ObjectDoesNotExist:
Expand Down Expand Up @@ -211,11 +213,11 @@ async def get_by_digest(request):
path = request.match_info['path']
digest = "sha256:{digest}".format(digest=request.match_info['digest'])
distribution = await Registry.match_distribution(path)
repository_version = distribution.get_repository_version()
log.info(digest)
try:
ca = ContentArtifact.objects.get(
content__in=distribution.publication.repository_version.content,
relative_path=digest)
ca = ContentArtifact.objects.get(content__in=repository_version.content,
relative_path=digest)
headers = {'Content-Type': ca.content.cast().media_type}
except ObjectDoesNotExist:
raise PathNotResolved(path)
Expand Down
67 changes: 64 additions & 3 deletions pulp_docker/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
BaseDistributionSerializer,
DetailRelatedField,
IdentityField,
NestedRelatedField,
RemoteSerializer,
SingleArtifactContentSerializer,
)
Expand Down Expand Up @@ -182,8 +183,7 @@ class DockerDistributionSerializer(BaseDistributionSerializer):
view_name='docker-distributions-detail'
)
base_path = serializers.CharField(
help_text=_('The base (relative) path component of the published url. Avoid paths that \
overlap with other distribution base paths (e.g. "foo" and "foo/bar")'),
help_text=_('The base (relative) path that identifies the registry path.'),
validators=[validators.MaxLengthValidator(
models.DockerDistribution._meta.get_field('base_path').max_length,
message=_('Distribution base_path length must be less than {} characters').format(
Expand All @@ -197,7 +197,68 @@ class DockerDistributionSerializer(BaseDistributionSerializer):
help_text=_('The Registry hostame:port/name/ to use with docker pull command defined by '
'this distribution.')
)
repository_version = NestedRelatedField(
help_text=_('A URI of the repository version to be served by the Docker Distribution.'),
required=False,
label=_('Repository Version'),
queryset=models.RepositoryVersion.objects.all(),
view_name='versions-detail',
lookup_field='number',
parent_lookup_kwargs={'repository_pk': 'repository__pk'},
)

def validate(self, data):
"""
Validate the parameters for creating or updating Docker Distribution.

This method makes sure that only repository or a repository version is associated with a
Docker Distribution. It also validates that the base_path is a relative path.

Args:
data (dict): Dictionary of parameter value to validate

Returns:
Dict of validated data

Raises:
ValidationError if any of the validations fail.

"""
super().validate(data)
if 'repository' in data:
repository = data['repository']
elif self.instance:
repository = self.instance.repository
else:
repository = None

if 'repository_version' in data:
repository_version = data['repository_version']
elif self.instance:
repository_version = self.instance.repository_version
else:
repository_version = None

if repository and repository_version:
raise serializers.ValidationError({'repository': _("Repository can't be set if "
"repository_version is set also.")})
if 'publication' in data and data['publication']:
raise serializers.ValidationError({'publication': _("DockerDistributions don't serve "
"publications. A repository or "
"repository version should be "
"specified.")})
if 'publisher' in data and data['publisher']:
raise serializers.ValidationError({'publication': _("DockerDistributions don't work "
"with publishers. A repository or "
"a repository version should be "
"specified.")})
if 'base_path' in data and data['base_path']:
self._validate_relative_path(data['base_path'])

return data

class Meta:
model = models.DockerDistribution
fields = BaseDistributionSerializer.Meta.fields + ('base_path', 'registry_path')
fields = BaseDistributionSerializer.Meta.fields + ('base_path',
'registry_path',
'repository_version')
1 change: 0 additions & 1 deletion pulp_docker/app/tasks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
from .distribution import create, delete, update # noqa
from .publishing import publish # noqa
from .synchronize import synchronize # noqa
25 changes: 0 additions & 25 deletions pulp_docker/app/tasks/publishing.py

This file was deleted.

40 changes: 0 additions & 40 deletions pulp_docker/app/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@

from pulpcore.plugin.serializers import (
AsyncOperationResponseSerializer,
RepositoryPublishURLSerializer,
RepositorySyncURLSerializer,
)

from pulpcore.plugin.models import RepositoryVersion, Publication
from pulpcore.plugin.tasking import enqueue_with_reservation
from pulpcore.plugin.viewsets import (
ContentViewSet,
Expand Down Expand Up @@ -149,44 +147,6 @@ def sync(self, request, pk):
return OperationPostponedResponse(result, request)


class DockerPublicationViewSet(NamedModelViewSet, mixins.CreateModelMixin):
"""
A ViewSet for Docker Publication.
"""

endpoint_name = 'docker/publish'
queryset = Publication.objects.all()
serializer_class = RepositoryPublishURLSerializer

@swagger_auto_schema(
operation_description="Trigger an asynchronous task to create a docker publication",
responses={202: AsyncOperationResponseSerializer}
)
def create(self, request):
"""
Queues a task that publishes a new Docker Publication.

"""
serializer = RepositoryPublishURLSerializer(
data=request.data,
context={'request': request}
)
serializer.is_valid(raise_exception=True)
repository_version = serializer.validated_data.get('repository_version')

# Safe because version OR repository is enforced by serializer.
if not repository_version:
repository = serializer.validated_data.get('repository')
repository_version = RepositoryVersion.latest(repository)

result = enqueue_with_reservation(
tasks.publish,
[repository_version.repository],
kwargs={'repository_version_pk': str(repository_version.pk)}
)
return OperationPostponedResponse(result, request)


class DockerDistributionViewSet(NamedModelViewSet,
mixins.UpdateModelMixin,
mixins.RetrieveModelMixin,
Expand Down
80 changes: 0 additions & 80 deletions pulp_docker/tests/functional/api/test_publish.py

This file was deleted.

Loading