pulp-container 2.27.2__tar.gz → 2.27.4__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.
- {pulp_container-2.27.2 → pulp_container-2.27.4}/CHANGES.md +21 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/PKG-INFO +2 -1
- pulp_container-2.27.4/pulp_container/app/__init__.py +40 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/models.py +0 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/registry_api.py +13 -8
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/serializers.py +8 -17
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/sign.py +4 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/sync_stages.py +4 -2
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/synchronize.py +0 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/utils.py +55 -26
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/viewsets.py +0 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/constants.py +0 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_build_images.py +4 -8
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_crud_remotes.py +0 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_flatpak.py +0 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_sync_signatures.py +66 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container.egg-info/PKG-INFO +2 -1
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container.egg-info/requires.txt +1 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pyproject.toml +5 -2
- pulp_container-2.27.2/pulp_container/app/__init__.py +0 -15
- {pulp_container-2.27.2 → pulp_container-2.27.4}/COMMITMENT +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/COPYRIGHT +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/LICENSE +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/MANIFEST.in +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/README.rst +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/functest_requirements.txt +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/access_policy.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/authorization.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/cache.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/checks.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/content.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/downloaders.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/dynaconf_hooks.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/exceptions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/fields.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/global_access_conditions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/json_schemas.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/management/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/management/commands/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/management/commands/container-handle-image-data.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/management/commands/container-repair-media-type.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0001_initial.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0001_squashed_0032_upload_artifact.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0002_containerrepository.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0003_oci_mediatype.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0004_upload.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0005_contentredirectcontentguard.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0006_containerpushrepository.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0007_clear_tags_artifacts_refs.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0008_include_exclude_tags.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0009_container_namespace.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0010_remove_uploadchunk.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0011_add_container_repository_permissions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0012_add_container_namespace_permissions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0013_add_pull_push_permissions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0014_containerdistribution_private.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0015_manage_tags_push_repo.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0016_add_delete_versions_permission.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0017_add_granular_perms.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0018_containerdistribution_description.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0019_DATA_distribution_model_swap.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0020_update_push_repo_perms.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0021_data_move_redirect_content_guard_to_core.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0022_delete_contentredirectcontentguard.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0023_manifestsignature.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0024_containerremote_sigstore.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0025_signature_stored_in_textfield.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0026_manifest_signing_service.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0027_data_translate_perms_to_roles.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0028_add_role_manage_permissions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0029_remove_blob_media_type.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0030_enforce_tagged_manifest_reference.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0031_replace_charf_with_textf.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0032_upload_artifact.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0033_raise_warning_for_repair.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0034_translate_signed_schema.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0035_alter_blob_content_ptr_and_more.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0036_containerpushrepository_pending_blobs_manifests.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0037_create_pull_through_cache_models.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0038_add_manifest_metadata_fields.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0039_manifest_data.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0040_add_remote_repo_filter.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0041_add_pull_through_pull_permissions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0042_add_manifest_nature_field.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0043_add_os_arch_image_size_manifest_fields.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0044_add_domain.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0045_alter_manifest_compressed_image_size.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0046_alter_manifest_listed_manifests.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/modelresource.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/redirects.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/registry.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/replica.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/settings.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/builder.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/download_image_data.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/recursive_add.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/recursive_remove.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/tag.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/untag.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/token_verification.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/urls.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/webserver_snippets/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/webserver_snippets/apache.conf +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/webserver_snippets/nginx.conf +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_content_cache.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_crud_distributions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_domains.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_pull_content.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_pull_through_cache.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_pulpimportexport.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_push_content.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_push_signatures.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_rbac_push_repositories.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_rbac_remotes.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_rbac_repo_content.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_rbac_repo_versions.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_rbac_sync_repositories.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_recursive_add.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_recursive_remove.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_remote_filter_pull_through.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_repositories_list.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_sign_manifests.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_sync.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_tagging_images.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_token_authentication.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/conftest.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/constants.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/utils.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/unit/__init__.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/unit/test_json_schemas.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/unit/test_models.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/unit/test_serializers.py +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container.egg-info/SOURCES.txt +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container.egg-info/dependency_links.txt +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container.egg-info/entry_points.txt +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container.egg-info/top_level.txt +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/setup.cfg +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/test_requirements.txt +0 -0
- {pulp_container-2.27.2 → pulp_container-2.27.4}/unittest_requirements.txt +0 -0
|
@@ -8,6 +8,27 @@
|
|
|
8
8
|
|
|
9
9
|
[//]: # (towncrier release notes start)
|
|
10
10
|
|
|
11
|
+
## 2.27.4 (2026-03-30) {: #2.27.4 }
|
|
12
|
+
|
|
13
|
+
#### Bugfixes {: #2.27.4-bugfix }
|
|
14
|
+
|
|
15
|
+
- Don't blow up on encountering PQC signatures.
|
|
16
|
+
[#2237](https://github.com/pulp/pulp_container/issues/2237)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2.27.3 (2026-03-18) {: #2.27.3 }
|
|
21
|
+
|
|
22
|
+
#### Bugfixes {: #2.27.3-bugfix }
|
|
23
|
+
|
|
24
|
+
- Altered several id-fields and their related sequences.
|
|
25
|
+
|
|
26
|
+
INTEGER AutoField sequences can "run out" on large/old instances, update to BIGINT.
|
|
27
|
+
[#2080](https://github.com/pulp/pulp_container/issues/2080)
|
|
28
|
+
- Fixed memory usage when pushing large images with monolithic upload.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
11
32
|
## 2.27.2 (2026-02-24) {: #2.27.2 }
|
|
12
33
|
|
|
13
34
|
#### Bugfixes {: #2.27.2-bugfix }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pulp-container
|
|
3
|
-
Version: 2.27.
|
|
3
|
+
Version: 2.27.4
|
|
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
|
|
@@ -20,4 +20,5 @@ License-File: LICENSE
|
|
|
20
20
|
Requires-Dist: jsonschema<4.26,>=4.4
|
|
21
21
|
Requires-Dist: pulpcore<3.115,>=3.73.2
|
|
22
22
|
Requires-Dist: pyjwt[crypto]<2.11,>=2.4
|
|
23
|
+
Requires-Dist: pysequoia==0.1.32
|
|
23
24
|
Dynamic: license-file
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from pulpcore.plugin import PulpPluginAppConfig
|
|
2
|
+
from django.db import connection
|
|
3
|
+
from django.db.models.signals import post_migrate
|
|
4
|
+
|
|
5
|
+
update_sequences_to_bigint = """
|
|
6
|
+
ALTER TABLE container_blobmanifest ALTER COLUMN id TYPE bigint;
|
|
7
|
+
ALTER TABLE container_manifestlistmanifest ALTER COLUMN id TYPE bigint;
|
|
8
|
+
ALTER TABLE container_containerpushrepository_pending_blobs ALTER COLUMN id TYPE bigint;
|
|
9
|
+
ALTER TABLE container_containerpushrepository_pending_manifests ALTER COLUMN id TYPE bigint;
|
|
10
|
+
ALTER TABLE container_containerrepository_pending_manifests ALTER COLUMN id TYPE bigint;
|
|
11
|
+
ALTER TABLE container_containerrepository_pending_blobs ALTER COLUMN id TYPE bigint;
|
|
12
|
+
ALTER SEQUENCE container_blobmanifest_id_seq AS BIGINT;
|
|
13
|
+
ALTER SEQUENCE container_manifestlistmanifest_id_seq AS BIGINT;
|
|
14
|
+
ALTER SEQUENCE container_containerpushrepository_pending_blobs_id_seq AS BIGINT;
|
|
15
|
+
ALTER SEQUENCE container_containerpushrepository_pending_manifests_id_seq AS BIGINT;
|
|
16
|
+
ALTER SEQUENCE container_containerrepository_pending_blobs_id_seq AS BIGINT;
|
|
17
|
+
ALTER SEQUENCE container_containerrepository_pending_manifests_id_seq AS BIGINT;
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PulpContainerPluginAppConfig(PulpPluginAppConfig):
|
|
22
|
+
"""Entry point for the container plugin."""
|
|
23
|
+
|
|
24
|
+
name = "pulp_container.app"
|
|
25
|
+
label = "container"
|
|
26
|
+
version = "2.27.4"
|
|
27
|
+
python_package_name = "pulp-container"
|
|
28
|
+
domain_compatible = True
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def update_sequences(sender, **kwargs):
|
|
32
|
+
"""Update database sequences to bigint type after migrations."""
|
|
33
|
+
with connection.cursor() as cursor:
|
|
34
|
+
cursor.execute(update_sequences_to_bigint)
|
|
35
|
+
|
|
36
|
+
def ready(self):
|
|
37
|
+
super().ready()
|
|
38
|
+
from . import checks
|
|
39
|
+
|
|
40
|
+
post_migrate.connect(PulpContainerPluginAppConfig.update_sequences, sender=self)
|
|
@@ -967,24 +967,27 @@ class BlobUploads(ContainerRegistryApiMixin, ViewSet):
|
|
|
967
967
|
"""
|
|
968
968
|
Create a blob from uploaded chunks.
|
|
969
969
|
|
|
970
|
-
This request makes the upload complete. It can
|
|
971
|
-
body or last chunk
|
|
970
|
+
This request makes the upload complete. It can either carry a zero-length
|
|
971
|
+
body or contain the last chunk.
|
|
972
972
|
|
|
973
973
|
"""
|
|
974
974
|
_, repository = self.get_dr_push(request, path)
|
|
975
975
|
|
|
976
976
|
digest = request.query_params["digest"]
|
|
977
977
|
chunk = request.META["wsgi.input"]
|
|
978
|
-
# last chunk (and the only one) from monolitic upload
|
|
979
|
-
# or last chunk from chunked upload
|
|
980
|
-
last_chunk = ContentFile(chunk.read())
|
|
981
978
|
upload = get_object_or_404(models.Upload, pk=pk, repository=repository)
|
|
982
979
|
|
|
983
|
-
if
|
|
980
|
+
if upload.size == 0:
|
|
981
|
+
# monolithic upload to be completed in PUT
|
|
982
|
+
artifact = self.create_single_chunk_artifact(chunk)
|
|
983
|
+
elif artifact := upload.artifact:
|
|
984
|
+
# chunked upload was completed in PATCH
|
|
984
985
|
if artifact.sha256 != digest[len("sha256:") :]:
|
|
985
986
|
raise Exception("The digest did not match")
|
|
986
987
|
artifact.touch()
|
|
987
988
|
else:
|
|
989
|
+
# chunked upload to be completed in PUT
|
|
990
|
+
last_chunk = ContentFile(chunk.read())
|
|
988
991
|
chunks = UploadChunk.objects.filter(upload=upload).order_by("offset")
|
|
989
992
|
with NamedTemporaryFile("ab") as temp_file:
|
|
990
993
|
for chunk in chunks:
|
|
@@ -1541,8 +1544,10 @@ class Signatures(ContainerRegistryApiMixin, ViewSet):
|
|
|
1541
1544
|
except binascii.Error:
|
|
1542
1545
|
raise ManifestSignatureInvalid(digest=pk)
|
|
1543
1546
|
|
|
1544
|
-
|
|
1545
|
-
|
|
1547
|
+
try:
|
|
1548
|
+
signature_json = extract_data_from_signature(signature_raw, manifest.digest)
|
|
1549
|
+
except ValueError as exc:
|
|
1550
|
+
log.warning("Error processing signature on upload: {}".format(exc))
|
|
1546
1551
|
raise ManifestSignatureInvalid(digest=pk)
|
|
1547
1552
|
|
|
1548
1553
|
sig_digest = hashlib.sha256(signature_raw).hexdigest()
|
|
@@ -34,7 +34,6 @@ from pulp_container.app import models, fields
|
|
|
34
34
|
from pulp_container.constants import SIGNATURE_TYPE
|
|
35
35
|
from pulp_container.app.utils import get_full_path
|
|
36
36
|
|
|
37
|
-
|
|
38
37
|
VALID_SIGNATURE_NAME_REGEX = r"^sha256:[0-9a-f]{64}@[0-9a-f]{32}$"
|
|
39
38
|
VALID_TAG_REGEX = r"^[A-Za-z0-9][A-Za-z0-9._-]*$"
|
|
40
39
|
VALID_BASE_PATH_REGEX_COMPILED = re.compile(r"^[a-z0-9]+(?:(?:[._]|__|[-]*)[a-z0-9])*$")
|
|
@@ -299,25 +298,21 @@ class ContainerRemoteSerializer(RemoteSerializer):
|
|
|
299
298
|
child=serializers.CharField(max_length=255),
|
|
300
299
|
allow_null=True,
|
|
301
300
|
required=False,
|
|
302
|
-
help_text=_(
|
|
303
|
-
"""
|
|
301
|
+
help_text=_("""
|
|
304
302
|
A list of tags to include during sync.
|
|
305
303
|
Wildcards *, ? are recognized.
|
|
306
304
|
'include_tags' is evaluated before 'exclude_tags'.
|
|
307
|
-
"""
|
|
308
|
-
),
|
|
305
|
+
"""),
|
|
309
306
|
)
|
|
310
307
|
exclude_tags = serializers.ListField(
|
|
311
308
|
child=serializers.CharField(max_length=255),
|
|
312
309
|
allow_null=True,
|
|
313
310
|
required=False,
|
|
314
|
-
help_text=_(
|
|
315
|
-
"""
|
|
311
|
+
help_text=_("""
|
|
316
312
|
A list of tags to exclude during sync.
|
|
317
313
|
Wildcards *, ? are recognized.
|
|
318
314
|
'exclude_tags' is evaluated after 'include_tags'.
|
|
319
|
-
"""
|
|
320
|
-
),
|
|
315
|
+
"""),
|
|
321
316
|
)
|
|
322
317
|
|
|
323
318
|
policy = serializers.ChoiceField(
|
|
@@ -357,25 +352,21 @@ class ContainerPullThroughRemoteSerializer(RemoteSerializer):
|
|
|
357
352
|
child=serializers.CharField(max_length=255),
|
|
358
353
|
allow_null=True,
|
|
359
354
|
required=False,
|
|
360
|
-
help_text=_(
|
|
361
|
-
"""
|
|
355
|
+
help_text=_("""
|
|
362
356
|
A list of remotes to include during pull-through caching.
|
|
363
357
|
Wildcards *, ? are recognized.
|
|
364
358
|
'includes' is evaluated before 'excludes'.
|
|
365
|
-
"""
|
|
366
|
-
),
|
|
359
|
+
"""),
|
|
367
360
|
)
|
|
368
361
|
excludes = serializers.ListField(
|
|
369
362
|
child=serializers.CharField(max_length=255),
|
|
370
363
|
allow_null=True,
|
|
371
364
|
required=False,
|
|
372
|
-
help_text=_(
|
|
373
|
-
"""
|
|
365
|
+
help_text=_("""
|
|
374
366
|
A list of remotes to exclude during pull-through caching.
|
|
375
367
|
Wildcards *, ? are recognized.
|
|
376
368
|
'excludes' is evaluated after 'includes'.
|
|
377
|
-
"""
|
|
378
|
-
),
|
|
369
|
+
"""),
|
|
379
370
|
)
|
|
380
371
|
|
|
381
372
|
class Meta:
|
|
@@ -118,7 +118,10 @@ async def create_signature(manifest, reference, signing_service):
|
|
|
118
118
|
data = sig_fp.read()
|
|
119
119
|
encoded_sig = base64.b64encode(data).decode()
|
|
120
120
|
sig_digest = hashlib.sha256(data).hexdigest()
|
|
121
|
-
|
|
121
|
+
try:
|
|
122
|
+
sig_json = extract_data_from_signature(data, manifest.digest)
|
|
123
|
+
except ValueError:
|
|
124
|
+
raise
|
|
122
125
|
manifest_digest = sig_json["critical"]["image"]["docker-manifest-digest"]
|
|
123
126
|
|
|
124
127
|
signature = ManifestSignature(
|
|
@@ -391,8 +391,10 @@ class ContainerFirstStage(Stage):
|
|
|
391
391
|
def _create_signature_declarative_content(
|
|
392
392
|
self, signature_raw, man_dc, name=None, signature_b64=None
|
|
393
393
|
):
|
|
394
|
-
|
|
395
|
-
|
|
394
|
+
try:
|
|
395
|
+
signature_json = extract_data_from_signature(signature_raw, man_dc.content.digest)
|
|
396
|
+
except ValueError as exc:
|
|
397
|
+
log.warning("Error processing signature on sync: {}".format(str(exc)))
|
|
396
398
|
return
|
|
397
399
|
|
|
398
400
|
sig_digest = hashlib.sha256(signature_raw).hexdigest()
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import hashlib
|
|
3
3
|
import fnmatch
|
|
4
|
-
import re
|
|
5
|
-
import subprocess
|
|
6
|
-
import gnupg
|
|
7
4
|
import json
|
|
8
5
|
import logging
|
|
9
6
|
import time
|
|
@@ -15,6 +12,8 @@ from django.db import IntegrityError
|
|
|
15
12
|
from functools import partial
|
|
16
13
|
from rest_framework.exceptions import Throttled
|
|
17
14
|
|
|
15
|
+
from pysequoia.packet import PacketPile, Tag
|
|
16
|
+
|
|
18
17
|
from pulpcore.plugin.models import Artifact, Task
|
|
19
18
|
from pulpcore.plugin.util import get_domain
|
|
20
19
|
|
|
@@ -32,9 +31,6 @@ from pulp_container.app.json_schemas import (
|
|
|
32
31
|
SIGNATURE_SCHEMA,
|
|
33
32
|
)
|
|
34
33
|
|
|
35
|
-
KEY_ID_REGEX_COMPILED = re.compile(r"keyid ([0-9A-F]+)")
|
|
36
|
-
TIMESTAMP_REGEX_COMPILED = re.compile(r"created ([0-9]+)")
|
|
37
|
-
|
|
38
34
|
signature_validator = Draft7Validator(SIGNATURE_SCHEMA)
|
|
39
35
|
|
|
40
36
|
log = logging.getLogger(__name__)
|
|
@@ -86,6 +82,20 @@ def urlpath_sanitize(*args):
|
|
|
86
82
|
return "/".join(segments)
|
|
87
83
|
|
|
88
84
|
|
|
85
|
+
def keyid_from_fingerprint(fingerprint):
|
|
86
|
+
"""Derive a key ID from an OpenPGP fingerprint.
|
|
87
|
+
|
|
88
|
+
For v4 fingerprints (40 hex chars / 20 bytes), the key ID is the last 8 bytes.
|
|
89
|
+
For v6 fingerprints (64 hex chars / 32 bytes), the key ID is the first 8 bytes.
|
|
90
|
+
"""
|
|
91
|
+
if len(fingerprint) == 40:
|
|
92
|
+
return fingerprint[-16:]
|
|
93
|
+
elif len(fingerprint) == 64:
|
|
94
|
+
return fingerprint[:16]
|
|
95
|
+
else:
|
|
96
|
+
raise ValueError(f"Unexpected fingerprint length: {len(fingerprint)}")
|
|
97
|
+
|
|
98
|
+
|
|
89
99
|
def extract_data_from_signature(signature_raw, man_digest):
|
|
90
100
|
"""
|
|
91
101
|
Extract data from an "integrated" signature, aka a signed non-encrypted document.
|
|
@@ -98,37 +108,56 @@ def extract_data_from_signature(signature_raw, man_digest):
|
|
|
98
108
|
dict: JSON representation of the document and available data about signature
|
|
99
109
|
|
|
100
110
|
"""
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"
|
|
111
|
+
try:
|
|
112
|
+
pile = PacketPile.from_bytes(signature_raw)
|
|
113
|
+
except Exception as exc:
|
|
114
|
+
raise ValueError(
|
|
115
|
+
"Signed document for manifest {} is un-parseable: {}".format(man_digest, str(exc))
|
|
106
116
|
)
|
|
107
|
-
|
|
117
|
+
|
|
118
|
+
literal_data = None
|
|
119
|
+
signing_key_id = None
|
|
120
|
+
signing_key_fingerprint = None
|
|
121
|
+
signature_timestamp = None
|
|
122
|
+
|
|
123
|
+
for packet in pile:
|
|
124
|
+
if packet.tag == Tag.Literal:
|
|
125
|
+
literal_data = bytes(packet.literal_data)
|
|
126
|
+
elif packet.tag == Tag.Signature:
|
|
127
|
+
if packet.issuer_key_id is not None:
|
|
128
|
+
signing_key_id = packet.issuer_key_id.upper()
|
|
129
|
+
elif packet.issuer_fingerprint is not None:
|
|
130
|
+
signing_key_fingerprint = packet.issuer_fingerprint.upper()
|
|
131
|
+
signing_key_id = keyid_from_fingerprint(signing_key_fingerprint)
|
|
132
|
+
else:
|
|
133
|
+
raise ValueError(
|
|
134
|
+
"Signature for manifest {} has no fingerprint or key_id".format(man_digest)
|
|
135
|
+
)
|
|
136
|
+
if packet.signature_created is not None:
|
|
137
|
+
signature_timestamp = int(packet.signature_created.timestamp())
|
|
138
|
+
|
|
139
|
+
if not literal_data:
|
|
140
|
+
raise ValueError("Signature for manifest {} has no literal data".format(man_digest))
|
|
108
141
|
|
|
109
142
|
try:
|
|
110
|
-
sig_json = json.loads(
|
|
143
|
+
sig_json = json.loads(literal_data)
|
|
111
144
|
except Exception as exc:
|
|
112
|
-
|
|
113
|
-
"Signed document cannot be parsed to create a signature for {}."
|
|
114
|
-
|
|
145
|
+
raise ValueError(
|
|
146
|
+
"Signed document cannot be parsed to create a signature for {}. Error: {}".format(
|
|
147
|
+
man_digest, str(exc)
|
|
148
|
+
)
|
|
115
149
|
)
|
|
116
|
-
return
|
|
117
150
|
|
|
118
151
|
errors = []
|
|
119
152
|
for error in signature_validator.iter_errors(sig_json):
|
|
120
153
|
errors.append(f'{".".join(error.path)}: {error.message}')
|
|
121
154
|
|
|
122
155
|
if errors:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# fields since they are not encrypted and still readable without decrypting the signature first
|
|
129
|
-
packets = subprocess.check_output(["gpg", "--list-packets"], input=signature_raw).decode()
|
|
130
|
-
sig_json["signing_key_id"] = KEY_ID_REGEX_COMPILED.search(packets).group(1)
|
|
131
|
-
sig_json["signature_timestamp"] = TIMESTAMP_REGEX_COMPILED.search(packets).group(1)
|
|
156
|
+
raise ValueError("The signature for {} is not synced due to: {}".format(man_digest, errors))
|
|
157
|
+
|
|
158
|
+
sig_json["signing_key_id"] = signing_key_id
|
|
159
|
+
sig_json["signing_key_fingerprint"] = signing_key_fingerprint
|
|
160
|
+
sig_json["signature_timestamp"] = signature_timestamp
|
|
132
161
|
|
|
133
162
|
return sig_json
|
|
134
163
|
|
|
@@ -10,13 +10,11 @@ from pulp_container.constants import MANIFEST_TYPE
|
|
|
10
10
|
def containerfile_name():
|
|
11
11
|
"""A fixture for a basic container file used for building images."""
|
|
12
12
|
with NamedTemporaryFile() as containerfile:
|
|
13
|
-
containerfile.write(
|
|
14
|
-
b"""FROM quay.io/quay/busybox:latest
|
|
13
|
+
containerfile.write(b"""FROM quay.io/quay/busybox:latest
|
|
15
14
|
# Copy a file using COPY statement. Use the relative path specified in the 'artifacts' parameter.
|
|
16
15
|
COPY foo/bar/example.txt /tmp/inside-image.txt
|
|
17
16
|
# Print the content of the file when the container starts
|
|
18
|
-
CMD ["cat", "/tmp/inside-image.txt"]"""
|
|
19
|
-
)
|
|
17
|
+
CMD ["cat", "/tmp/inside-image.txt"]""")
|
|
20
18
|
containerfile.flush()
|
|
21
19
|
yield containerfile.name
|
|
22
20
|
|
|
@@ -215,11 +213,9 @@ def test_without_build_context(
|
|
|
215
213
|
|
|
216
214
|
def containerfile_without_context_files():
|
|
217
215
|
with NamedTemporaryFile() as containerfile:
|
|
218
|
-
containerfile.write(
|
|
219
|
-
b"""FROM quay.io/quay/busybox:latest
|
|
216
|
+
containerfile.write(b"""FROM quay.io/quay/busybox:latest
|
|
220
217
|
# Print the content of the file when the container starts
|
|
221
|
-
CMD ["ls", "/"]"""
|
|
222
|
-
)
|
|
218
|
+
CMD ["ls", "/"]""")
|
|
223
219
|
containerfile.flush()
|
|
224
220
|
yield containerfile.name
|
|
225
221
|
|
|
@@ -9,6 +9,9 @@ IMAGE_MANIFEST_TAG = "7.9-511-source"
|
|
|
9
9
|
MANIFEST_LIST_TAG = "7.9"
|
|
10
10
|
SIGSTORE_URL = "https://access.redhat.com/webassets/docker/content/sigstore"
|
|
11
11
|
|
|
12
|
+
UBI10_MICRO_REPOSITORY_NAME = "ubi10-micro"
|
|
13
|
+
UBI10_MICRO_TAG = "latest"
|
|
14
|
+
|
|
12
15
|
|
|
13
16
|
@pytest.fixture
|
|
14
17
|
def synced_repository(
|
|
@@ -120,3 +123,66 @@ def test_sync_images_without_sigstore_requiring_signatures(container_bindings, s
|
|
|
120
123
|
repository_version=synced_repository.latest_version_href
|
|
121
124
|
).results
|
|
122
125
|
assert len(tags) == 0
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_sync_image_with_pqc_signatures(
|
|
129
|
+
delete_orphans_pre,
|
|
130
|
+
container_repo,
|
|
131
|
+
container_remote_factory,
|
|
132
|
+
container_bindings,
|
|
133
|
+
monitor_task,
|
|
134
|
+
):
|
|
135
|
+
"""Sync ubi10-micro:latest from registry.access.redhat.com with all signatures."""
|
|
136
|
+
data = gen_container_remote(
|
|
137
|
+
url=REDHAT_REGISTRY_V2,
|
|
138
|
+
upstream_name=UBI10_MICRO_REPOSITORY_NAME,
|
|
139
|
+
policy="on_demand",
|
|
140
|
+
include_tags=[UBI10_MICRO_TAG],
|
|
141
|
+
sigstore=SIGSTORE_URL,
|
|
142
|
+
)
|
|
143
|
+
remote = container_remote_factory(**data)
|
|
144
|
+
|
|
145
|
+
sync_data = {"remote": remote.pulp_href, "signed_only": False}
|
|
146
|
+
response = container_bindings.RepositoriesContainerApi.sync(container_repo.pulp_href, sync_data)
|
|
147
|
+
monitor_task(response.task)
|
|
148
|
+
|
|
149
|
+
repo = container_bindings.RepositoriesContainerApi.read(container_repo.pulp_href)
|
|
150
|
+
|
|
151
|
+
tags = container_bindings.ContentTagsApi.list(
|
|
152
|
+
repository_version=repo.latest_version_href
|
|
153
|
+
).results
|
|
154
|
+
assert len(tags) == 1
|
|
155
|
+
assert tags[0].name == UBI10_MICRO_TAG
|
|
156
|
+
|
|
157
|
+
signatures = container_bindings.ContentSignaturesApi.list(
|
|
158
|
+
repository_version=repo.latest_version_href
|
|
159
|
+
).results
|
|
160
|
+
assert len(signatures) > 0
|
|
161
|
+
|
|
162
|
+
# Assert that a signature using one of the "old" Red Hat signing release keys exist
|
|
163
|
+
expected_key_ids = ["199E2F91FD431D51", "E60D446E63405576"]
|
|
164
|
+
assert any(s.key_id in expected_key_ids for s in signatures), (
|
|
165
|
+
f"No signature found with key_ids {expected_key_ids}; "
|
|
166
|
+
f"found key_ids: {sorted({s.key_id for s in signatures})}"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# Assert that a signature using the Red Hat PQC (ML-DSA-87) signing key exists
|
|
170
|
+
# Fingerprint: FCD355B305707A62DA143AB6E422397E50FE8467A2A95343D246D6276AFEDF8F
|
|
171
|
+
# Key ID => first 8 bytes (16 hex chars)
|
|
172
|
+
expected_key_id = "FCD355B305707A62"
|
|
173
|
+
assert any(s.key_id == expected_key_id for s in signatures), (
|
|
174
|
+
f"No signature found with key_id {expected_key_id!r}; "
|
|
175
|
+
f"found key_ids: {sorted({s.key_id for s in signatures})}"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# ubi10-micro:latest is a manifest list; collect all listed manifests and verify
|
|
179
|
+
# that each has at least one signature
|
|
180
|
+
manifest_list = container_bindings.ContentManifestsApi.read(tags[0].tagged_manifest)
|
|
181
|
+
listed_manifests = [
|
|
182
|
+
container_bindings.ContentManifestsApi.read(lm_href)
|
|
183
|
+
for lm_href in manifest_list.listed_manifests
|
|
184
|
+
]
|
|
185
|
+
for lm in listed_manifests:
|
|
186
|
+
lm_signatures = [s for s in signatures if s.signed_manifest == lm.pulp_href]
|
|
187
|
+
assert len(lm_signatures) > 0, f"No signatures found for manifest {lm.digest}"
|
|
188
|
+
assert all(s.name.startswith(lm.digest) for s in lm_signatures)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pulp-container
|
|
3
|
-
Version: 2.27.
|
|
3
|
+
Version: 2.27.4
|
|
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
|
|
@@ -20,4 +20,5 @@ License-File: LICENSE
|
|
|
20
20
|
Requires-Dist: jsonschema<4.26,>=4.4
|
|
21
21
|
Requires-Dist: pulpcore<3.115,>=3.73.2
|
|
22
22
|
Requires-Dist: pyjwt[crypto]<2.11,>=2.4
|
|
23
|
+
Requires-Dist: pysequoia==0.1.32
|
|
23
24
|
Dynamic: license-file
|
|
@@ -7,7 +7,7 @@ build-backend = 'setuptools.build_meta'
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "pulp-container"
|
|
10
|
-
version = "2.27.
|
|
10
|
+
version = "2.27.4"
|
|
11
11
|
description = "Container plugin for the Pulp Project"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
authors = [
|
|
@@ -26,6 +26,7 @@ dependencies = [
|
|
|
26
26
|
"jsonschema>=4.4,<4.26",
|
|
27
27
|
"pulpcore>=3.73.2,<3.115",
|
|
28
28
|
"pyjwt[crypto]>=2.4,<2.11",
|
|
29
|
+
"pysequoia==0.1.32",
|
|
29
30
|
]
|
|
30
31
|
|
|
31
32
|
[project.urls]
|
|
@@ -81,12 +82,14 @@ ignore = [
|
|
|
81
82
|
".github/**",
|
|
82
83
|
"lint_requirements.txt",
|
|
83
84
|
".flake8",
|
|
85
|
+
"AGENTS.md",
|
|
86
|
+
"CLAUDE.md",
|
|
84
87
|
]
|
|
85
88
|
|
|
86
89
|
[tool.bumpversion]
|
|
87
90
|
# This section is managed by the plugin template. Do not edit manually.
|
|
88
91
|
|
|
89
|
-
current_version = "2.27.
|
|
92
|
+
current_version = "2.27.4"
|
|
90
93
|
commit = false
|
|
91
94
|
tag = false
|
|
92
95
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<alpha>0a)?(?P<patch>\\d+)(\\.(?P<release>[a-z]+))?"
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
from pulpcore.plugin import PulpPluginAppConfig
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class PulpContainerPluginAppConfig(PulpPluginAppConfig):
|
|
5
|
-
"""Entry point for the container plugin."""
|
|
6
|
-
|
|
7
|
-
name = "pulp_container.app"
|
|
8
|
-
label = "container"
|
|
9
|
-
version = "2.27.2"
|
|
10
|
-
python_package_name = "pulp-container"
|
|
11
|
-
domain_compatible = True
|
|
12
|
-
|
|
13
|
-
def ready(self):
|
|
14
|
-
super().ready()
|
|
15
|
-
from . import checks
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/global_access_conditions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/management/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0001_initial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0003_oci_mediatype.py
RENAMED
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0004_upload.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0039_manifest_data.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/migrations/0044_add_domain.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/download_image_data.py
RENAMED
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/tasks/recursive_remove.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/webserver_snippets/__init__.py
RENAMED
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/webserver_snippets/apache.conf
RENAMED
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/app/webserver_snippets/nginx.conf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_domains.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/api/test_sync.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/functional/constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/unit/test_json_schemas.py
RENAMED
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container/tests/unit/test_serializers.py
RENAMED
|
File without changes
|
|
File without changes
|
{pulp_container-2.27.2 → pulp_container-2.27.4}/pulp_container.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|