pulpcore 3.121.3__tar.gz → 3.122.0__tar.gz

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.
Files changed (539) hide show
  1. {pulpcore-3.121.3 → pulpcore-3.122.0}/CHANGES.md +71 -0
  2. {pulpcore-3.121.3 → pulpcore-3.122.0}/PKG-INFO +3 -3
  3. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/app/__init__.py +1 -1
  4. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/__init__.py +1 -1
  5. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/apps.py +1 -1
  6. pulpcore-3.122.0/pulpcore/app/management/commands/clear-cache.py +108 -0
  7. pulpcore-3.122.0/pulpcore/app/migrations/0161_upstreampulp_remote_policy.py +34 -0
  8. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/publication.py +3 -3
  9. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/replica.py +3 -0
  10. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/repository.py +35 -0
  11. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/replica.py +12 -1
  12. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/settings.py +1 -1
  13. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/export.py +7 -2
  14. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/orphan.py +14 -1
  15. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/replica.py +20 -12
  16. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/repository.py +18 -2
  17. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/util.py +42 -8
  18. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/content.py +3 -0
  19. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/repository.py +4 -8
  20. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/cache/cache.py +18 -9
  21. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/content/handler.py +96 -6
  22. pulpcore-3.122.0/pulpcore/pagination.py +78 -0
  23. pulpcore-3.122.0/pulpcore/saml2/backends.py +75 -0
  24. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_replication.py +75 -0
  25. pulpcore-3.122.0/pulpcore/tests/functional/api/using_plugin/test_cdn_cache_validation.py +267 -0
  26. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_orphans.py +7 -1
  27. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_pulpimport.py +13 -4
  28. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_repo_versions.py +71 -0
  29. pulpcore-3.122.0/pulpcore/tests/unit/export/test_local_fs_export.py +48 -0
  30. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_publication_retention.py +9 -10
  31. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_repository.py +26 -1
  32. pulpcore-3.122.0/pulpcore/tests/unit/test_clear_cache_command.py +124 -0
  33. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_gpg_verify.py +61 -0
  34. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_replica.py +34 -1
  35. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore.egg-info/PKG-INFO +3 -3
  36. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore.egg-info/SOURCES.txt +7 -0
  37. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore.egg-info/requires.txt +2 -2
  38. {pulpcore-3.121.3 → pulpcore-3.122.0}/pyproject.toml +4 -4
  39. {pulpcore-3.121.3 → pulpcore-3.122.0}/CODE_OF_CONDUCT.md +0 -0
  40. {pulpcore-3.121.3 → pulpcore-3.122.0}/COMMITMENT +0 -0
  41. {pulpcore-3.121.3 → pulpcore-3.122.0}/CONTRIBUTING.md +0 -0
  42. {pulpcore-3.121.3 → pulpcore-3.122.0}/COPYRIGHT +0 -0
  43. {pulpcore-3.121.3 → pulpcore-3.122.0}/LICENSE +0 -0
  44. {pulpcore-3.121.3 → pulpcore-3.122.0}/MANIFEST.in +0 -0
  45. {pulpcore-3.121.3 → pulpcore-3.122.0}/README.md +0 -0
  46. {pulpcore-3.121.3 → pulpcore-3.122.0}/ci_requirements.txt +0 -0
  47. {pulpcore-3.121.3 → pulpcore-3.122.0}/functest_requirements.txt +0 -0
  48. {pulpcore-3.121.3 → pulpcore-3.122.0}/manage.py +0 -0
  49. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/__init__.py +0 -0
  50. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/app/migrations/0001_initial.py +0 -0
  51. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/app/migrations/0002_alter_rhsmcertguard_contentguard_ptr_and_more.py +0 -0
  52. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/app/migrations/__init__.py +0 -0
  53. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/app/models.py +0 -0
  54. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/app/serializers.py +0 -0
  55. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/app/viewsets.py +0 -0
  56. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/pytest_plugin.py +0 -0
  57. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/rhsm/__init__.py +0 -0
  58. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/rhsm/rhsm_check_path.py +0 -0
  59. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/__init__.py +0 -0
  60. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/__init__.py +0 -0
  61. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/api/__init__.py +0 -0
  62. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/api/test_rhsm_certguard.py +0 -0
  63. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/api/test_x509_certguard.py +0 -0
  64. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/katello-default-ca.crt +0 -0
  65. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/katello-default-ca.key +0 -0
  66. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/trusted_but_expired.pem +0 -0
  67. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/uber.cert +0 -0
  68. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/untrusted_cert-key.pem +0 -0
  69. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/untrusted_cert.pem +0 -0
  70. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v1/1514454871848760713-key.pem +0 -0
  71. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v1/1514454871848760713.pem +0 -0
  72. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v1/159442575569388840-key.pem +0 -0
  73. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v1/159442575569388840.pem +0 -0
  74. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v3/4260035510644027985-key.pem +0 -0
  75. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v3/4260035510644027985.pem +0 -0
  76. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v3/5527980418107729172-key.pem +0 -0
  77. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/rhsm/v3/5527980418107729172.pem +0 -0
  78. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/thirdparty_ca/certificates/ca.pem +0 -0
  79. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/thirdparty_ca/genca.sh +0 -0
  80. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/thirdparty_ca/keys/ca.pem +0 -0
  81. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/certificates/ca.pem +0 -0
  82. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/certificates/client.pem +0 -0
  83. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/certificates/server.pem +0 -0
  84. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/certificates/un_urlencoded_cert.txt +0 -0
  85. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/certificates/untrusted_client.pem +0 -0
  86. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/genall.sh +0 -0
  87. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/genca.sh +0 -0
  88. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/genclient.sh +0 -0
  89. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/gensrv.sh +0 -0
  90. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/keys/ca.pem +0 -0
  91. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/keys/client.pem +0 -0
  92. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/artifacts/x509/keys/server.pem +0 -0
  93. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/conftest.py +0 -0
  94. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/functional/constants.py +0 -0
  95. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/unit/__init__.py +0 -0
  96. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/unit/certdata.py +0 -0
  97. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_certguard/tests/unit/test_rhsm_check_path.py +0 -0
  98. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/__init__.py +0 -0
  99. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/migrations/0001_initial_squashed_0016_add_domain.py +0 -0
  100. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/migrations/0017_alter_filealternatecontentsource_alternatecontentsource_ptr_and_more.py +0 -0
  101. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/migrations/0018_alter_filecontent_options.py +0 -0
  102. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/migrations/0019_add_filegitremote.py +0 -0
  103. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/migrations/0020_filerepository_last_sync_details.py +0 -0
  104. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/migrations/__init__.py +0 -0
  105. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/modelresource.py +0 -0
  106. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/models.py +0 -0
  107. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/replica.py +0 -0
  108. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/serializers.py +0 -0
  109. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/settings.py +0 -0
  110. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/tasks/__init__.py +0 -0
  111. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/tasks/publishing.py +0 -0
  112. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/tasks/synchronizing.py +0 -0
  113. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/app/viewsets.py +0 -0
  114. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/manifest.py +0 -0
  115. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/pytest_plugin.py +0 -0
  116. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/__init__.py +0 -0
  117. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/__init__.py +0 -0
  118. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/__init__.py +0 -0
  119. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_acs.py +0 -0
  120. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_auto_publish.py +0 -0
  121. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_bad_sync.py +0 -0
  122. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_content_labels.py +0 -0
  123. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_crud_content_unit.py +0 -0
  124. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_crud_remotes.py +0 -0
  125. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_distributed_publication.py +0 -0
  126. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_domains.py +0 -0
  127. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_download_policies.py +0 -0
  128. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_filesystem_export.py +0 -0
  129. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_generic_list.py +0 -0
  130. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_git_sync.py +0 -0
  131. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_labels.py +0 -0
  132. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_mime_types.py +0 -0
  133. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_overwrite_content.py +0 -0
  134. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_publish.py +0 -0
  135. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_pulp_export.py +0 -0
  136. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_rbac.py +0 -0
  137. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_remote_settings.py +0 -0
  138. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_sync.py +0 -0
  139. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/functional/api/test_sync_optimization.py +0 -0
  140. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/unit/__init__.py +0 -0
  141. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/unit/test_git_sync.py +0 -0
  142. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/unit/test_safe_paths.py +0 -0
  143. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/unit/test_serializers.py +0 -0
  144. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulp_file/tests/unit/test_sync_optimization.py +0 -0
  145. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/__init__.py +0 -0
  146. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/__init__.py +0 -0
  147. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/access_policy.py +0 -0
  148. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/authentication.py +0 -0
  149. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/checks.py +0 -0
  150. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/contexts.py +0 -0
  151. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/entrypoint.py +0 -0
  152. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/files.py +0 -0
  153. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/find_url.py +0 -0
  154. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/global_access_conditions.py +0 -0
  155. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/importexport.py +0 -0
  156. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/loggers.py +0 -0
  157. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/manage.py +0 -0
  158. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/__init__.py +0 -0
  159. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/__init__.py +0 -0
  160. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/add-signing-service.py +0 -0
  161. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/analyze-publication.py +0 -0
  162. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/clean-up-progress-reports.py +0 -0
  163. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/datarepair-2327.py +0 -0
  164. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/datarepair.py +0 -0
  165. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/dump-permissions.py +0 -0
  166. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/dump-publications-to-fs.py +0 -0
  167. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/handle-artifact-checksums.py +0 -0
  168. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/list-signing-services.py +0 -0
  169. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/migrationstat.py +0 -0
  170. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/openapi.py +0 -0
  171. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/optimizemigration.py +0 -0
  172. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/rebasemigrations.py +0 -0
  173. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/remove-plugin.py +0 -0
  174. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/remove-signing-service.py +0 -0
  175. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/repository-size.py +0 -0
  176. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/reset-admin-password.py +0 -0
  177. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/rotate-db-key.py +0 -0
  178. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/management/commands/shell.py +0 -0
  179. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0001_squashed_0090_char_to_text_field.py +0 -0
  180. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0091_systemid.py +0 -0
  181. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0092_alter_upload_options.py +0 -0
  182. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0093_add_info_field_repositoryversion.py +0 -0
  183. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0094_protect_repository_content.py +0 -0
  184. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0095_artifactdistribution.py +0 -0
  185. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0096_alter_task_logging_cid.py +0 -0
  186. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0097_remove_telemetry_task_schedule.py +0 -0
  187. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0098_pulp_labels.py +0 -0
  188. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0099_versions_field.py +0 -0
  189. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0100_upstreampulp.py +0 -0
  190. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0101_add_domain.py +0 -0
  191. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0102_add_domain_relations.py +0 -0
  192. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0103_alter_export_task.py +0 -0
  193. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0104_delete_label.py +0 -0
  194. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0105_abstract_uuid_gen.py +0 -0
  195. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0106_alter_artifactdistribution_distribution_ptr_and_more.py +0 -0
  196. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0107_distribution_hidden.py +0 -0
  197. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0108_task_versions.py +0 -0
  198. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0109_contentartifact_relative_path_index.py +0 -0
  199. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0110_apiappstatus.py +0 -0
  200. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0111_task_enc_args_task_enc_kwargs.py +0 -0
  201. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0112_alter_upstreampulp_options.py +0 -0
  202. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0113_headercontentguard.py +0 -0
  203. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0114_remove_task_args_remove_task_kwargs.py +0 -0
  204. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0115_compositecontentguard.py +0 -0
  205. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0116_alter_remoteartifact_md5_alter_remoteartifact_sha1_and_more.py +0 -0
  206. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0117_task_unblocked_at.py +0 -0
  207. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0118_task_core_task_unblock_2276a4_idx_and_more.py +0 -0
  208. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0119_grouprole_core_groupr_object__250e22_idx_and_more.py +0 -0
  209. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0120_get_url_removal.py +0 -0
  210. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0121_add_profile_artifacts_table.py +0 -0
  211. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0122_record_last_replication_timestamp.py +0 -0
  212. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0123_upstreampulp_q_select.py +0 -0
  213. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0124_task_deferred_task_immediate.py +0 -0
  214. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0125_openpgpdistribution_openpgpkeyring_openpgppublickey_and_more.py +0 -0
  215. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0126_remoteartifact_failed_at.py +0 -0
  216. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0127_remove_upstreampulp_pulp_label_select.py +0 -0
  217. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0128_domain_pulp_labels.py +0 -0
  218. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0129_content_pulp_labels.py +0 -0
  219. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0130_upstreampulp_policy.py +0 -0
  220. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0131_distribution_checkpoint_publication_checkpoint.py +0 -0
  221. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0132_alter_content_options.py +0 -0
  222. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0132_task_profile_options.py +0 -0
  223. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0133_repositoryversion_content_ids.py +0 -0
  224. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0134_task_insert_trigger.py +0 -0
  225. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0135_task_pulp_task_resources_index.py +0 -0
  226. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0136_delete_basedistribution.py +0 -0
  227. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0137_appstatus.py +0 -0
  228. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0138_vulnerabilityreport.py +0 -0
  229. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0139_task_app_lock.py +0 -0
  230. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0140_require_appstatus_zdu.py +0 -0
  231. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0141_alter_appstatus_name.py +0 -0
  232. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0142_task_result.py +0 -0
  233. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0143_require_app_lock_zdu.py +0 -0
  234. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0144_delete_old_appstatus.py +0 -0
  235. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0145_domainize_import_export.py +0 -0
  236. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0146_repository_retain_checkpoints.py +0 -0
  237. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0147_content_pulp_labels_gin.py +0 -0
  238. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0148_artifact_artifact_domain_size_index.py +0 -0
  239. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0149_distributedpublication.py +0 -0
  240. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0150_taskschedule_task_kwargs.py +0 -0
  241. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0151_upstreampulp_connect_timeout_and_more.py +0 -0
  242. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0152_alter_repositoryversion_content_ids.py +0 -0
  243. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0153_taskschedule_pulp_domain_alter_taskschedule_name_and_more.py +0 -0
  244. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0154_task_api_version.py +0 -0
  245. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0155_create_rel_path_domains.py +0 -0
  246. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0156_alter_contentartifact_relative_path_and_more.py +0 -0
  247. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0157_distribution_base_path_constraint.py +0 -0
  248. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0158_domain_default_content_guard.py +0 -0
  249. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0159_alter_contentartifact_relative_path_and_more.py +0 -0
  250. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/0160_envvarheadercontentguard.py +0 -0
  251. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/migrations/__init__.py +0 -0
  252. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/mime_types.py +0 -0
  253. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/modelresource.py +0 -0
  254. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/__init__.py +0 -0
  255. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/access_policy.py +0 -0
  256. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/acs.py +0 -0
  257. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/analytics.py +0 -0
  258. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/base.py +0 -0
  259. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/content.py +0 -0
  260. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/domain.py +0 -0
  261. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/exporter.py +0 -0
  262. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/fields.py +0 -0
  263. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/generic.py +0 -0
  264. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/importer.py +0 -0
  265. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/openpgp.py +0 -0
  266. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/progress.py +0 -0
  267. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/role.py +0 -0
  268. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/status.py +0 -0
  269. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/storage.py +0 -0
  270. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/task.py +0 -0
  271. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/upload.py +0 -0
  272. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/models/vulnerability_report.py +0 -0
  273. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/netutil.py +0 -0
  274. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/openpgp.py +0 -0
  275. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/protobuf/__init__.py +0 -0
  276. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/protobuf/analytics_pb2.py +0 -0
  277. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/pulp_hashlib.py +0 -0
  278. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/pulpcore_gunicorn_application.py +0 -0
  279. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/redis_connection.py +0 -0
  280. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/replica.py +0 -0
  281. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/response.py +0 -0
  282. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/role_util.py +0 -0
  283. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/__init__.py +0 -0
  284. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/access_policy.py +0 -0
  285. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/acs.py +0 -0
  286. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/base.py +0 -0
  287. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/content.py +0 -0
  288. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/domain.py +0 -0
  289. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/exporter.py +0 -0
  290. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/fields.py +0 -0
  291. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/importer.py +0 -0
  292. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/openpgp.py +0 -0
  293. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/orphans.py +0 -0
  294. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/progress.py +0 -0
  295. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/publication.py +0 -0
  296. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/purge.py +0 -0
  297. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/reclaim.py +0 -0
  298. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/repair.py +0 -0
  299. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/repository.py +0 -0
  300. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/status.py +0 -0
  301. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/task.py +0 -0
  302. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/upload.py +0 -0
  303. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/user.py +0 -0
  304. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/serializers/vulnerability_report.py +0 -0
  305. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/__init__.py +0 -0
  306. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/analytics.py +0 -0
  307. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/base.py +0 -0
  308. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/datarepair.py +0 -0
  309. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/importer.py +0 -0
  310. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/migrate.py +0 -0
  311. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/purge.py +0 -0
  312. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/reclaim_space.py +0 -0
  313. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/telemetry.py +0 -0
  314. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/test.py +0 -0
  315. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/upload.py +0 -0
  316. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/tasks/vulnerability_report.py +0 -0
  317. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/templates/rest_framework/api.html +0 -0
  318. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/templatetags/__init__.py +0 -0
  319. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/templatetags/pulp_urls.py +0 -0
  320. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/urls.py +0 -0
  321. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/views/__init__.py +0 -0
  322. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/views/datarepair.py +0 -0
  323. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/views/importer.py +0 -0
  324. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/views/orphans.py +0 -0
  325. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/views/repair.py +0 -0
  326. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/views/status.py +0 -0
  327. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/__init__.py +0 -0
  328. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/access_policy.py +0 -0
  329. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/acs.py +0 -0
  330. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/base.py +0 -0
  331. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/custom_filters.py +0 -0
  332. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/domain.py +0 -0
  333. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/exporter.py +0 -0
  334. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/importer.py +0 -0
  335. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/openpgp.py +0 -0
  336. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/orphans.py +0 -0
  337. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/publication.py +0 -0
  338. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/reclaim.py +0 -0
  339. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/replica.py +0 -0
  340. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/task.py +0 -0
  341. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/upload.py +0 -0
  342. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/user.py +0 -0
  343. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/viewsets/vulnerability_report.py +0 -0
  344. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/workload_identity/__init__.py +0 -0
  345. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/workload_identity/authentication.py +0 -0
  346. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/workload_identity/authz.py +0 -0
  347. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/workload_identity/backend.py +0 -0
  348. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/workload_identity/config.py +0 -0
  349. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/workload_identity/principal.py +0 -0
  350. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/workload_identity/rules.py +0 -0
  351. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/app/wsgi.py +0 -0
  352. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/backends.py +0 -0
  353. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/cache/__init__.py +0 -0
  354. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/constants.py +0 -0
  355. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/content/__init__.py +0 -0
  356. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/content/authentication.py +0 -0
  357. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/content/entrypoint.py +0 -0
  358. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/content/instrumentation.py +0 -0
  359. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/download/__init__.py +0 -0
  360. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/download/base.py +0 -0
  361. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/download/factory.py +0 -0
  362. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/download/file.py +0 -0
  363. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/download/http.py +0 -0
  364. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/exceptions/__init__.py +0 -0
  365. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/exceptions/base.py +0 -0
  366. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/exceptions/plugin.py +0 -0
  367. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/exceptions/validation.py +0 -0
  368. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/filters.py +0 -0
  369. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/metrics.py +0 -0
  370. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/middleware.py +0 -0
  371. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/migrations.py +0 -0
  372. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/openapi/__init__.py +0 -0
  373. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/openapi/hooks.py +0 -0
  374. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/__init__.py +0 -0
  375. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/access_policy.py +0 -0
  376. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/actions.py +0 -0
  377. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/apps.py +0 -0
  378. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/authentication/__init__.py +0 -0
  379. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/cache/__init__.py +0 -0
  380. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/constants.py +0 -0
  381. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/content.py +0 -0
  382. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/download/__init__.py +0 -0
  383. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/exceptions.py +0 -0
  384. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/files.py +0 -0
  385. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/find_url.py +0 -0
  386. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/importexport.py +0 -0
  387. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/migrations.py +0 -0
  388. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/modelresources.py +0 -0
  389. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/models/__init__.py +0 -0
  390. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/models/role.py +0 -0
  391. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/publication_utils.py +0 -0
  392. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/pulp_hashlib.py +0 -0
  393. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/replica.py +0 -0
  394. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/repo_version_utils.py +0 -0
  395. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/responses.py +0 -0
  396. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/serializers/__init__.py +0 -0
  397. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/serializers/content.py +0 -0
  398. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/stages/__init__.py +0 -0
  399. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/stages/api.py +0 -0
  400. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/stages/artifact_stages.py +0 -0
  401. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/stages/content_stages.py +0 -0
  402. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/stages/declarative_version.py +0 -0
  403. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/stages/models.py +0 -0
  404. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/storage.py +0 -0
  405. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/sync.py +0 -0
  406. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/tasking.py +0 -0
  407. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/util.py +0 -0
  408. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/viewsets/__init__.py +0 -0
  409. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/plugin/viewsets/content.py +0 -0
  410. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/pytest_plugin.py +0 -0
  411. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/responses.py +0 -0
  412. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/__init__.py +0 -0
  413. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/_util.py +0 -0
  414. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/entrypoint.py +0 -0
  415. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/kafka.py +0 -0
  416. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/redis_locks.py +0 -0
  417. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/redis_tasks.py +0 -0
  418. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/redis_worker.py +0 -0
  419. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/storage.py +0 -0
  420. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/tasks.py +0 -0
  421. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tasking/worker.py +0 -0
  422. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/__init__.py +0 -0
  423. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/__init__.py +0 -0
  424. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/__init__.py +0 -0
  425. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_access_policy.py +0 -0
  426. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_api_docs.py +0 -0
  427. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_api_root_rewrite.py +0 -0
  428. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_artifact_distribution.py +0 -0
  429. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_auth.py +0 -0
  430. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_correlation_id.py +0 -0
  431. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_crd_artifacts.py +0 -0
  432. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_crud_domains.py +0 -0
  433. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_filter.py +0 -0
  434. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_login.py +0 -0
  435. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_openapi_schema.py +0 -0
  436. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_openpgp.py +0 -0
  437. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_repos.py +0 -0
  438. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_role.py +0 -0
  439. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_root_endpoint.py +0 -0
  440. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_scoping.py +0 -0
  441. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_signing_service.py +0 -0
  442. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_status.py +0 -0
  443. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_task_purge.py +0 -0
  444. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_tasking.py +0 -0
  445. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_upload.py +0 -0
  446. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_users_groups.py +0 -0
  447. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_v4_status.py +0 -0
  448. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/test_workers.py +0 -0
  449. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/__init__.py +0 -0
  450. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_checkpoint.py +0 -0
  451. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_content_access.py +0 -0
  452. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_content_cache.py +0 -0
  453. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_content_delivery.py +0 -0
  454. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_content_directory.py +0 -0
  455. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_content_path.py +0 -0
  456. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_content_promotion.py +0 -0
  457. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_contentguard.py +0 -0
  458. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_crud_repos.py +0 -0
  459. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_distributions.py +0 -0
  460. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_filesystemexport.py +0 -0
  461. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_labels.py +0 -0
  462. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_migrate.py +0 -0
  463. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_pagination.py +0 -0
  464. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_prn.py +0 -0
  465. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_proxy.py +0 -0
  466. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_reclaim_disk_space.py +0 -0
  467. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_repair.py +0 -0
  468. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_tasks.py +0 -0
  469. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/api/using_plugin/test_unlinking_repo.py +0 -0
  470. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/assets/__init__.py +0 -0
  471. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/content_with_coverage.py +0 -0
  472. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/functional/utils.py +0 -0
  473. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/performance/__init__.py +0 -0
  474. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/performance/test_performance.py +0 -0
  475. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/__init__.py +0 -0
  476. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/conftest.py +0 -0
  477. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/content/__init__.py +0 -0
  478. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/content/test_handler.py +0 -0
  479. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/content/test_heartbeat.py +0 -0
  480. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/download/__init__.py +0 -0
  481. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/download/test_downloader_base.py +0 -0
  482. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/download/test_downloader_factory.py +0 -0
  483. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/download/test_downloader_file.py +0 -0
  484. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/metrics/__init__.py +0 -0
  485. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/metrics/conftest.py +0 -0
  486. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/metrics/test_aiohttp_instrumentation.py +0 -0
  487. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/metrics/test_django_instrumentation.py +0 -0
  488. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/migration/__init__.py +0 -0
  489. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/__init__.py +0 -0
  490. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_base.py +0 -0
  491. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_content.py +0 -0
  492. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_content_ids_migration.py +0 -0
  493. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_distribution.py +0 -0
  494. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_remote.py +0 -0
  495. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/models/test_task.py +0 -0
  496. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/roles/__init__.py +0 -0
  497. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/roles/test_adjust_roles.py +0 -0
  498. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/roles/test_roles.py +0 -0
  499. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/__init__.py +0 -0
  500. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/test_base.py +0 -0
  501. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/test_domain.py +0 -0
  502. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/test_fields.py +0 -0
  503. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/test_orphans_cleanup.py +0 -0
  504. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/test_pulpexport.py +0 -0
  505. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/test_repository.py +0 -0
  506. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/serializers/test_user.py +0 -0
  507. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/stages/__init__.py +0 -0
  508. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/stages/test_artifactdownloader.py +0 -0
  509. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/stages/test_resource_budget.py +0 -0
  510. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/stages/test_stages.py +0 -0
  511. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/tasking/__init__.py +0 -0
  512. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/tasking/test_delete_tasks.py +0 -0
  513. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/tasking/test_missing_worker_cleanup.py +0 -0
  514. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/tasking/test_orphan_redis_locks.py +0 -0
  515. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/tasking/test_redis_fetch_task.py +0 -0
  516. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/tasking/test_waiting_tasks_metric.py +0 -0
  517. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_cache.py +0 -0
  518. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_chunked_file.py +0 -0
  519. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_content_guard.py +0 -0
  520. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_fetch_task_hol_blocking.py +0 -0
  521. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_files.py +0 -0
  522. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_import_checks.py +0 -0
  523. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_list_signing_services_command.py +0 -0
  524. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_middleware.py +0 -0
  525. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_pulp_urls.py +0 -0
  526. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_settings.py +0 -0
  527. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_util.py +0 -0
  528. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_viewsets.py +0 -0
  529. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/test_vulnerability_report.py +0 -0
  530. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/viewsets/__init__.py +0 -0
  531. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/viewsets/test_viewset_base.py +0 -0
  532. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/workload_identity/__init__.py +0 -0
  533. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore/tests/unit/workload_identity/test_workload_identity.py +0 -0
  534. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore.egg-info/dependency_links.txt +0 -0
  535. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore.egg-info/entry_points.txt +0 -0
  536. {pulpcore-3.121.3 → pulpcore-3.122.0}/pulpcore.egg-info/top_level.txt +0 -0
  537. {pulpcore-3.121.3 → pulpcore-3.122.0}/setup.cfg +0 -0
  538. {pulpcore-3.121.3 → pulpcore-3.122.0}/test_requirements.txt +0 -0
  539. {pulpcore-3.121.3 → pulpcore-3.122.0}/unittest_requirements.txt +0 -0
@@ -8,6 +8,49 @@
8
8
 
9
9
  [//]: # (towncrier release notes start)
10
10
 
11
+ ## 3.122.0 (2026-10-14) {: #3.122.0 }
12
+
13
+ ### REST API {: #3.122.0-rest-api }
14
+
15
+ #### Features {: #3.122.0-rest-api-feature }
16
+
17
+ - Added `ETag`/`If-None-Match` and `Last-Modified`/`If-Modified-Since` (`304 Not Modified`) support on content-app responses so edge caches can revalidate without re-downloading.
18
+ [#7929](https://github.com/pulp/pulpcore/issues/7929)
19
+ - Added a `pulpcore-manager clear-cache` command to clear cached content responses globally or by repository, distribution, or base path.
20
+ [#8165](https://github.com/pulp/pulpcore/issues/8165)
21
+ - Added `UpstreamPulp.remote_policy` so remotes created during replication can use `on_demand` or `streamed` instead of defaulting to `immediate`.
22
+ - Added an authentication backend for SAML2 attribute based authorization.
23
+
24
+ #### Bugfixes {: #3.122.0-rest-api-bugfix }
25
+
26
+ - Use repository-version summaries to speed unfiltered content-list pagination counts.
27
+ [#PULP-1996](https://github.com/pulp/pulpcore/issues/PULP-1996)
28
+ - Fixed a bug where filesystem export trying to use local on demand files can be tricked breaking out of `ALLOWED_IMPORT_PATHS`.
29
+ - Fixed an issue where users were able to list (but not modify) uploads they didn't have permissions to view.
30
+ - Fixed directory listings for published content displaying publication time instead of repository added date.
31
+ - Optimized `scope_queryset` SQL queries when using a domain scoped endpoint.
32
+ - Orphan cleanup with `content_hrefs` now deletes only artifacts associated with the selected content.
33
+ - Removed parent directory sizes and fixed wrong last modified timestamp in content app listings.
34
+ - Repeated object lookups in a single API request now reuse the retrieved object.
35
+ - Reverted support for returning 304 responses to content requests with conditional headers
36
+ because of a breaking change in the internal plugin's API.
37
+
38
+ ### Plugin API {: #3.122.0-plugin-api }
39
+
40
+ #### Features {: #3.122.0-plugin-api-feature }
41
+
42
+ - Made `add_and_remove` and `aadd_and_remove` return the serialized newly created repository version as the task result.
43
+
44
+ ### Pulp File {: #3.122.0-pulp-file }
45
+
46
+ No significant changes.
47
+
48
+ ### Pulp Cert Guard {: #3.122.0-pulp-cert-guard }
49
+
50
+ No significant changes.
51
+
52
+ ---
53
+
11
54
  ## 3.121.3 (2026-10-09) {: #3.121.3 }
12
55
 
13
56
  ### REST API {: #3.121.3-rest-api }
@@ -218,6 +261,34 @@ No significant changes.
218
261
 
219
262
  ---
220
263
 
264
+ ## 3.118.2 (2026-10-13) {: #3.118.2 }
265
+
266
+ ### REST API {: #3.118.2-rest-api }
267
+
268
+ #### Bugfixes {: #3.118.2-rest-api-bugfix }
269
+
270
+ - Avoid loading repository version content IDs when serving fallback content during the grace period.
271
+ - Fixed an issue where users were able to list (but not modify) uploads they didn't have permissions to view.
272
+ - Fixed directory listings for published content displaying publication time instead of repository added date.
273
+ - Fixed vulnerability report rescans to update existing reports.
274
+ - Optimized `scope_queryset` SQL queries when using a domain scoped endpoint.
275
+ - Removed parent directory sizes and fixed wrong last modified timestamp in content app listings.
276
+ - Repeated object lookups in a single API request now reuse the retrieved object.
277
+
278
+ ### Plugin API {: #3.118.2-plugin-api }
279
+
280
+ No significant changes.
281
+
282
+ ### Pulp File {: #3.118.2-pulp-file }
283
+
284
+ No significant changes.
285
+
286
+ ### Pulp Cert Guard {: #3.118.2-pulp-cert-guard }
287
+
288
+ No significant changes.
289
+
290
+ ---
291
+
221
292
  ## 3.118.1 (2026-09-17) {: #3.118.1 }
222
293
 
223
294
  ### REST API {: #3.118.1-rest-api }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pulpcore
3
- Version: 3.121.3
3
+ Version: 3.122.0
4
4
  Summary: Pulp Django Application and Related Modules
5
5
  Author-email: Pulp Team <pulp-list@redhat.com>
6
6
  License-Expression: GPL-2.0-or-later
@@ -27,7 +27,7 @@ Requires-Dist: click<8.6,>=8.1.0
27
27
  Requires-Dist: cryptography<51.0,>=49.0.0
28
28
  Requires-Dist: pyjwt<3,>=2.4
29
29
  Requires-Dist: Django<5.3,>=5.2.0
30
- Requires-Dist: django-filter<=26.1,>=24.3
30
+ Requires-Dist: django-filter<=26.2,>=24.3
31
31
  Requires-Dist: django-guid<3.7,>=3.4.0
32
32
  Requires-Dist: django-import-export<5.0,>=2.9
33
33
  Requires-Dist: django-lifecycle<=1.3.0,>=1.0
@@ -78,7 +78,7 @@ Provides-Extra: diagnostics
78
78
  Requires-Dist: pyinstrument~=5.0; extra == "diagnostics"
79
79
  Requires-Dist: memray~=1.17; extra == "diagnostics"
80
80
  Provides-Extra: uvloop
81
- Requires-Dist: uvloop<0.22,>=0.20; extra == "uvloop"
81
+ Requires-Dist: uvloop<0.24,>=0.20; extra == "uvloop"
82
82
  Dynamic: license-file
83
83
 
84
84
 
@@ -6,6 +6,6 @@ class PulpCertGuardPluginAppConfig(PulpPluginAppConfig):
6
6
 
7
7
  name = "pulp_certguard.app"
8
8
  label = "certguard"
9
- version = "3.121.3"
9
+ version = "3.122.0"
10
10
  python_package_name = "pulpcore"
11
11
  domain_compatible = True
@@ -8,6 +8,6 @@ class PulpFilePluginAppConfig(PulpPluginAppConfig):
8
8
 
9
9
  name = "pulp_file.app"
10
10
  label = "file"
11
- version = "3.121.3"
11
+ version = "3.122.0"
12
12
  python_package_name = "pulpcore"
13
13
  domain_compatible = True
@@ -238,7 +238,7 @@ class PulpAppConfig(PulpPluginAppConfig):
238
238
  label = "core"
239
239
 
240
240
  # The version of this app
241
- version = "3.121.3"
241
+ version = "3.122.0"
242
242
 
243
243
  # The python package name providing this app
244
244
  python_package_name = "pulpcore"
@@ -0,0 +1,108 @@
1
+ from gettext import gettext as _
2
+
3
+ from django.conf import settings
4
+ from django.core.management import BaseCommand, CommandError
5
+ from django.db.models import Q
6
+ from rest_framework.exceptions import ValidationError
7
+
8
+ from pulpcore.app.models import Distribution, Repository
9
+ from pulpcore.app.util import cache_key, resolve_prn
10
+ from pulpcore.cache import Cache
11
+
12
+
13
+ def resolve_resources(resources, model):
14
+ """Resolve resource names and PRNs to a queryset filter."""
15
+ pks = []
16
+ names = []
17
+ for resource in resources:
18
+ if resource.startswith("prn:"):
19
+ try:
20
+ resource_model, pk = resolve_prn(resource)
21
+ except ValidationError as exc:
22
+ raise CommandError(str(exc))
23
+ if not issubclass(resource_model, model):
24
+ raise CommandError(f"{resource} is not a {model.__name__} PRN.")
25
+ pks.append(pk)
26
+ else:
27
+ names.append(resource)
28
+ return Q(pk__in=pks) | Q(name__in=names)
29
+
30
+
31
+ class Command(BaseCommand):
32
+ """Clear cached content responses."""
33
+
34
+ help = "Clear cached content responses, optionally for repositories or distributions."
35
+
36
+ def add_arguments(self, parser):
37
+ """Set up arguments."""
38
+ parser.add_argument(
39
+ "--repository",
40
+ action="append",
41
+ help=_("Repository name or PRN to clear. May be specified more than once."),
42
+ )
43
+ parser.add_argument(
44
+ "--distribution",
45
+ action="append",
46
+ help=_("Distribution name or PRN to clear. May be specified more than once."),
47
+ )
48
+ parser.add_argument(
49
+ "--base-path",
50
+ action="append",
51
+ help=_("Base path to clear directly. May be specified more than once."),
52
+ )
53
+ parser.add_argument(
54
+ "--domain",
55
+ help=_("Domain name to clear or use with resource names."),
56
+ )
57
+
58
+ def handle(self, *args, **options):
59
+ """Clear the selected content cache entries."""
60
+ if not settings.CACHE_ENABLED:
61
+ raise CommandError("Content caching is not enabled.")
62
+
63
+ repositories = options["repository"]
64
+ distributions = options["distribution"]
65
+ base_paths = options["base_path"]
66
+ if isinstance(repositories, str):
67
+ repositories = [repositories]
68
+ if isinstance(distributions, str):
69
+ distributions = [distributions]
70
+ if isinstance(base_paths, str):
71
+ base_paths = [base_paths]
72
+ domain = options["domain"]
73
+ distribution_queryset = Distribution.objects.all()
74
+ if base_paths:
75
+ if settings.DOMAIN_ENABLED and not domain:
76
+ raise CommandError(
77
+ "--domain is required with --base-path when domains are enabled."
78
+ )
79
+ base_keys = cache_key(base_paths, domain=domain)
80
+ elif repositories:
81
+ selected_repositories = Repository.objects.filter(
82
+ resolve_resources(repositories, Repository)
83
+ )
84
+ distribution_queryset = distribution_queryset.filter(
85
+ Q(repository__in=selected_repositories)
86
+ | Q(repository_version__repository__in=selected_repositories)
87
+ | Q(publication__repository_version__repository__in=selected_repositories)
88
+ )
89
+ elif distributions:
90
+ distribution_queryset = distribution_queryset.filter(
91
+ resolve_resources(distributions, Distribution)
92
+ )
93
+
94
+ if not base_paths:
95
+ if domain:
96
+ distribution_queryset = distribution_queryset.filter(pulp_domain__name=domain)
97
+ if settings.DOMAIN_ENABLED:
98
+ base_keys = [
99
+ cache_key(distribution.base_path, domain=distribution.pulp_domain)
100
+ for distribution in distribution_queryset.select_related("pulp_domain")
101
+ ]
102
+ else:
103
+ base_keys = list(distribution_queryset.values_list("base_path", flat=True))
104
+
105
+ cleared_entries = Cache().delete(base_key=base_keys) if base_keys else 0
106
+ self.stdout.write(
107
+ f"Cleared {cleared_entries} cache entr{'y' if cleared_entries == 1 else 'ies'}."
108
+ )
@@ -0,0 +1,34 @@
1
+ from django.db import migrations, models
2
+
3
+
4
+ class Migration(migrations.Migration):
5
+
6
+ dependencies = [
7
+ ("core", "0160_envvarheadercontentguard"),
8
+ ]
9
+
10
+ operations = [
11
+ migrations.AddField(
12
+ model_name="upstreampulp",
13
+ name="remote_policy",
14
+ field=models.TextField(
15
+ choices=[
16
+ ("immediate", "When syncing, download all metadata and content now."),
17
+ (
18
+ "on_demand",
19
+ "When syncing, download metadata, but do not download content now. "
20
+ "Instead, download content as clients request it, and save it in Pulp "
21
+ "to be served for future client requests.",
22
+ ),
23
+ (
24
+ "streamed",
25
+ "When syncing, download metadata, but do not download content now. "
26
+ "Instead,download content as clients request it, but never save it in "
27
+ "Pulp. This causes future requests for that same content to have to be "
28
+ "downloaded again.",
29
+ ),
30
+ ],
31
+ null=True,
32
+ ),
33
+ ),
34
+ ]
@@ -868,7 +868,7 @@ class Distribution(MasterModel):
868
868
 
869
869
  def get_fallback_ca(self, path):
870
870
  """
871
- Return a ContentArtifact for path from the grace-period publication history, or None.
871
+ Return the ContentArtifact and RepositoryVersion for path from publication history, or None.
872
872
 
873
873
  Iterates DistributedPublication records for this distribution from newest to oldest,
874
874
  trying each publication until the path is found. Handles both pass-through and
@@ -894,7 +894,7 @@ class Distribution(MasterModel):
894
894
  .first()
895
895
  )
896
896
  if ca is not None:
897
- return ca
897
+ return ca, pub.repository_version
898
898
  else:
899
899
  pa = (
900
900
  pub.published_artifact.select_related(
@@ -905,7 +905,7 @@ class Distribution(MasterModel):
905
905
  .first()
906
906
  )
907
907
  if pa is not None:
908
- return pa.content_artifact
908
+ return pa.content_artifact, pub.repository_version
909
909
  return None
910
910
 
911
911
  @hook(BEFORE_CREATE)
@@ -11,6 +11,8 @@ from django.db import models
11
11
  from pulpcore.app.util import get_domain_pk
12
12
  from pulpcore.plugin.models import AutoAddObjPermsMixin, BaseModel, EncryptedTextField
13
13
 
14
+ from .repository import Remote
15
+
14
16
 
15
17
  class UpstreamPulp(BaseModel, AutoAddObjPermsMixin):
16
18
  ALL = "all"
@@ -59,6 +61,7 @@ class UpstreamPulp(BaseModel, AutoAddObjPermsMixin):
59
61
  sock_read_timeout = models.FloatField(
60
62
  null=True, validators=[MinValueValidator(0.0, "Timeout must be >= 0")]
61
63
  )
64
+ remote_policy = models.TextField(choices=Remote.POLICY_CHOICES, null=True)
62
65
 
63
66
  q_select = models.TextField(null=True)
64
67
  policy = models.TextField(choices=POLICY_CHOICES, default=ALL)
@@ -983,6 +983,41 @@ class RepositoryVersion(BaseModel):
983
983
  get_latest_by = "number"
984
984
  ordering = ("number",)
985
985
 
986
+ def _summary_counts(self):
987
+ """Return cached summary counts, loading all rows at most once."""
988
+ if not hasattr(self, "_repository_version_summary_counts"):
989
+ self._repository_version_summary_counts = {
990
+ (item.content_type, item.count_type): item.count for item in self.counts.all()
991
+ }
992
+ return self._repository_version_summary_counts
993
+
994
+ def _get_count(self, content_type, count_type):
995
+ """Return a count for one content type or sum counts across all types."""
996
+ counts = self._summary_counts()
997
+ if content_type is not None:
998
+ return counts.get((content_type, count_type), 0)
999
+ return sum(
1000
+ value
1001
+ for (item_type, item_count_type), value in counts.items()
1002
+ if item_count_type == count_type
1003
+ )
1004
+
1005
+ def has_count(self, content_type, count_type):
1006
+ """Return whether a persisted summary exists for a content type and count type."""
1007
+ return (content_type, count_type) in self._summary_counts()
1008
+
1009
+ def count(self, content_type=None):
1010
+ """Return the number of present content units, optionally by type."""
1011
+ return self._get_count(content_type, RepositoryVersionContentDetails.PRESENT)
1012
+
1013
+ def added_count(self, content_type=None):
1014
+ """Return the number of content units added, optionally by type."""
1015
+ return self._get_count(content_type, RepositoryVersionContentDetails.ADDED)
1016
+
1017
+ def removed_count(self, content_type=None):
1018
+ """Return the number of content units removed, optionally by type."""
1019
+ return self._get_count(content_type, RepositoryVersionContentDetails.REMOVED)
1020
+
986
1021
  def _content_relationships(self):
987
1022
  """
988
1023
  Returns a set of repository_content for a repository version
@@ -3,7 +3,7 @@ from gettext import gettext as _
3
3
  from rest_framework import serializers
4
4
  from rest_framework.validators import UniqueValidator
5
5
 
6
- from pulpcore.app.models import UpstreamPulp
6
+ from pulpcore.app.models import Remote, UpstreamPulp
7
7
  from pulpcore.app.serializers import (
8
8
  HiddenFieldsMixin,
9
9
  IdentityField,
@@ -122,6 +122,16 @@ class UpstreamPulpSerializer(ModelSerializer, HiddenFieldsMixin):
122
122
  ),
123
123
  min_value=0.0,
124
124
  )
125
+ remote_policy = serializers.ChoiceField(
126
+ choices=Remote.POLICY_CHOICES,
127
+ help_text=_(
128
+ "Download policy for remotes created during replication. One of 'immediate', "
129
+ "'on_demand', or 'streamed'. Distinct from 'policy', which controls how replicate "
130
+ "manages local objects. Defaults to the Remote default ('immediate') when unset."
131
+ ),
132
+ required=False,
133
+ allow_null=True,
134
+ )
125
135
 
126
136
  pulp_last_updated = serializers.DateTimeField(
127
137
  help_text="Timestamp of the most recent update of the remote.", read_only=True
@@ -178,6 +188,7 @@ class UpstreamPulpSerializer(ModelSerializer, HiddenFieldsMixin):
178
188
  "connect_timeout",
179
189
  "sock_connect_timeout",
180
190
  "sock_read_timeout",
191
+ "remote_policy",
181
192
  "pulp_last_updated",
182
193
  "hidden_fields",
183
194
  "q_select",
@@ -616,7 +616,7 @@ def saml2_settings_hook(settings):
616
616
  if "SAML_CONFIG" in settings:
617
617
  data["INSTALLED_APPS"] = ["djangosaml2"]
618
618
  data["MIDDLEWARE"] = ["djangosaml2.middleware.SamlSessionMiddleware"]
619
- data["AUTHENTICATION_BACKENDS"] = ["djangosaml2.backends.Saml2Backend"]
619
+ data["AUTHENTICATION_BACKENDS"] = ["pulpcore.saml2.backends.PulpSaml2Backend"]
620
620
  if "LOGIN_URL" not in settings:
621
621
  data["LOGIN_URL"] = "/saml2/login/"
622
622
  if "SESSION_COOKIE_SECURE" not in settings:
@@ -7,7 +7,7 @@ import tarfile
7
7
  from gettext import gettext as _
8
8
  from glob import glob
9
9
  from pathlib import Path
10
- from urllib.parse import unquote, urlparse
10
+ from urllib.parse import urlparse
11
11
 
12
12
  from django.conf import settings
13
13
 
@@ -97,7 +97,12 @@ def _validate_fs_export(content_artifacts):
97
97
  def _local_path_from_file_url(url):
98
98
  """Convert a file:// URL to an absolute local filesystem path."""
99
99
  parsed = urlparse(url)
100
- return os.path.abspath(os.path.join(parsed.netloc, unquote(parsed.path)))
100
+ if parsed.netloc not in ["", "localhost"]:
101
+ raise UnexportableArtifactException()
102
+ path = Path(parsed.path).resolve()
103
+ if not any(path.is_relative_to(allowed) for allowed in settings.ALLOWED_IMPORT_PATHS):
104
+ raise UnexportableArtifactException()
105
+ return str(path)
101
106
 
102
107
 
103
108
  def _file_url_local_paths(content_artifacts):
@@ -8,6 +8,7 @@ from django.utils import timezone
8
8
  from pulpcore.app.models import (
9
9
  Artifact,
10
10
  Content,
11
+ ContentArtifact,
11
12
  ProgressReport,
12
13
  PublishedMetadata,
13
14
  PulpTemporaryFile,
@@ -47,9 +48,19 @@ def orphan_cleanup(
47
48
  This task removes Artifact files from the filesystem as well.
48
49
 
49
50
  Kwargs:
50
- content_pks (list): A list of content pks. If specified, only remove these orphans.
51
+ content_pks (list): If specified, only remove these orphan content units and their orphaned
52
+ artifacts.
51
53
 
52
54
  """
55
+ artifact_pks = None
56
+ if content_pks:
57
+ # Content deletion removes these memberships, so capture the artifacts first.
58
+ artifact_pks = list(
59
+ ContentArtifact.objects.filter(content_id__in=content_pks, artifact__isnull=False)
60
+ .values_list("artifact_id", flat=True)
61
+ .distinct()
62
+ )
63
+
53
64
  content = Content.objects.orphaned(orphan_protection_time, content_pks).exclude(
54
65
  pulp_type=PublishedMetadata.get_pulp_type()
55
66
  )
@@ -86,6 +97,8 @@ def orphan_cleanup(
86
97
 
87
98
  # delete the artifacts that don't belong to any content
88
99
  artifacts = Artifact.objects.orphaned(orphan_protection_time)
100
+ if artifact_pks is not None:
101
+ artifacts = artifacts.filter(pk__in=artifact_pks)
89
102
 
90
103
  skipped_artifact = 0
91
104
  with ProgressReport(
@@ -53,6 +53,25 @@ def _ssl_temp_files(server):
53
53
  pass
54
54
 
55
55
 
56
+ def _build_remote_settings(server):
57
+ """Build fields copied onto remotes created during replication."""
58
+ remote_settings = {
59
+ "ca_cert": server.ca_cert,
60
+ "tls_validation": server.tls_validation,
61
+ "client_cert": server.client_cert,
62
+ "client_key": server.client_key,
63
+ "download_concurrency": server.download_concurrency,
64
+ "max_retries": server.max_retries,
65
+ "total_timeout": server.total_timeout,
66
+ "connect_timeout": server.connect_timeout,
67
+ "sock_connect_timeout": server.sock_connect_timeout,
68
+ "sock_read_timeout": server.sock_read_timeout,
69
+ }
70
+ if server.remote_policy is not None:
71
+ remote_settings["policy"] = server.remote_policy
72
+ return remote_settings
73
+
74
+
56
75
  def replicate_distributions(server_pk, q_select=None, **kwargs):
57
76
  server = UpstreamPulp.objects.get(pk=server_pk)
58
77
  with _ssl_temp_files(server) as ssl_files:
@@ -76,18 +95,7 @@ def replicate_distributions(server_pk, q_select=None, **kwargs):
76
95
  }
77
96
  )
78
97
 
79
- remote_settings = {
80
- "ca_cert": server.ca_cert,
81
- "tls_validation": server.tls_validation,
82
- "client_cert": server.client_cert,
83
- "client_key": server.client_key,
84
- "download_concurrency": server.download_concurrency,
85
- "max_retries": server.max_retries,
86
- "total_timeout": server.total_timeout,
87
- "connect_timeout": server.connect_timeout,
88
- "sock_connect_timeout": server.sock_connect_timeout,
89
- "sock_read_timeout": server.sock_read_timeout,
90
- }
98
+ remote_settings = _build_remote_settings(server)
91
99
  try:
92
100
  task_group = TaskGroup.current()
93
101
  supported_replicators = []
@@ -10,6 +10,7 @@ from django.db import transaction
10
10
 
11
11
  from pulpcore.app import models
12
12
  from pulpcore.app.models import ProgressReport
13
+ from pulpcore.app.serializers import RepositoryVersionSerializer
13
14
  from pulpcore.app.util import get_domain
14
15
  from pulpcore.exceptions.base import RepositoryVersionDeleteError
15
16
 
@@ -198,6 +199,14 @@ def repair_all_artifacts(verify_checksums, **kwargs):
198
199
  loop.run_until_complete(_repair_artifacts_for_content(verify_checksums=verify_checksums))
199
200
 
200
201
 
202
+ def _serialize_version(version):
203
+ """Serialize `version` if it was created (i.e. not discarded as a no-op) else return None."""
204
+ if not version.complete:
205
+ return None
206
+ # The hyperlinked fields require the "request" key in the context, but hrefs are relative.
207
+ return RepositoryVersionSerializer(version, context={"request": None}).data
208
+
209
+
201
210
  def add_and_remove(
202
211
  repository_pk,
203
212
  add_content_units,
@@ -220,6 +229,10 @@ def add_and_remove(
220
229
  as the initial set of content for our new RepositoryVersion
221
230
  overwrite (bool): When False, raise ContentOverwriteError if any content being added
222
231
  conflicts with existing content based on repo_key_fields. Defaults to True.
232
+
233
+ Returns:
234
+ dict: The serialized newly created RepositoryVersion, or None if nothing changed and no
235
+ version was created.
223
236
  """
224
237
  repository = models.Repository.objects.get(pk=repository_pk).cast()
225
238
 
@@ -247,11 +260,13 @@ def add_and_remove(
247
260
  new_version.remove_content(models.Content.objects.filter(pk__in=remove_content_units))
248
261
  new_version.add_content(models.Content.objects.filter(pk__in=add_content_units))
249
262
 
263
+ return _serialize_version(new_version)
264
+
250
265
 
251
266
  async def aadd_and_remove(
252
267
  repository_pk, add_content_units, remove_content_units, base_version_pk=None, **kwargs
253
268
  ):
254
- """Aynsc version of add_and_remove."""
269
+ """Async version of add_and_remove."""
255
270
  repository = await models.Repository.objects.aget(pk=repository_pk)
256
271
  repository = await repository.acast()
257
272
 
@@ -271,5 +286,6 @@ async def aadd_and_remove(
271
286
  with repository.new_version(base_version=base_version) as new_version:
272
287
  new_version.remove_content(models.Content.objects.filter(pk__in=remove_content_units))
273
288
  new_version.add_content(models.Content.objects.filter(pk__in=add_content_units))
289
+ return _serialize_version(new_version)
274
290
 
275
- await sync_to_async(add_to_repository)()
291
+ return await sync_to_async(add_to_repository)()
@@ -17,6 +17,8 @@ from django.apps import apps
17
17
  from django.conf import settings
18
18
  from django.db import connection
19
19
  from django.db.models import Model, UUIDField
20
+ from django.urls import Resolver404, resolve
21
+ from django.utils.http import parse_http_date
20
22
  from rest_framework.reverse import reverse as drf_reverse
21
23
  from rest_framework.serializers import ValidationError
22
24
 
@@ -164,6 +166,18 @@ def resolve_prn(prn):
164
166
  return model, pk
165
167
 
166
168
 
169
+ def resolve_repository_version_href(uri):
170
+ """Return route parameters from a numbered repository-version href."""
171
+ try:
172
+ kwargs = resolve(urlparse(uri).path).kwargs
173
+ except Resolver404:
174
+ raise ValidationError(detail=_("URI not valid: {u}").format(u=uri))
175
+ if "repository_pk" not in kwargs or "number" not in kwargs:
176
+ raise ValidationError(detail=_("URI not valid: {u}").format(u=uri))
177
+ kwargs["number"] = int(kwargs["number"])
178
+ return kwargs
179
+
180
+
167
181
  def extract_pk(uri, only_prn=False):
168
182
  """
169
183
  Resolve a resource URI or PRN to a simple PK value.
@@ -467,9 +481,9 @@ def gpg_verify(public_keys, signature, detached_data=None):
467
481
  result = verify(file=detached_data, store=store, signature=sig)
468
482
  else:
469
483
  result = verify(bytes=sig_data, store=store)
470
- except Exception:
471
- message = _("The signature is not valid.")
472
- raise InvalidSignatureError(message, verified=VerifyResult(status=message)) from None
484
+ except Exception as e:
485
+ message = _("The signature is not valid: {}").format(e)
486
+ raise InvalidSignatureError(message, verified=VerifyResult(status=message))
473
487
 
474
488
  return VerifyResult(result)
475
489
 
@@ -679,14 +693,15 @@ def set_domain(new_domain):
679
693
  return new_domain
680
694
 
681
695
 
682
- def cache_key(base_path):
683
- """Returns the base-key(s) used in the Cache for the passed base_path(s)."""
696
+ def cache_key(base_path, domain=None):
697
+ """Return the cache base key or keys for the passed base path or paths."""
684
698
  if settings.DOMAIN_ENABLED:
685
- domain = get_domain()
699
+ domain = domain or get_domain()
700
+ domain_name = domain if isinstance(domain, str) else domain.name
686
701
  if isinstance(base_path, str):
687
- base_path = f"{domain.name}:{base_path}"
702
+ base_path = f"{domain_name}:{base_path}"
688
703
  else:
689
- base_path = [f"{domain.name}:{path}" for path in base_path]
704
+ base_path = [f"{domain_name}:{path}" for path in base_path]
690
705
 
691
706
  return base_path
692
707
 
@@ -714,6 +729,25 @@ def normalize_http_status(status):
714
729
  return ""
715
730
 
716
731
 
732
+ def check_request_was_modified(request, last_modified, etag=None):
733
+ if_none_match = request.headers.get("If-None-Match")
734
+ if_modified_since = request.headers.get("If-Modified-Since")
735
+
736
+ if not if_none_match and not (last_modified and if_modified_since):
737
+ return True
738
+
739
+ if if_none_match:
740
+ client_etags = [etag == client_etag.strip() for client_etag in if_none_match.split(",")]
741
+ return not any(client_etags)
742
+
743
+ try:
744
+ last_modified_ts = parse_http_date(last_modified)
745
+ if_modified_ts = parse_http_date(if_modified_since)
746
+ return last_modified_ts > if_modified_ts
747
+ except (TypeError, ValueError):
748
+ return True
749
+
750
+
717
751
  class HashingFileWriter(RawIOBase):
718
752
  """
719
753
  A file-like object that handles writing data to disk with simultaneous