Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typed Repositories #299

Merged
merged 1 commit into from Nov 11, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES/5625.removal
@@ -0,0 +1,3 @@
Sync is no longer available at the {remote_href}/sync/ repository={repo_href} endpoint. Instead, use POST {repo_href}/sync/ remote={remote_href}.

Creating / listing / editing / deleting file repositories is now performed on /pulp/api/v3/file/file/ instead of /pulp/api/v3/repositories/. Only file content can be present in a file repository, and only a file repository can hold file content.
2 changes: 1 addition & 1 deletion docs/_scripts/add_remove.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

echo "Kick off a task to add content to a repository, storing TASK_URL env variable"
export TASK_URL=$(http POST $BASE_ADDR$REPO_HREF'versions/' \
export TASK_URL=$(http POST $BASE_ADDR$REPO_HREF'modify/' \
add_content_units:="[\"$CONTENT_HREF\"]" \
| jq -r '.task')

Expand Down
2 changes: 1 addition & 1 deletion docs/_scripts/repo.sh
Expand Up @@ -2,7 +2,7 @@
export REPO_NAME=$(head /dev/urandom | tr -dc a-z | head -c5)

echo "Creating a new repository named $REPO_NAME."
export REPO_HREF=$(http POST $BASE_ADDR/pulp/api/v3/repositories/ name=$REPO_NAME \
export REPO_HREF=$(http POST $BASE_ADDR/pulp/api/v3/repositories/file/file/ name=$REPO_NAME \
| jq -r '.pulp_href')

echo "Inspecting repository."
Expand Down
2 changes: 1 addition & 1 deletion docs/_scripts/sync.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

echo "Create a task to sync the repository using the remote."
export TASK_URL=$(http POST $BASE_ADDR$REMOTE_HREF'sync/' repository=$REPO_HREF mirror=False \
export TASK_URL=$(http POST $BASE_ADDR$REPO_HREF'sync/' remote=$REMOTE_HREF mirror=False \
| jq -r '.task')

# Poll the task (here we use a function defined in docs/_scripts/base.sh)
Expand Down
2 changes: 1 addition & 1 deletion docs/_static/api.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/workflows/publish-host.rst
Expand Up @@ -17,8 +17,8 @@ Publication GET Response (after task is complete)::
"pulp_href": "/pulp/api/v3/publications/file/file/7d5440f6-202c-4e71-ace2-14c534f6df9e/",
"distributions": [],
"publisher": null,
"repository": "http://localhost:24817/pulp/api/v3/repositories/%3CRepository:%20foo%3E/",
"repository_version": "/pulp/api/v3/repositories/e242c556-bf46-4330-9c81-0be5432e55ba/versions/1/"
"repository": "/pulp/api/v3/repositories/e242c556-bf46-4330-9c81-0be5432e55ba/file/file/",
"repository_version": "/pulp/api/v3/repositories/e242c556-bf46-4330-9c81-0be5432e55ba/file/file/versions/1/"
}

Reference: `File Publication Usage <../restapi.html#tag/publications>`_
Expand Down
10 changes: 5 additions & 5 deletions docs/workflows/sync.rst
Expand Up @@ -11,9 +11,9 @@ Repository GET Response::

{
"pulp_created": "2019-05-16T19:23:55.224096Z",
"pulp_href": "/pulp/api/v3/repositories/680f18e7-0513-461f-b067-436b03285e4c/",
"pulp_href": "/pulp/api/v3/repositories/file/file/680f18e7-0513-461f-b067-436b03285e4c/",
"latest_version_href": null,
"versions_href": "/pulp/api/v3/repositories/680f18e7-0513-461f-b067-436b03285e4c/versions/",
"versions_href": "/pulp/api/v3/repositories/file/file/680f18e7-0513-461f-b067-436b03285e4c/versions/",
"description": "",
"name": "foo"
}
Expand Down Expand Up @@ -59,19 +59,19 @@ Repository Version GET Response (when complete)::

{
"pulp_created": "2019-05-16T19:23:58.230896Z",
"pulp_href": "/pulp/api/v3/repositories/680f18e7-0513-461f-b067-436b03285e4c/versions/1/",
"pulp_href": "/pulp/api/v3/repositories/file/file/680f18e7-0513-461f-b067-436b03285e4c/versions/1/",
"base_version": null,
"content_summary": {
"added": {
"file.file": {
"count": 3,
"href": "/pulp/api/v3/content/file/files/?repository_version_added=/pulp/api/v3/repositories/680f18e7-0513-461f-b067-436b03285e4c/versions/1/"
"href": "/pulp/api/v3/content/file/files/?repository_version_added=/pulp/api/v3/repositories/file/file/680f18e7-0513-461f-b067-436b03285e4c/versions/1/"
}
},
"present": {
"file.file": {
"count": 3,
"href": "/pulp/api/v3/content/file/files/?repository_version=/pulp/api/v3/repositories/680f18e7-0513-461f-b067-436b03285e4c/versions/1/"
"href": "/pulp/api/v3/content/file/files/?repository_version=/pulp/api/v3/repositories/file/file/680f18e7-0513-461f-b067-436b03285e4c/versions/1/"
}
},
"removed": {}
Expand Down
10 changes: 5 additions & 5 deletions docs/workflows/upload.rst
Expand Up @@ -58,9 +58,9 @@ Repository GET Response::

{
"pulp_created": "2019-05-16T19:23:55.224096Z",
"pulp_href": "/pulp/api/v3/repositories/680f18e7-0513-461f-b067-436b03285e4c/",
"pulp_href": "/pulp/api/v3/repositories/file/file/680f18e7-0513-461f-b067-436b03285e4c/",
"latest_version_href": null,
"versions_href": "/pulp/api/v3/repositories/680f18e7-0513-461f-b067-436b03285e4c/versions/",
"versions_href": "/pulp/api/v3/repositories/file/file/680f18e7-0513-461f-b067-436b03285e4c/versions/",
"description": null,
"name": "foo"
}
Expand All @@ -79,19 +79,19 @@ Repository Version GET Response::

{
"pulp_created": "2019-05-16T20:07:50.363735Z",
"pulp_href": "/pulp/api/v3/repositories/0d908664-e300-4223-869b-fc5d2cef285f/versions/1/",
"pulp_href": "/pulp/api/v3/repositories/file/file/0d908664-e300-4223-869b-fc5d2cef285f/versions/1/",
"base_version": null,
"content_summary": {
"added": {
"file.file": {
"count": 1,
"href": "/pulp/api/v3/content/file/files/?repository_version_added=/pulp/api/v3/repositories/0d908664-e300-4223-869b-fc5d2cef285f/versions/1/"
"href": "/pulp/api/v3/content/file/files/?repository_version_added=/pulp/api/v3/repositories/file/file/0d908664-e300-4223-869b-fc5d2cef285f/versions/1/"
}
},
"present": {
"file.file": {
"count": 1,
"href": "/pulp/api/v3/content/file/files/?repository_version=/pulp/api/v3/repositories/0d908664-e300-4223-869b-fc5d2cef285f/versions/1/"
"href": "/pulp/api/v3/content/file/files/?repository_version=/pulp/api/v3/repositories/file/file/0d908664-e300-4223-869b-fc5d2cef285f/versions/1/"
}
},
"removed": {}
Expand Down
25 changes: 25 additions & 0 deletions pulp_file/app/migrations/0005_filerepository.py
@@ -0,0 +1,25 @@
# Generated by Django 2.2.6 on 2019-10-28 18:42

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('core', '0013_repository_pulp_type'),
('file', '0004_filefilesystemexporter'),
]

operations = [
migrations.CreateModel(
name='FileRepository',
fields=[
('repository_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='file_filerepository', serialize=False, to='core.Repository')),
],
options={
'default_related_name': '%(app_label)s_%(model_name)s',
},
bases=('core.repository',),
),
]
12 changes: 12 additions & 0 deletions pulp_file/app/models.py
Expand Up @@ -8,6 +8,7 @@
Publication,
PublicationDistribution,
Remote,
Repository,
)


Expand Down Expand Up @@ -37,6 +38,17 @@ class Meta:
unique_together = ("relative_path", "digest")


class FileRepository(Repository):
"""
The "file" repository type.
"""

TYPE = "file"

class Meta:
default_related_name = "%(app_label)s_%(model_name)s"


class FileRemote(Remote):
"""
Remote for "file" content.
Expand Down
14 changes: 13 additions & 1 deletion pulp_file/app/serializers.py
Expand Up @@ -10,14 +10,16 @@
PublicationDistributionSerializer,
PublicationSerializer,
RemoteSerializer,
RepositorySerializer,
SingleArtifactContentUploadSerializer,
)

from .models import (
from pulp_file.app.models import (
FileContent,
FileDistribution,
FileFileSystemExporter,
FileRemote,
FileRepository,
FilePublication,
)

Expand Down Expand Up @@ -55,6 +57,16 @@ class Meta:
model = FileContent


class FileRepositorySerializer(RepositorySerializer):
"""
Serializer for File Repositories.
"""

class Meta:
fields = RepositorySerializer.Meta.fields
model = FileRepository


class FileRemoteSerializer(RemoteSerializer):
"""
Serializer for File Remotes.
Expand Down
6 changes: 3 additions & 3 deletions pulp_file/app/tasks/synchronizing.py
Expand Up @@ -4,15 +4,15 @@
from gettext import gettext as _
from urllib.parse import urlparse, urlunparse

from pulpcore.plugin.models import Artifact, ProgressReport, Remote, Repository
from pulpcore.plugin.models import Artifact, ProgressReport, Remote
from pulpcore.plugin.stages import (
DeclarativeArtifact,
DeclarativeContent,
DeclarativeVersion,
Stage,
)

from pulp_file.app.models import FileContent, FileRemote
from pulp_file.app.models import FileContent, FileRemote, FileRepository
from pulp_file.manifest import Manifest


Expand All @@ -35,7 +35,7 @@ def synchronize(remote_pk, repository_pk, mirror):

"""
remote = FileRemote.objects.get(pk=remote_pk)
repository = Repository.objects.get(pk=repository_pk)
repository = FileRepository.objects.get(pk=repository_pk)

if not remote.url:
raise ValueError(_("A remote must have a url specified to synchronize."))
Expand Down
51 changes: 39 additions & 12 deletions pulp_file/app/viewsets.py
Expand Up @@ -13,9 +13,11 @@
BaseDistributionViewSet,
ContentFilter,
FileSystemExporterViewSet,
RemoteViewSet,
OperationPostponedResponse,
PublicationViewSet,
RemoteViewSet,
RepositoryViewSet,
RepositoryVersionViewSet,
SingleArtifactContentUploadViewSet,
)

Expand All @@ -25,13 +27,15 @@
FileDistribution,
FileFileSystemExporter,
FileRemote,
FileRepository,
FilePublication,
)
from .serializers import (
FileContentSerializer,
FileDistributionSerializer,
FileFileSystemExporterSerializer,
FileRemoteSerializer,
FileRepositorySerializer,
FilePublicationSerializer,
)

Expand Down Expand Up @@ -59,17 +63,16 @@ class FileContentViewSet(SingleArtifactContentUploadViewSet):
filterset_class = FileContentFilter


class FileRemoteViewSet(RemoteViewSet):
class FileRepositoryViewSet(RepositoryViewSet):
"""
<!-- User-facing documentation, rendered as html-->
FileRemote represents an external source of <a href="#operation/content_file_files_list">File
Content</a>. The target url of a FileRemote must contain a file manifest, which contains the
metadata for all files at the source.
FileRepository represents a single file repository, to which content can be synced, added,
or removed.
"""

endpoint_name = "file"
queryset = FileRemote.objects.all()
serializer_class = FileRemoteSerializer
queryset = FileRepository.objects.all()
serializer_class = FileRepositorySerializer

@swagger_auto_schema(
operation_description="Trigger an asynchronous task to sync file content.",
Expand All @@ -82,10 +85,12 @@ def sync(self, request, pk):

The ``repository`` field has to be provided.
"""
remote = self.get_object()
serializer = RepositorySyncURLSerializer(data=request.data, context={"request": request})
serializer.is_valid(raise_exception=True)
repository = serializer.validated_data.get("repository")

repository = self.get_object()
remote = serializer.validated_data.get("remote")

mirror = serializer.validated_data.get("mirror", False)
result = enqueue_with_reservation(
tasks.synchronize,
Expand All @@ -95,14 +100,36 @@ def sync(self, request, pk):
return OperationPostponedResponse(result, request)


class FileRepositoryVersionViewSet(RepositoryVersionViewSet):
"""
<!-- User-facing documentation, rendered as html-->
FileRepositoryVersion represents a single file repository version.
"""

parent_viewset = FileRepositoryViewSet


class FileRemoteViewSet(RemoteViewSet):
"""
<!-- User-facing documentation, rendered as html-->
FileRemote represents an external source of <a href="#operation/content_file_files_list">File
Content</a>. The target url of a FileRemote must contain a file manifest, which contains the
metadata for all files at the source.
"""

endpoint_name = "file"
queryset = FileRemote.objects.all()
serializer_class = FileRemoteSerializer


class FilePublicationViewSet(PublicationViewSet):
"""
<!-- User-facing documentation, rendered as html-->
A FilePublication contains metadata about all the <a
href="#operation/content_file_files_list">File Content</a> in a particular <a
href="https://docs.pulpproject.org/en/3.0/nightly/restapi.html#operation/repositories_versions_list">Repository
Version.</a> Once a FilePublication has been created, it can be hosted using the <a
href="#operation/distributions_file_file_list">File Distribution API.</a>
href="href="#tag/repositories:-file-versions">File Repository Version.</a>
Once a FilePublication has been created, it can be hosted using the
<a href="#operation/distributions_file_file_list">File Distribution API.</a>
"""

endpoint_name = "file"
Expand Down
12 changes: 9 additions & 3 deletions pulp_file/tests/functional/api/test_crud_content_unit.py
Expand Up @@ -6,10 +6,16 @@

from pulp_smash import api, config, utils
from pulp_smash.exceptions import TaskReportError
from pulp_smash.pulp3.constants import ARTIFACTS_PATH, REPO_PATH
from pulp_smash.pulp3.constants import ARTIFACTS_PATH
from pulp_smash.pulp3.utils import delete_orphans, gen_repo

from pulp_file.tests.functional.constants import FILE_CONTENT_PATH, FILE_URL, FILE_URL2
from pulp_file.tests.functional.constants import (
FILE_REPO_PATH,
FILE_CONTENT_PATH,
FILE_URL,
FILE_URL2,
)

from pulp_file.tests.functional.utils import (
gen_file_content_attrs,
gen_file_content_upload_attrs,
Expand Down Expand Up @@ -261,7 +267,7 @@ def test_second_unit_replaces_the_first(self):
"""
delete_orphans(self.cfg)

repo = self.client.post(REPO_PATH, gen_repo())
repo = self.client.post(FILE_REPO_PATH, gen_repo())
self.addCleanup(self.client.delete, repo["pulp_href"])

files = {"file": utils.http_get(FILE_URL)}
Expand Down
5 changes: 3 additions & 2 deletions pulp_file/tests/functional/api/test_download_content.py
Expand Up @@ -6,13 +6,14 @@
from urllib.parse import urljoin

from pulp_smash import api, config, utils
from pulp_smash.pulp3.constants import ON_DEMAND_DOWNLOAD_POLICIES, REPO_PATH
from pulp_smash.pulp3.constants import ON_DEMAND_DOWNLOAD_POLICIES
from pulp_smash.pulp3.utils import download_content_unit, gen_distribution, gen_repo, sync

from pulp_file.tests.functional.constants import (
FILE_DISTRIBUTION_PATH,
FILE_FIXTURE_URL,
FILE_REMOTE_PATH,
FILE_REPO_PATH,
)
from pulp_file.tests.functional.utils import (
create_file_publication,
Expand Down Expand Up @@ -74,7 +75,7 @@ def do_test(self, policy):
cfg = config.get_config()
client = api.Client(cfg, api.json_handler)

repo = client.post(REPO_PATH, gen_repo())
repo = client.post(FILE_REPO_PATH, gen_repo())
self.addCleanup(client.delete, repo["pulp_href"])

body = gen_file_remote(policy=policy)
Expand Down