From 8d0a2277589896a417d728c51c16e54168dbf275 Mon Sep 17 00:00:00 2001 From: Matthias Dellweg Date: Thu, 25 Mar 2021 16:15:22 +0100 Subject: [PATCH] Make filesystem exporter apis async This will introduce a change that is about to come with pulpcore 3.12 anyway. But that would introduce incompatible bindings changes between two pulp_file releases. We must be proactive here in order to be able to ship compatible binding packages. Required PR: https://github.com/pulp/pulpcore/pull/1200 fixes #8451 https://pulp.plan.io/issues/8451 --- CHANGES/8451.bugfix | 1 + CHANGES/8451.removal | 1 + pulp_file/app/viewsets.py | 55 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 CHANGES/8451.bugfix create mode 100644 CHANGES/8451.removal diff --git a/CHANGES/8451.bugfix b/CHANGES/8451.bugfix new file mode 100644 index 00000000..3c339ecb --- /dev/null +++ b/CHANGES/8451.bugfix @@ -0,0 +1 @@ +Added asynchronous tasking to the Update and Delete endpoints of FilesystemExporter to provide proper locking on resources. diff --git a/CHANGES/8451.removal b/CHANGES/8451.removal new file mode 100644 index 00000000..51027d0b --- /dev/null +++ b/CHANGES/8451.removal @@ -0,0 +1 @@ +Update and Delete endpoints of FilesystemExporter changed to return 202 with tasks. diff --git a/pulp_file/app/viewsets.py b/pulp_file/app/viewsets.py index 85445055..18b24d0a 100644 --- a/pulp_file/app/viewsets.py +++ b/pulp_file/app/viewsets.py @@ -22,6 +22,7 @@ RepositoryVersionViewSet, SingleArtifactContentUploadViewSet, ) +from pulpcore.plugin.viewsets.content import tasks as coretasks from . import tasks from .models import ( @@ -194,6 +195,60 @@ class FileFilesystemExporterViewSet(ExporterViewSet): queryset = FileFilesystemExporter.objects.all() serializer_class = FileFilesystemExporterSerializer + # ----8<----8<----8<---- + # This section can be savely removed, once the plugin depends on pulpcore >= 3.12 + @extend_schema( + description="Trigger an asynchronous update task", + responses={202: AsyncOperationResponseSerializer}, + ) + def update(self, request, pk, **kwargs): + """ + Update a model instance. + """ + partial = kwargs.pop("partial", False) + instance = self.get_object() + serializer = self.get_serializer(instance, data=request.data, partial=partial) + serializer.is_valid(raise_exception=True) + app_label = instance._meta.app_label + async_result = enqueue_with_reservation( + coretasks.base.general_update, + [instance], + args=(pk, app_label, serializer.__class__.__name__), + kwargs={"data": request.data, "partial": partial}, + ) + return OperationPostponedResponse(async_result, request) + + @extend_schema( + description="Trigger an asynchronous partial update task", + responses={202: AsyncOperationResponseSerializer}, + ) + def partial_update(self, request, *args, **kwargs): + """ + Partially update a model instance. + """ + kwargs["partial"] = True + return self.update(request, *args, **kwargs) + + @extend_schema( + description="Trigger an asynchronous delete task", + responses={202: AsyncOperationResponseSerializer}, + ) + def destroy(self, request, pk, **kwargs): + """ + Delete a model instance. + """ + instance = self.get_object() + serializer = self.get_serializer(instance) + app_label = instance._meta.app_label + async_result = enqueue_with_reservation( + coretasks.base.general_delete, + [instance], + args=(pk, app_label, serializer.__class__.__name__), + ) + return OperationPostponedResponse(async_result, request) + + # ----8<----8<----8<---- + class FileFilesystemExportViewSet(ExportViewSet): """