pulpcore 3.89.1__py3-none-any.whl → 3.90.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pulpcore might be problematic. Click here for more details.

Files changed (43) hide show
  1. pulp_certguard/app/__init__.py +1 -1
  2. pulp_file/app/__init__.py +1 -1
  3. pulp_file/tests/functional/api/test_filesystem_export.py +220 -0
  4. pulp_file/tests/functional/api/test_pulp_export.py +103 -3
  5. pulpcore/app/apps.py +1 -1
  6. pulpcore/app/importexport.py +18 -2
  7. pulpcore/app/management/commands/shell.py +8 -0
  8. pulpcore/app/migrations/0144_delete_old_appstatus.py +28 -0
  9. pulpcore/app/migrations/0145_domainize_import_export.py +53 -0
  10. pulpcore/app/modelresource.py +61 -21
  11. pulpcore/app/models/__init__.py +2 -5
  12. pulpcore/app/models/exporter.py +7 -1
  13. pulpcore/app/models/fields.py +0 -1
  14. pulpcore/app/models/importer.py +8 -1
  15. pulpcore/app/models/repository.py +16 -0
  16. pulpcore/app/models/status.py +8 -138
  17. pulpcore/app/models/task.py +15 -25
  18. pulpcore/app/serializers/domain.py +1 -1
  19. pulpcore/app/serializers/exporter.py +4 -4
  20. pulpcore/app/serializers/importer.py +2 -2
  21. pulpcore/app/serializers/task.py +11 -8
  22. pulpcore/app/tasks/importer.py +44 -10
  23. pulpcore/app/tasks/repository.py +27 -0
  24. pulpcore/app/viewsets/base.py +18 -14
  25. pulpcore/app/viewsets/domain.py +1 -1
  26. pulpcore/app/viewsets/exporter.py +1 -8
  27. pulpcore/app/viewsets/importer.py +1 -6
  28. pulpcore/app/viewsets/task.py +0 -1
  29. pulpcore/content/instrumentation.py +18 -15
  30. pulpcore/openapi/__init__.py +16 -2
  31. pulpcore/plugin/tasking.py +4 -2
  32. pulpcore/tasking/tasks.py +245 -127
  33. pulpcore/tasking/worker.py +41 -47
  34. pulpcore/tests/functional/api/test_crud_domains.py +7 -0
  35. pulpcore/tests/functional/api/test_tasking.py +2 -2
  36. pulpcore/tests/functional/api/using_plugin/test_crud_repos.py +9 -2
  37. pulpcore/tests/unit/content/test_handler.py +43 -0
  38. {pulpcore-3.89.1.dist-info → pulpcore-3.90.1.dist-info}/METADATA +7 -7
  39. {pulpcore-3.89.1.dist-info → pulpcore-3.90.1.dist-info}/RECORD +43 -39
  40. {pulpcore-3.89.1.dist-info → pulpcore-3.90.1.dist-info}/WHEEL +0 -0
  41. {pulpcore-3.89.1.dist-info → pulpcore-3.90.1.dist-info}/entry_points.txt +0 -0
  42. {pulpcore-3.89.1.dist-info → pulpcore-3.90.1.dist-info}/licenses/LICENSE +0 -0
  43. {pulpcore-3.89.1.dist-info → pulpcore-3.90.1.dist-info}/top_level.txt +0 -0
@@ -13,7 +13,7 @@ from rest_framework import viewsets
13
13
  from rest_framework.decorators import action
14
14
  from rest_framework.generics import get_object_or_404
15
15
  from rest_framework.response import Response
16
- from pulpcore.openapi import PulpAutoSchema
16
+ from pulpcore.openapi import PulpAutoSchema, InheritSerializer
17
17
  from rest_framework.serializers import ValidationError as DRFValidationError, ListField, CharField
18
18
 
19
19
  from pulpcore.app import tasks
@@ -482,27 +482,31 @@ class AsyncUpdateMixin(AsyncReservedObjectMixin):
482
482
  ALLOW_NON_BLOCKING_UPDATE = True
483
483
 
484
484
  @extend_schema(
485
- description="Trigger an asynchronous update task",
486
- responses={202: AsyncOperationResponseSerializer},
485
+ description="Update the entity and trigger an asynchronous task if necessary",
486
+ responses={200: InheritSerializer, 202: AsyncOperationResponseSerializer},
487
487
  )
488
488
  def update(self, request, pk, **kwargs):
489
489
  partial = kwargs.pop("partial", False)
490
490
  instance = self.get_object()
491
491
  serializer = self.get_serializer(instance, data=request.data, partial=partial)
492
492
  serializer.is_valid(raise_exception=True)
493
- app_label = instance._meta.app_label
494
- task = dispatch(
495
- tasks.base.ageneral_update,
496
- exclusive_resources=self.async_reserved_resources(instance),
497
- args=(pk, app_label, serializer.__class__.__name__),
498
- kwargs={"data": request.data, "partial": partial},
499
- immediate=self.ALLOW_NON_BLOCKING_UPDATE,
500
- )
501
- return OperationPostponedResponse(task, request)
493
+
494
+ if all(getattr(instance, key) == value for key, value in serializer.validated_data.items()):
495
+ return Response(serializer.data)
496
+ else:
497
+ app_label = instance._meta.app_label
498
+ task = dispatch(
499
+ tasks.base.ageneral_update,
500
+ exclusive_resources=self.async_reserved_resources(instance),
501
+ args=(pk, app_label, serializer.__class__.__name__),
502
+ kwargs={"data": request.data, "partial": partial},
503
+ immediate=self.ALLOW_NON_BLOCKING_UPDATE,
504
+ )
505
+ return OperationPostponedResponse(task, request)
502
506
 
503
507
  @extend_schema(
504
- description="Trigger an asynchronous partial update task",
505
- responses={202: AsyncOperationResponseSerializer},
508
+ description="Update the entity partially and trigger an asynchronous task if necessary",
509
+ responses={200: InheritSerializer, 202: AsyncOperationResponseSerializer},
506
510
  )
507
511
  def partial_update(self, request, *args, **kwargs):
508
512
  kwargs["partial"] = True
@@ -109,7 +109,7 @@ class DomainViewSet(
109
109
 
110
110
  @extend_schema(
111
111
  description="Trigger an asynchronous update task",
112
- responses={202: AsyncOperationResponseSerializer},
112
+ responses={200: DomainSerializer, 202: AsyncOperationResponseSerializer},
113
113
  )
114
114
  def update(self, request, pk, **kwargs):
115
115
  """Prevent trying to update the default domain."""
@@ -1,6 +1,5 @@
1
- from django.conf import settings
2
1
  from drf_spectacular.utils import extend_schema
3
- from rest_framework import mixins, exceptions
2
+ from rest_framework import mixins
4
3
 
5
4
  from pulpcore.app.models import (
6
5
  Export,
@@ -34,8 +33,6 @@ from pulpcore.app.viewsets.base import NAME_FILTER_OPTIONS
34
33
  from pulpcore.plugin.tasking import dispatch
35
34
  from pulpcore.app.response import OperationPostponedResponse
36
35
 
37
- from gettext import gettext as _
38
-
39
36
 
40
37
  class ExporterViewSet(
41
38
  NamedModelViewSet,
@@ -120,8 +117,6 @@ class PulpExportViewSet(ExportViewSet):
120
117
  """
121
118
  Generates a Task to export the set of repositories assigned to a specific PulpExporter.
122
119
  """
123
- if settings.DOMAIN_ENABLED:
124
- raise exceptions.ValidationError(_("Export not supported with Domains enabled."))
125
120
  # Validate Exporter
126
121
  exporter = PulpExporter.objects.get(pk=exporter_pk).cast()
127
122
  ExporterSerializer.validate_path(exporter.path, check_is_dir=True)
@@ -159,8 +154,6 @@ class FilesystemExportViewSet(ExportViewSet):
159
154
  """
160
155
  Generates a Task to export files to the filesystem.
161
156
  """
162
- if settings.DOMAIN_ENABLED:
163
- raise exceptions.ValidationError(_("Export not supported with Domains enabled."))
164
157
  # Validate Exporter
165
158
  exporter = FilesystemExporter.objects.get(pk=exporter_pk).cast()
166
159
  ExporterSerializer.validate_path(exporter.path, check_is_dir=True)
@@ -1,7 +1,6 @@
1
- from django.conf import settings
2
1
  from django.http import Http404
3
2
  from drf_spectacular.utils import extend_schema
4
- from rest_framework import mixins, exceptions
3
+ from rest_framework import mixins
5
4
 
6
5
  from pulpcore.app.models import (
7
6
  Import,
@@ -25,8 +24,6 @@ from pulpcore.app.viewsets import (
25
24
  from pulpcore.app.viewsets.base import NAME_FILTER_OPTIONS
26
25
  from pulpcore.tasking.tasks import dispatch
27
26
 
28
- from gettext import gettext as _
29
-
30
27
 
31
28
  class ImporterViewSet(
32
29
  NamedModelViewSet,
@@ -87,8 +84,6 @@ class PulpImportViewSet(ImportViewSet):
87
84
  )
88
85
  def create(self, request, importer_pk):
89
86
  """Import a Pulp export into Pulp."""
90
- if settings.DOMAIN_ENABLED:
91
- raise exceptions.ValidationError(_("Import not supported with Domains enabled."))
92
87
  try:
93
88
  importer = PulpImporter.objects.get(pk=importer_pk)
94
89
  except PulpImporter.DoesNotExist:
@@ -68,7 +68,6 @@ class TaskFilter(BaseFilterSet):
68
68
  model = Task
69
69
  fields = {
70
70
  "state": ["exact", "in", "ne"],
71
- "worker": ["exact", "in", "isnull"],
72
71
  "name": ["exact", "contains", "in", "ne"],
73
72
  "logging_cid": ["exact", "contains"],
74
73
  "pulp_created": DATETIME_FILTER_OPTIONS,
@@ -21,23 +21,26 @@ def instrumentation(exporter=None, reader=None, provider=None):
21
21
  try:
22
22
  response = await handler(request)
23
23
  status_code = response.status
24
+
25
+ return response
24
26
  except web.HTTPException as exc:
25
27
  status_code = exc.status
26
- response = exc
27
-
28
- duration_ms = (time.time() - start_time) * 1000
29
-
30
- request_duration_histogram.record(
31
- duration_ms,
32
- attributes={
33
- "http.method": request.method,
34
- "http.status_code": normalize_http_status(status_code),
35
- "http.route": _get_view_request_handler_func(request),
36
- "worker.name": get_worker_name(),
37
- },
38
- )
39
-
40
- return response
28
+ raise exc
29
+ except Exception as exc:
30
+ status_code = exc.status if hasattr(exc, "status") else 500
31
+ raise exc
32
+ finally:
33
+ duration_ms = (time.time() - start_time) * 1000
34
+
35
+ request_duration_histogram.record(
36
+ duration_ms,
37
+ attributes={
38
+ "http.method": request.method,
39
+ "http.status_code": normalize_http_status(status_code),
40
+ "http.route": _get_view_request_handler_func(request),
41
+ "worker.name": get_worker_name(),
42
+ },
43
+ )
41
44
 
42
45
  return middleware
43
46
 
@@ -23,8 +23,8 @@ from drf_spectacular.plumbing import (
23
23
  )
24
24
  from drf_spectacular.settings import spectacular_settings
25
25
  from drf_spectacular.types import OpenApiTypes
26
- from drf_spectacular.utils import OpenApiParameter, extend_schema_field
27
- from drf_spectacular.extensions import OpenApiAuthenticationExtension
26
+ from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_field
27
+ from drf_spectacular.extensions import OpenApiViewExtension, OpenApiAuthenticationExtension
28
28
  from rest_framework import mixins, serializers
29
29
  from rest_framework.exceptions import ParseError
30
30
  from rest_framework.request import Request
@@ -48,6 +48,10 @@ API_ROOT_NO_FRONT_SLASH = API_ROOT_NO_FRONT_SLASH.replace("<", "{").replace(">",
48
48
  extend_schema_field(OpenApiTypes.INT64)(serializers.IntegerField)
49
49
 
50
50
 
51
+ class InheritSerializer(serializers.Serializer):
52
+ """This is a dummy tracer to allow mixins to refer to the natural serializer of a viewset."""
53
+
54
+
51
55
  class PulpAutoSchema(AutoSchema):
52
56
  """Pulp Auto Schema."""
53
57
 
@@ -238,6 +242,7 @@ class PulpAutoSchema(AutoSchema):
238
242
  """
239
243
  Handle response status code.
240
244
  """
245
+ # DRF handles this most of the time. But it seems set_label still needs it.
241
246
  response = super()._get_response_bodies()
242
247
  if (
243
248
  self.method == "POST"
@@ -248,6 +253,15 @@ class PulpAutoSchema(AutoSchema):
248
253
 
249
254
  return response
250
255
 
256
+ def _get_response_for_code(
257
+ self, serializer, status_code, media_types=None, direction="response"
258
+ ):
259
+ """Hack to replace the InheritSerializer with the real deal."""
260
+ if serializer == InheritSerializer:
261
+ serializer = self._get_serializer()
262
+
263
+ return super()._get_response_for_code(serializer, status_code, media_types, direction)
264
+
251
265
 
252
266
  class PulpSchemaGenerator(SchemaGenerator):
253
267
  """Pulp Schema Generator."""
@@ -1,5 +1,5 @@
1
1
  # Support plugins dispatching tasks
2
- from pulpcore.tasking.tasks import dispatch
2
+ from pulpcore.tasking.tasks import dispatch, adispatch
3
3
 
4
4
  from pulpcore.app.tasks import (
5
5
  ageneral_update,
@@ -13,13 +13,14 @@ from pulpcore.app.tasks import (
13
13
  reclaim_space,
14
14
  )
15
15
  from pulpcore.app.tasks.vulnerability_report import check_content
16
- from pulpcore.app.tasks.repository import add_and_remove
16
+ from pulpcore.app.tasks.repository import add_and_remove, aadd_and_remove
17
17
 
18
18
 
19
19
  __all__ = [
20
20
  "ageneral_update",
21
21
  "check_content",
22
22
  "dispatch",
23
+ "adispatch",
23
24
  "fs_publication_export",
24
25
  "fs_repo_version_export",
25
26
  "general_create",
@@ -29,4 +30,5 @@ __all__ = [
29
30
  "orphan_cleanup",
30
31
  "reclaim_space",
31
32
  "add_and_remove",
33
+ "aadd_and_remove",
32
34
  ]