Repository: pulp/pulpcore

Issue:
Cannot upload content via pulp-container because of the change made to the `Upload` model
The following commit broke the pulp-container upload: https://github.com/pulp/pulpcore/commit/9192c2bf0ccb0e0a2df595fd3efdd0980c80ff34.

Traceback:
```
pulp_1    | pulp [adbae673f9b7498d8240989c1bba93ff]: django.request:ERROR: Internal Server Error: /v2/myorg/mygroup/ubuntu/blobs/uploads/
pulp_1    | Traceback (most recent call last):
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
pulp_1    |     response = get_response(request)
pulp_1    |                ^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
pulp_1    |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
pulp_1    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
pulp_1    |     return view_func(*args, **kwargs)
pulp_1    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/rest_framework/viewsets.py", line 124, in view
pulp_1    |     return self.dispatch(request, *args, **kwargs)
pulp_1    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 509, in dispatch
pulp_1    |     response = self.handle_exception(exc)
pulp_1    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/src/pulp_container/pulp_container/app/registry_api.py", line 271, in handle_exception
pulp_1    |     response = super().handle_exception(exc)
pulp_1    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 469, in handle_exception
pulp_1    |     self.raise_uncaught_exception(exc)
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
pulp_1    |     raise exc
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
pulp_1    |     response = handler(request, *args, **kwargs)
pulp_1    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/src/pulp_container/pulp_container/app/registry_api.py", line 758, in create
pulp_1    |     upload.save()
pulp_1    |   File "/usr/lib64/python3.11/contextlib.py", line 81, in inner
pulp_1    |     return func(*args, **kwds)
pulp_1    |            ^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/django_lifecycle/mixins.py", line 196, in save
pulp_1    |     self._run_hooked_methods(AFTER_CREATE, **kwargs)
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/django_lifecycle/mixins.py", line 312, in _run_hooked_methods
pulp_1    |     method.run(self)
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/django_lifecycle/mixins.py", line 46, in run
pulp_1    |     self.method(instance)
pulp_1    |   File "/usr/local/lib/python3.11/site-packages/django_lifecycle/decorators.py", line 119, in func
pulp_1    |     hooked_method(*args, **kwargs)
pulp_1    |   File "/src/pulpcore/pulpcore/app/models/access_policy.py", line 70, in add_perms
pulp_1    |     viewset = get_viewset_for_model(self)
pulp_1    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
pulp_1    |   File "/src/pulpcore/pulpcore/app/util.py", line 188, in get_viewset_for_model
pulp_1    |     raise LookupError("Could not determine ViewSet base name for model {}".format(model_class))
```

This is reproducible always when trying to push any image to the Pulp Container Registry.

Affected code:
https://github.com/pulp/pulp_container/blob/742acc52f8fc44c4d18a41621455b21e2b9133ec/pulp_container/app/models.py#L804


Discussion:
Solutions considered:
1. make the post create hook not fail in that case
2. teach pulp_container to do something about it
3. we need a common super class without the mixin +1

@mdellweg

Resolving patch:
diff --git a/pulpcore/app/models/access_policy.py b/pulpcore/app/models/access_policy.py
--- a/pulpcore/app/models/access_policy.py
+++ b/pulpcore/app/models/access_policy.py
@@ -67,10 +67,14 @@ def __init__(self, *args, **kwargs):
 
     @hook("after_create")
     def add_perms(self):
-        viewset = get_viewset_for_model(self)
-        for permission_class in viewset.get_permissions(viewset):
-            if hasattr(permission_class, "handle_creation_hooks"):
-                permission_class.handle_creation_hooks(self)
+        try:
+            viewset = get_viewset_for_model(self)
+        except LookupError:
+            pass
+        else:
+            for permission_class in viewset.get_permissions(viewset):
+                if hasattr(permission_class, "handle_creation_hooks"):
+                    permission_class.handle_creation_hooks(self)
 
     def add_roles_for_users(self, roles, users):
         """


Test patch:
diff --git a/pulpcore/tests/unit/models/test_base.py b/pulpcore/tests/unit/models/test_base.py
--- a/pulpcore/tests/unit/models/test_base.py
+++ b/pulpcore/tests/unit/models/test_base.py
@@ -1,12 +1,8 @@
 import pytest
 from uuid import uuid4
 
-from pulpcore.app.models import Repository
-
-try:
-    from pulp_file.app.models import FileRepository, FileRemote
-except ImportError:
-    pytestmark = pytest.mark.skip("These tests need pulp_file to be installed.")
+from pulpcore.app.models import AutoAddObjPermsMixin, Repository
+from pulp_file.app.models import FileRepository, FileRemote
 
 
 @pytest.mark.django_db
@@ -61,3 +57,15 @@ def test_cast(django_assert_num_queries):
 def test_get_model_for_pulp_type():
     assert Repository.get_model_for_pulp_type("core.repository") is Repository
     assert Repository.get_model_for_pulp_type("file.file") is FileRepository
+
+
+class PermissionRepository(Repository, AutoAddObjPermsMixin):
+    class Meta:
+        app_label = "test"
+        default_related_name = "permission_repository"
+        proxy = True
+
+
+@pytest.mark.django_db
+def test_resiliant_auto_perms():
+    PermissionRepository(name="auto permission test").save()