pulp-container 2.29.3__tar.gz → 2.30.1__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 (159) hide show
  1. {pulp_container-2.29.3 → pulp_container-2.30.1}/CHANGES.md +100 -5
  2. {pulp_container-2.29.3 → pulp_container-2.30.1}/PKG-INFO +1 -1
  3. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/__init__.py +1 -1
  4. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/downloaders.py +1 -1
  5. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/registry_api.py +30 -6
  6. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/viewsets.py +12 -12
  7. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container.egg-info/PKG-INFO +1 -1
  8. {pulp_container-2.29.3 → pulp_container-2.30.1}/pyproject.toml +2 -2
  9. {pulp_container-2.29.3 → pulp_container-2.30.1}/COMMITMENT +0 -0
  10. {pulp_container-2.29.3 → pulp_container-2.30.1}/COPYRIGHT +0 -0
  11. {pulp_container-2.29.3 → pulp_container-2.30.1}/LICENSE +0 -0
  12. {pulp_container-2.29.3 → pulp_container-2.30.1}/MANIFEST.in +0 -0
  13. {pulp_container-2.29.3 → pulp_container-2.30.1}/README.rst +0 -0
  14. {pulp_container-2.29.3 → pulp_container-2.30.1}/functest_requirements.txt +0 -0
  15. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/__init__.py +0 -0
  16. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/access_policy.py +0 -0
  17. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/authorization.py +0 -0
  18. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/cache.py +0 -0
  19. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/checks.py +0 -0
  20. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/content.py +0 -0
  21. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/dynaconf_hooks.py +0 -0
  22. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/exceptions.py +0 -0
  23. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/fields.py +0 -0
  24. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/global_access_conditions.py +0 -0
  25. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/json_schemas.py +0 -0
  26. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/management/__init__.py +0 -0
  27. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/management/commands/__init__.py +0 -0
  28. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/management/commands/container-handle-image-data.py +0 -0
  29. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/management/commands/container-repair-media-type.py +0 -0
  30. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/management/commands/container-repair-pull-through-distributions.py +0 -0
  31. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0001_initial.py +0 -0
  32. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0001_squashed_0032_upload_artifact.py +0 -0
  33. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0002_containerrepository.py +0 -0
  34. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0003_oci_mediatype.py +0 -0
  35. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0004_upload.py +0 -0
  36. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0005_contentredirectcontentguard.py +0 -0
  37. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0006_containerpushrepository.py +0 -0
  38. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0007_clear_tags_artifacts_refs.py +0 -0
  39. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0008_include_exclude_tags.py +0 -0
  40. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0009_container_namespace.py +0 -0
  41. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0010_remove_uploadchunk.py +0 -0
  42. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0011_add_container_repository_permissions.py +0 -0
  43. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0012_add_container_namespace_permissions.py +0 -0
  44. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0013_add_pull_push_permissions.py +0 -0
  45. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0014_containerdistribution_private.py +0 -0
  46. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0015_manage_tags_push_repo.py +0 -0
  47. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0016_add_delete_versions_permission.py +0 -0
  48. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0017_add_granular_perms.py +0 -0
  49. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0018_containerdistribution_description.py +0 -0
  50. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0019_DATA_distribution_model_swap.py +0 -0
  51. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0020_update_push_repo_perms.py +0 -0
  52. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0021_data_move_redirect_content_guard_to_core.py +0 -0
  53. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0022_delete_contentredirectcontentguard.py +0 -0
  54. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0023_manifestsignature.py +0 -0
  55. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0024_containerremote_sigstore.py +0 -0
  56. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0025_signature_stored_in_textfield.py +0 -0
  57. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0026_manifest_signing_service.py +0 -0
  58. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0027_data_translate_perms_to_roles.py +0 -0
  59. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0028_add_role_manage_permissions.py +0 -0
  60. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0029_remove_blob_media_type.py +0 -0
  61. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0030_enforce_tagged_manifest_reference.py +0 -0
  62. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0031_replace_charf_with_textf.py +0 -0
  63. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0032_upload_artifact.py +0 -0
  64. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0033_raise_warning_for_repair.py +0 -0
  65. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0034_translate_signed_schema.py +0 -0
  66. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0035_alter_blob_content_ptr_and_more.py +0 -0
  67. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0036_containerpushrepository_pending_blobs_manifests.py +0 -0
  68. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0037_create_pull_through_cache_models.py +0 -0
  69. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0038_add_manifest_metadata_fields.py +0 -0
  70. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0039_manifest_data.py +0 -0
  71. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0040_add_remote_repo_filter.py +0 -0
  72. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0041_add_pull_through_pull_permissions.py +0 -0
  73. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0042_add_manifest_nature_field.py +0 -0
  74. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0043_add_os_arch_image_size_manifest_fields.py +0 -0
  75. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0044_add_domain.py +0 -0
  76. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0045_alter_manifest_compressed_image_size.py +0 -0
  77. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0046_alter_manifest_listed_manifests.py +0 -0
  78. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0047_containernamespace_pulp_labels.py +0 -0
  79. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0048_containerremote_includes_excludes.py +0 -0
  80. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0049_manifestsignature_fingerprint.py +0 -0
  81. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/0050_alter_containernamespace_options.py +0 -0
  82. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/migrations/__init__.py +0 -0
  83. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/modelresource.py +0 -0
  84. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/models.py +0 -0
  85. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/pull_through.py +0 -0
  86. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/redirects.py +0 -0
  87. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/registry.py +0 -0
  88. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/replica.py +0 -0
  89. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/serializers.py +0 -0
  90. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/settings.py +0 -0
  91. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/__init__.py +0 -0
  92. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/builder.py +0 -0
  93. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/download_image_data.py +0 -0
  94. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/migrate_push_repository.py +0 -0
  95. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/recursive_add.py +0 -0
  96. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/recursive_remove.py +0 -0
  97. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/sign.py +0 -0
  98. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/sync_stages.py +0 -0
  99. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/synchronize.py +0 -0
  100. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/tag.py +0 -0
  101. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/tasks/untag.py +0 -0
  102. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/token_verification.py +0 -0
  103. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/urls.py +0 -0
  104. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/utils.py +0 -0
  105. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/webserver_snippets/__init__.py +0 -0
  106. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/webserver_snippets/apache.conf +0 -0
  107. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/app/webserver_snippets/nginx.conf +0 -0
  108. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/constants.py +0 -0
  109. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/__init__.py +0 -0
  110. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/__init__.py +0 -0
  111. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/__init__.py +0 -0
  112. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_build_images.py +0 -0
  113. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_cancel_blob_upload.py +0 -0
  114. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_content_cache.py +0 -0
  115. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_crud_distributions.py +0 -0
  116. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_crud_remotes.py +0 -0
  117. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_delete_blob.py +0 -0
  118. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_delete_manifest.py +0 -0
  119. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_domains.py +0 -0
  120. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_flatpak.py +0 -0
  121. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_migrate_push_repository.py +0 -0
  122. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_pull_content.py +0 -0
  123. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_pull_through_cache.py +0 -0
  124. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_pulpimportexport.py +0 -0
  125. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_push_content.py +0 -0
  126. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_push_signatures.py +0 -0
  127. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_rbac_push_repositories.py +0 -0
  128. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_rbac_remotes.py +0 -0
  129. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_rbac_repo_content.py +0 -0
  130. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_rbac_repo_versions.py +0 -0
  131. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_rbac_sync_repositories.py +0 -0
  132. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_recursive_add.py +0 -0
  133. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_recursive_remove.py +0 -0
  134. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_remote_filter_pull_through.py +0 -0
  135. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_repositories_list.py +0 -0
  136. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_sign_manifests.py +0 -0
  137. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_sync.py +0 -0
  138. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_sync_signatures.py +0 -0
  139. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_tagging_images.py +0 -0
  140. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/api/test_token_authentication.py +0 -0
  141. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/conftest.py +0 -0
  142. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/constants.py +0 -0
  143. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/functional/utils.py +0 -0
  144. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/__init__.py +0 -0
  145. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/fixtures/ryuk_0.13.0_manifest_list.json +0 -0
  146. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/test_downloaders.py +0 -0
  147. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/test_json_schemas.py +0 -0
  148. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/test_models.py +0 -0
  149. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/test_pull_through_repair.py +0 -0
  150. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/test_serializers.py +0 -0
  151. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container/tests/unit/test_sync_stages.py +0 -0
  152. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container.egg-info/SOURCES.txt +0 -0
  153. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container.egg-info/dependency_links.txt +0 -0
  154. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container.egg-info/entry_points.txt +0 -0
  155. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container.egg-info/requires.txt +0 -0
  156. {pulp_container-2.29.3 → pulp_container-2.30.1}/pulp_container.egg-info/top_level.txt +0 -0
  157. {pulp_container-2.29.3 → pulp_container-2.30.1}/setup.cfg +0 -0
  158. {pulp_container-2.29.3 → pulp_container-2.30.1}/test_requirements.txt +0 -0
  159. {pulp_container-2.29.3 → pulp_container-2.30.1}/unittest_requirements.txt +0 -0
@@ -8,24 +8,29 @@
8
8
 
9
9
  [//]: # (towncrier release notes start)
10
10
 
11
- ## 2.29.3 (2026-10-28) {: #2.29.3 }
11
+ ## 2.30.1 (2026-10-28) {: #2.30.1 }
12
12
 
13
- #### Bugfixes {: #2.29.3-bugfix }
13
+ #### Bugfixes {: #2.30.1-bugfix }
14
14
 
15
15
  - Allow anonymous pull-through for public distributions
16
16
  [#1976](https://github.com/pulp/pulp_container/issues/1976)
17
17
  - Container blob downloads now respect each Domain's object storage redirect setting.
18
18
  - Fixed pull-through signature lookups failing with a 500 when the upstream registry (e.g. gcr.io) sends unquoted values in its bearer auth challenge.
19
- - Fixed the registry Authorization header leaking into a shared module-level headers dict, which could send one remote's credentials to another registry.
20
19
  - Retried GHCR requests that fail with 403 using a bearer token, and fell back to GET when a registry (e.g. ECR Public) rejects HEAD on blob endpoints.
21
20
  - Treat an explicitly empty Accept header like a missing header when retrieving registry blobs.
22
21
 
23
22
  ---
24
23
 
25
- ## 2.29.2 (2026-10-08) {: #2.29.2 }
24
+ ## 2.30.0 (2026-10-08) {: #2.30.0 }
26
25
 
27
- #### Bugfixes {: #2.29.2-bugfix }
26
+ #### Features {: #2.30.0-feature }
28
27
 
28
+ - Pull-through manifest resolution now uses HEAD checks, reducing Docker Hub 429s for repeated tag resolutions.
29
+
30
+ #### Bugfixes {: #2.30.0-bugfix }
31
+
32
+ - Prevent container distributions from overlapping other distribution base paths. Pull-through distributions **NEED** to be fixed before upgrading pulpcore; run `pulpcore-manager container-repair-pull-through-distributions` to repair existing distributions.
33
+ [#2494](https://github.com/pulp/pulp_container/issues/2494)
29
34
  - Fixed global auth token leakage. CVE-2026-103868
30
35
 
31
36
  ---
@@ -129,6 +134,21 @@
129
134
 
130
135
  ---
131
136
 
137
+ ## 2.27.13 (2026-10-07) {: #2.27.13 }
138
+
139
+ No significant changes.
140
+
141
+ ---
142
+
143
+ ## 2.27.12 (2026-09-23) {: #2.27.12 }
144
+
145
+ #### Bugfixes {: #2.27.12-bugfix }
146
+
147
+ - Prevent container distributions from overlapping other distribution base paths. Pull-through distributions **NEED** to be fixed before upgrading pulpcore; run `pulpcore-manager container-repair-pull-through-distributions` to repair existing distributions.
148
+ [#2494](https://github.com/pulp/pulp_container/issues/2494)
149
+
150
+ ---
151
+
132
152
  ## 2.27.11 (2026-07-29) {: #2.27.11 }
133
153
 
134
154
  No significant changes.
@@ -249,6 +269,21 @@ No significant changes.
249
269
  #### Misc {: #2.27.0-misc }
250
270
 
251
271
 
272
+ ---
273
+
274
+ ## 2.26.18 (2026-10-07) {: #2.26.18 }
275
+
276
+ No significant changes.
277
+
278
+ ---
279
+
280
+ ## 2.26.17 (2026-09-23) {: #2.26.17 }
281
+
282
+ #### Bugfixes {: #2.26.17-bugfix }
283
+
284
+ - Prevent container distributions from overlapping other distribution base paths. Pull-through distributions **NEED** to be fixed before upgrading pulpcore; run `pulpcore-manager container-repair-pull-through-distributions` to repair existing distributions.
285
+ [#2494](https://github.com/pulp/pulp_container/issues/2494)
286
+
252
287
  ---
253
288
 
254
289
  ## 2.26.16 (2026-06-08) {: #2.26.16 }
@@ -457,6 +492,21 @@ No significant changes.
457
492
 
458
493
  ---
459
494
 
495
+ ## 2.24.14 (2026-10-07) {: #2.24.14 }
496
+
497
+ No significant changes.
498
+
499
+ ---
500
+
501
+ ## 2.24.13 (2026-09-23) {: #2.24.13 }
502
+
503
+ #### Bugfixes {: #2.24.13-bugfix }
504
+
505
+ - Prevent container distributions from overlapping other distribution base paths. Pull-through distributions **NEED** to be fixed before upgrading pulpcore; run `pulpcore-manager container-repair-pull-through-distributions` to repair existing distributions.
506
+ [#2494](https://github.com/pulp/pulp_container/issues/2494)
507
+
508
+ ---
509
+
460
510
  ## 2.24.12 (2026-07-21) {: #2.24.12 }
461
511
 
462
512
  #### Bugfixes {: #2.24.12-bugfix }
@@ -595,6 +645,21 @@ No significant changes.
595
645
 
596
646
  ---
597
647
 
648
+ ## 2.22.12 (2026-10-07) {: #2.22.12 }
649
+
650
+ No significant changes.
651
+
652
+ ---
653
+
654
+ ## 2.22.11 (2026-09-23) {: #2.22.11 }
655
+
656
+ #### Bugfixes {: #2.22.11-bugfix }
657
+
658
+ - Prevent container distributions from overlapping other distribution base paths. Pull-through distributions **NEED** to be fixed before upgrading pulpcore; run `pulpcore-manager container-repair-pull-through-distributions` to repair existing distributions.
659
+ [#2494](https://github.com/pulp/pulp_container/issues/2494)
660
+
661
+ ---
662
+
598
663
  ## 2.22.10 (2026-07-23) {: #2.22.10 }
599
664
 
600
665
  #### Bugfixes {: #2.22.10-bugfix }
@@ -788,6 +853,21 @@ No significant changes.
788
853
 
789
854
  ---
790
855
 
856
+ ## 2.20.13 (2026-10-07) {: #2.20.13 }
857
+
858
+ No significant changes.
859
+
860
+ ---
861
+
862
+ ## 2.20.12 (2026-09-23) {: #2.20.12 }
863
+
864
+ #### Bugfixes {: #2.20.12-bugfix }
865
+
866
+ - Prevent container distributions from overlapping other distribution base paths. Pull-through distributions **NEED** to be fixed before upgrading pulpcore; run `pulpcore-manager container-repair-pull-through-distributions` to repair existing distributions.
867
+ [#2494](https://github.com/pulp/pulp_container/issues/2494)
868
+
869
+ ---
870
+
791
871
  ## 2.20.11 (2026-07-27) {: #2.20.11 }
792
872
 
793
873
  #### Bugfixes {: #2.20.11-bugfix }
@@ -929,6 +1009,21 @@ No significant changes.
929
1009
 
930
1010
  ---
931
1011
 
1012
+ ## 2.19.15 (2026-10-07) {: #2.19.15 }
1013
+
1014
+ No significant changes.
1015
+
1016
+ ---
1017
+
1018
+ ## 2.19.14 (2026-09-23) {: #2.19.14 }
1019
+
1020
+ #### Bugfixes {: #2.19.14-bugfix }
1021
+
1022
+ - Prevent container distributions from overlapping other distribution base paths. Pull-through distributions **NEED** to be fixed before upgrading pulpcore; run `pulpcore-manager container-repair-pull-through-distributions` to repair existing distributions.
1023
+ [#2494](https://github.com/pulp/pulp_container/issues/2494)
1024
+
1025
+ ---
1026
+
932
1027
  ## 2.19.13 (2026-07-27) {: #2.19.13 }
933
1028
 
934
1029
  #### Bugfixes {: #2.19.13-bugfix }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pulp-container
3
- Version: 2.29.3
3
+ Version: 2.30.1
4
4
  Summary: Container plugin for the Pulp Project
5
5
  Author-email: Pulp Team <pulp-list@redhat.com>
6
6
  Project-URL: Homepage, https://pulpproject.org
@@ -24,7 +24,7 @@ class PulpContainerPluginAppConfig(PulpPluginAppConfig):
24
24
 
25
25
  name = "pulp_container.app"
26
26
  label = "container"
27
- version = "2.29.3"
27
+ version = "2.30.1"
28
28
  python_package_name = "pulp-container"
29
29
  domain_compatible = True
30
30
 
@@ -51,7 +51,7 @@ class RegistryAuthHttpDownloader(HttpDownloader):
51
51
  headers = {}
52
52
  repo_name = None
53
53
  if extra_data is not None:
54
- headers = dict(extra_data.get("headers", headers))
54
+ headers = extra_data.get("headers", headers)
55
55
  repo_name = extra_data.get("repo_name", None)
56
56
  http_method = extra_data.get("http_method", "get") if extra_data is not None else "get"
57
57
  this_token = self.factory.registry_auth["bearer"]
@@ -1510,14 +1510,43 @@ class Manifests(RedirectsMixin, ContainerRegistryApiMixin, ViewSet):
1510
1510
  Fetch a manifest from the upstream remote.
1511
1511
  Returns the local manifest, if it exists in Pulp, and the full response from upstream.
1512
1512
  Raises response errors if manifest is not found or the download fails.
1513
+
1514
+ A HEAD request is issued first to check the manifest's digest against what is already
1515
+ stored in Pulp. Per Docker Hub's pull-rate accounting, a HEAD ("version check") does not
1516
+ count as a pull, unlike a GET. If the manifest is already stored locally, the HEAD
1517
+ response is returned as-is and the counted GET is skipped entirely.
1513
1518
  """
1514
1519
  relative_url = "/v2/{name}/manifests/{pk}".format(
1515
1520
  name=remote.namespaced_upstream_name, pk=pk
1516
1521
  )
1517
1522
  tag_url = urljoin(remote.url, relative_url)
1523
+
1524
+ head_response = self._fetch_manifest_response(remote, tag_url, pk, http_method="head")
1525
+ digest = head_response.headers.get("docker-content-digest")
1526
+ if digest:
1527
+ manifest = models.Manifest.objects.filter(
1528
+ digest=digest, pulp_domain=get_domain()
1529
+ ).first()
1530
+ if manifest is not None:
1531
+ return manifest, head_response
1532
+
1533
+ # The manifest is not stored locally yet, or the upstream did not report a digest on the
1534
+ # HEAD response; fall back to a full GET, identical to the previous behavior.
1535
+ response = self._fetch_manifest_response(remote, tag_url, pk, http_method="get")
1536
+ digest = response.headers.get("docker-content-digest")
1537
+ return models.Manifest.objects.filter(
1538
+ digest=digest, pulp_domain=get_domain()
1539
+ ).first(), response
1540
+
1541
+ def _fetch_manifest_response(self, remote, tag_url, pk, http_method):
1542
+ """
1543
+ Issue a HEAD or GET request for a manifest and map response errors consistently.
1544
+ """
1518
1545
  downloader = remote.get_downloader(url=tag_url)
1519
1546
  try:
1520
- response = downloader.fetch(extra_data={"headers": V2_ACCEPT_HEADERS})
1547
+ return downloader.fetch(
1548
+ extra_data={"headers": V2_ACCEPT_HEADERS, "http_method": http_method}
1549
+ )
1521
1550
  except ClientResponseError as response_error:
1522
1551
  if response_error.status == 429:
1523
1552
  # the client could request the manifest outside the docker hub pull limit;
@@ -1530,11 +1559,6 @@ class Manifests(RedirectsMixin, ContainerRegistryApiMixin, ViewSet):
1530
1559
  except (ClientConnectionError, TimeoutException):
1531
1560
  # The remote server is not available at the moment
1532
1561
  raise GatewayTimeout()
1533
- else:
1534
- digest = response.headers.get("docker-content-digest")
1535
- return models.Manifest.objects.filter(
1536
- digest=digest, pulp_domain=get_domain()
1537
- ).first(), response
1538
1562
 
1539
1563
  def put(self, request, path, pk=None):
1540
1564
  """
@@ -561,7 +561,7 @@ class TagOperationsMixin:
561
561
  responses={202: AsyncOperationResponseSerializer},
562
562
  )
563
563
  @action(detail=True, methods=["post"], serializer_class=serializers.TagImageSerializer)
564
- def tag(self, request, pk):
564
+ def tag(self, request, pk, **kwargs):
565
565
  """
566
566
  Create a task which is responsible for creating a new tag.
567
567
  """
@@ -592,7 +592,7 @@ class TagOperationsMixin:
592
592
  responses={202: AsyncOperationResponseSerializer},
593
593
  )
594
594
  @action(detail=True, methods=["post"], serializer_class=serializers.UnTagImageSerializer)
595
- def untag(self, request, pk):
595
+ def untag(self, request, pk, **kwargs):
596
596
  """
597
597
  Create a task which is responsible for untagging an image.
598
598
  """
@@ -622,7 +622,7 @@ class SignOperationsMixin:
622
622
  responses={202: AsyncOperationResponseSerializer},
623
623
  )
624
624
  @action(detail=True, methods=["post"], serializer_class=serializers.RepositorySignSerializer)
625
- def sign(self, request, pk):
625
+ def sign(self, request, pk, **kwargs):
626
626
  """
627
627
  Signs manifests by tag in the repository.
628
628
  """
@@ -827,7 +827,7 @@ class ContainerRepositoryViewSet(
827
827
  methods=["post"],
828
828
  serializer_class=serializers.ContainerRepositorySyncURLSerializer,
829
829
  )
830
- def sync(self, request, pk):
830
+ def sync(self, request, pk, **kwargs):
831
831
  """
832
832
  Synchronizes a repository. The ``repository`` field has to be provided.
833
833
  """
@@ -861,7 +861,7 @@ class ContainerRepositoryViewSet(
861
861
  responses={202: AsyncOperationResponseSerializer},
862
862
  )
863
863
  @action(detail=True, methods=["post"], serializer_class=serializers.RecursiveManageSerializer)
864
- def add(self, request, pk):
864
+ def add(self, request, pk, **kwargs):
865
865
  """
866
866
  Queues a task that creates a new RepositoryVersion by adding content units.
867
867
  """
@@ -900,7 +900,7 @@ class ContainerRepositoryViewSet(
900
900
  responses={202: AsyncOperationResponseSerializer},
901
901
  )
902
902
  @action(detail=True, methods=["post"], serializer_class=serializers.RecursiveManageSerializer)
903
- def remove(self, request, pk):
903
+ def remove(self, request, pk, **kwargs):
904
904
  """
905
905
  Queues a task that creates a new RepositoryVersion by removing content units.
906
906
  """
@@ -935,7 +935,7 @@ class ContainerRepositoryViewSet(
935
935
  responses={202: AsyncOperationResponseSerializer},
936
936
  )
937
937
  @action(detail=True, methods=["post"], serializer_class=serializers.TagCopySerializer)
938
- def copy_tags(self, request, pk):
938
+ def copy_tags(self, request, pk, **kwargs):
939
939
  """
940
940
  Queues a task that creates a new RepositoryVersion by adding Tags.
941
941
  """
@@ -968,7 +968,7 @@ class ContainerRepositoryViewSet(
968
968
  responses={202: AsyncOperationResponseSerializer},
969
969
  )
970
970
  @action(detail=True, methods=["post"], serializer_class=serializers.ManifestCopySerializer)
971
- def copy_manifests(self, request, pk):
971
+ def copy_manifests(self, request, pk, **kwargs):
972
972
  """
973
973
  Queues a task that creates a new RepositoryVersion by adding Manifests.
974
974
  """
@@ -1008,7 +1008,7 @@ class ContainerRepositoryViewSet(
1008
1008
  responses={202: AsyncOperationResponseSerializer},
1009
1009
  )
1010
1010
  @action(detail=True, methods=["post"], serializer_class=serializers.OCIBuildImageSerializer)
1011
- def build_image(self, request, pk):
1011
+ def build_image(self, request, pk, **kwargs):
1012
1012
  """
1013
1013
  Create a task which is responsible for creating a new image and tag.
1014
1014
  """
@@ -1169,7 +1169,7 @@ class ContainerPushRepositoryViewSet(
1169
1169
  @action(
1170
1170
  detail=True, methods=["post"], serializer_class=serializers.MigratePushRepositorySerializer
1171
1171
  )
1172
- def migrate(self, request, pk):
1172
+ def migrate(self, request, pk, **kwargs):
1173
1173
  """
1174
1174
  Create a task which converts a push repository into a container repository in place.
1175
1175
  """
@@ -1199,7 +1199,7 @@ class ContainerPushRepositoryViewSet(
1199
1199
  responses={202: AsyncOperationResponseSerializer},
1200
1200
  )
1201
1201
  @action(detail=True, methods=["post"], serializer_class=serializers.RemoveImageSerializer)
1202
- def remove_image(self, request, pk):
1202
+ def remove_image(self, request, pk, **kwargs):
1203
1203
  """
1204
1204
  Create a task which deletes an image by the passed digest.
1205
1205
  """
@@ -1225,7 +1225,7 @@ class ContainerPushRepositoryViewSet(
1225
1225
  return OperationPostponedResponse(result, request)
1226
1226
 
1227
1227
  @action(detail=True, methods=["post"], serializer_class=serializers.RemoveSignaturesSerializer)
1228
- def remove_signatures(self, request, pk):
1228
+ def remove_signatures(self, request, pk, **kwargs):
1229
1229
  """
1230
1230
  Create a task which deletes signatures by the passed key_id.
1231
1231
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pulp-container
3
- Version: 2.29.3
3
+ Version: 2.30.1
4
4
  Summary: Container plugin for the Pulp Project
5
5
  Author-email: Pulp Team <pulp-list@redhat.com>
6
6
  Project-URL: Homepage, https://pulpproject.org
@@ -7,7 +7,7 @@ build-backend = 'setuptools.build_meta'
7
7
 
8
8
  [project]
9
9
  name = "pulp-container"
10
- version = "2.29.3"
10
+ version = "2.30.1"
11
11
  description = "Container plugin for the Pulp Project"
12
12
  readme = "README.md"
13
13
  authors = [
@@ -89,7 +89,7 @@ ignore = [
89
89
  [tool.bumpversion]
90
90
  # This section is managed by the plugin template. Do not edit manually.
91
91
 
92
- current_version = "2.29.3"
92
+ current_version = "2.30.1"
93
93
  commit = false
94
94
  tag = false
95
95
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<alpha>0a)?(?P<patch>\\d+)(\\.(?P<release>[a-z]+))?"
File without changes