pulp-python 3.28.2__tar.gz → 3.30.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.
- {pulp_python-3.28.2 → pulp_python-3.30.0}/CHANGES.md +85 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/PKG-INFO +1 -1
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/__init__.py +5 -3
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/management/commands/repair-python-metadata.py +7 -3
- pulp_python-3.30.0/pulp_python/app/migrations/0022_pythonblocklistentry.py +48 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/modelresource.py +1 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/models.py +78 -12
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/pypi/serializers.py +7 -5
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/pypi/views.py +23 -24
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/replica.py +3 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/serializers.py +136 -14
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/tasks/publish.py +2 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/tasks/repair.py +4 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/tasks/sync.py +13 -15
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/tasks/upload.py +7 -6
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/utils.py +8 -6
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/viewsets.py +81 -3
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/pytest_plugin.py +8 -6
- pulp_python-3.30.0/pulp_python/tests/functional/api/test_blocklist.py +152 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_consume_content.py +0 -1
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_crud_content_unit.py +5 -4
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_crud_publications.py +6 -5
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_crud_remotes.py +3 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_domains.py +6 -5
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_export_import.py +5 -3
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_pypi_simple_api.py +2 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_rbac.py +5 -4
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_repair.py +2 -1
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_upload.py +5 -3
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python.egg-info/PKG-INFO +1 -1
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python.egg-info/SOURCES.txt +2 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pyproject.toml +31 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/COMMITMENT +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/COPYRIGHT +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/LICENSE +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/MANIFEST.in +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/README.md +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/functest_requirements.txt +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/global_access_conditions.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/management/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/management/commands/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0001_initial.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0001_squashed_0010_update_json_field.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0002_pythonpackagecontent_python_version.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0003_new_sync_filters.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0004_DATA_swap_distribution_model.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0005_pythonpackagecontent_sha256.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0006_pythonrepository_autopublish.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0007_pythonpackagecontent_mv-2-1.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0008_pythonpackagecontent_unique_sha256.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0009_pythondistribution_allow_uploads.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0010_update_json_field.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0011_alter_pythondistribution_distribution_ptr_and_more.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0012_add_domain.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0013_add_rbac_permissions.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0014_pythonpackagecontent_dynamic_and_more.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0015_alter_pythonpackagecontent_options.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0016_pythonpackagecontent_metadata_sha256.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0017_pythonpackagecontent_size.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0018_packageprovenance.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0019_create_missing_metadata_artifacts.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0020_pythonpackagecontent_name_normalized.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/0021_pythonrepository_upload_duplicate_filenames.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/migrations/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/provenance.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/pypi/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/settings.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/tasks/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/tasks/vulnerability_report.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/urls.py +2 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/webserver_snippets/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/webserver_snippets/apache.conf +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/app/webserver_snippets/nginx.conf +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_attestations.py +2 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_auto_publish.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_download_content.py +2 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_full_mirror.py +9 -9
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_pypi_apis.py +5 -5
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_sync.py +11 -11
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/api/test_vulnerability_report.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/assets/shelf-reader-0.1.tar.gz.publish.attestation +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/assets/shelf_reader-0.1-py2-none-any.whl.publish.attestation +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/constants.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/functional/utils.py +2 -2
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/unit/__init__.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python/tests/unit/test_models.py +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python.egg-info/dependency_links.txt +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python.egg-info/entry_points.txt +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python.egg-info/requires.txt +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/pulp_python.egg-info/top_level.txt +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/setup.cfg +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/test_requirements.txt +0 -0
- {pulp_python-3.28.2 → pulp_python-3.30.0}/unittest_requirements.txt +0 -0
|
@@ -8,6 +8,35 @@
|
|
|
8
8
|
|
|
9
9
|
[//]: # (towncrier release notes start)
|
|
10
10
|
|
|
11
|
+
## 3.30.0 (2026-05-13) {: #3.30.0 }
|
|
12
|
+
|
|
13
|
+
#### Features {: #3.30.0-feature }
|
|
14
|
+
|
|
15
|
+
- Added filtering by `name`, `version`, and `filename` to the blocklist entries API endpoint.
|
|
16
|
+
[#1229](https://github.com/pulp/pulp_python/issues/1229)
|
|
17
|
+
|
|
18
|
+
#### Deprecations and Removals {: #3.30.0-removal }
|
|
19
|
+
|
|
20
|
+
- Deprecated the `repair-python-metadata` management command in favor of the repository `repair_metadata` task.
|
|
21
|
+
[#1207](https://github.com/pulp/pulp_python/issues/1207)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 3.29.0 (2026-04-17) {: #3.29.0 }
|
|
26
|
+
|
|
27
|
+
#### Features {: #3.29.0-feature }
|
|
28
|
+
|
|
29
|
+
- Added repository-specific package blocklist.
|
|
30
|
+
[#1166](https://github.com/pulp/pulp_python/issues/1166)
|
|
31
|
+
|
|
32
|
+
#### Bugfixes {: #3.29.0-bugfix }
|
|
33
|
+
|
|
34
|
+
- Fixed "Worker has gone missing" errors during repair_metadata on large repositories (1000+ packages) by reducing peak memory consumption.
|
|
35
|
+
[#1188](https://github.com/pulp/pulp_python/issues/1188)
|
|
36
|
+
- Support "atomic" replications in pulpcore 3.107
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
11
40
|
## 3.28.2 (2026-04-14) {: #3.28.2 }
|
|
12
41
|
|
|
13
42
|
#### Bugfixes {: #3.28.2-bugfix }
|
|
@@ -42,6 +71,23 @@
|
|
|
42
71
|
|
|
43
72
|
---
|
|
44
73
|
|
|
74
|
+
## 3.27.2 (2026-04-14) {: #3.27.2 }
|
|
75
|
+
|
|
76
|
+
#### Bugfixes {: #3.27.2-bugfix }
|
|
77
|
+
|
|
78
|
+
- Fixed "Worker has gone missing" errors during repair_metadata on large repositories (1000+ packages) by reducing peak memory consumption.
|
|
79
|
+
[#1188](https://github.com/pulp/pulp_python/issues/1188)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 3.27.1 (2026-04-01) {: #3.27.1 }
|
|
84
|
+
|
|
85
|
+
#### Bugfixes {: #3.27.1-bugfix }
|
|
86
|
+
|
|
87
|
+
- Support "atomic" replications in pulpcore 3.107
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
45
91
|
## 3.27.0 (2026-03-17) {: #3.27.0 }
|
|
46
92
|
|
|
47
93
|
#### Bugfixes {: #3.27.0-bugfix }
|
|
@@ -243,6 +289,23 @@
|
|
|
243
289
|
|
|
244
290
|
---
|
|
245
291
|
|
|
292
|
+
## 3.19.3 (2026-05-04) {: #3.19.3 }
|
|
293
|
+
|
|
294
|
+
#### Bugfixes {: #3.19.3-bugfix }
|
|
295
|
+
|
|
296
|
+
- Fixed pull-through caching not checking the repository if package was not present on remote.
|
|
297
|
+
[#1004](https://github.com/pulp/pulp_python/issues/1004)
|
|
298
|
+
- Fixed pull-through caching failing for packages with bad names.
|
|
299
|
+
[#1040](https://github.com/pulp/pulp_python/issues/1040)
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## 3.19.2 (2026-04-28) {: #3.19.2 }
|
|
304
|
+
|
|
305
|
+
No significant changes.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
246
309
|
## 3.19.1 (2025-09-14) {: #3.19.1 }
|
|
247
310
|
|
|
248
311
|
#### Bugfixes {: #3.19.1-bugfix }
|
|
@@ -349,6 +412,14 @@
|
|
|
349
412
|
|
|
350
413
|
---
|
|
351
414
|
|
|
415
|
+
## 3.13.6 (2026-04-01) {: #3.13.6 }
|
|
416
|
+
|
|
417
|
+
#### Bugfixes {: #3.13.6-bugfix }
|
|
418
|
+
|
|
419
|
+
- Support "atomic" replications in pulpcore 3.107
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
352
423
|
## 3.13.5 (2025-04-23) {: #3.13.5 }
|
|
353
424
|
|
|
354
425
|
No significant changes.
|
|
@@ -415,6 +486,14 @@ No significant changes.
|
|
|
415
486
|
|
|
416
487
|
---
|
|
417
488
|
|
|
489
|
+
## 3.12.9 (2026-04-01) {: #3.12.9 }
|
|
490
|
+
|
|
491
|
+
#### Bugfixes {: #3.12.9-bugfix }
|
|
492
|
+
|
|
493
|
+
- Support "atomic" replications in pulpcore 3.107
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
418
497
|
## 3.12.8 (2025-11-18) {: #3.12.8 }
|
|
419
498
|
|
|
420
499
|
No significant changes.
|
|
@@ -507,6 +586,12 @@ No significant changes.
|
|
|
507
586
|
|
|
508
587
|
---
|
|
509
588
|
|
|
589
|
+
## 3.11.8 (2026-04-21) {: #3.11.8 }
|
|
590
|
+
|
|
591
|
+
No significant changes.
|
|
592
|
+
|
|
593
|
+
---
|
|
594
|
+
|
|
510
595
|
## 3.11.7 (2025-11-18) {: #3.11.7 }
|
|
511
596
|
|
|
512
597
|
No significant changes.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
from gettext import gettext as _
|
|
2
|
+
|
|
1
3
|
from django.db.models.signals import post_migrate
|
|
4
|
+
|
|
2
5
|
from pulpcore.plugin import PulpPluginAppConfig
|
|
3
|
-
from gettext import gettext as _
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
class PulpPythonPluginAppConfig(PulpPluginAppConfig):
|
|
@@ -10,7 +12,7 @@ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
|
|
|
10
12
|
|
|
11
13
|
name = "pulp_python.app"
|
|
12
14
|
label = "python"
|
|
13
|
-
version = "3.
|
|
15
|
+
version = "3.30.0"
|
|
14
16
|
python_package_name = "pulp-python"
|
|
15
17
|
domain_compatible = True
|
|
16
18
|
|
|
@@ -26,7 +28,7 @@ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
|
|
|
26
28
|
|
|
27
29
|
# TODO: Remove this when https://github.com/pulp/pulpcore/issues/5500 is resolved
|
|
28
30
|
def _populate_pypi_access_policies(sender, apps, verbosity, **kwargs):
|
|
29
|
-
from pulp_python.app.pypi.views import PyPIView, SimpleView, UploadView
|
|
31
|
+
from pulp_python.app.pypi.views import MetadataView, PyPIView, SimpleView, UploadView
|
|
30
32
|
|
|
31
33
|
try:
|
|
32
34
|
AccessPolicy = apps.get_model("core", "AccessPolicy")
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import re
|
|
2
1
|
import os
|
|
3
|
-
|
|
2
|
+
import re
|
|
4
3
|
from gettext import gettext as _
|
|
5
4
|
|
|
6
5
|
from django.conf import settings
|
|
6
|
+
from django.core.management import BaseCommand, CommandError
|
|
7
7
|
|
|
8
8
|
from pulpcore.plugin.util import extract_pk
|
|
9
|
+
|
|
9
10
|
from pulp_python.app.models import PythonPackageContent, PythonRepository
|
|
10
11
|
from pulp_python.app.utils import artifact_to_python_content_data
|
|
11
12
|
|
|
@@ -78,7 +79,10 @@ class Command(BaseCommand):
|
|
|
78
79
|
Management command to repair metadata of PythonPackageContent.
|
|
79
80
|
"""
|
|
80
81
|
|
|
81
|
-
help = _(
|
|
82
|
+
help = _(
|
|
83
|
+
"[Deprecated] Use the repository `repair_metadata` task instead. "
|
|
84
|
+
"Repair the metadata of PythonPackageContent stored in PythonRepositories."
|
|
85
|
+
)
|
|
82
86
|
|
|
83
87
|
def add_arguments(self, parser):
|
|
84
88
|
"""Set up arguments."""
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Generated by Django 5.2.10 on 2026-04-16 14:00
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
import django_lifecycle.mixins
|
|
5
|
+
import pulpcore.app.models.base
|
|
6
|
+
from django.db import migrations, models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Migration(migrations.Migration):
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
("python", "0021_pythonrepository_upload_duplicate_filenames"),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
operations = [
|
|
16
|
+
migrations.CreateModel(
|
|
17
|
+
name="PythonBlocklistEntry",
|
|
18
|
+
fields=[
|
|
19
|
+
(
|
|
20
|
+
"pulp_id",
|
|
21
|
+
models.UUIDField(
|
|
22
|
+
default=pulpcore.app.models.base.pulp_uuid,
|
|
23
|
+
editable=False,
|
|
24
|
+
primary_key=True,
|
|
25
|
+
serialize=False,
|
|
26
|
+
),
|
|
27
|
+
),
|
|
28
|
+
("pulp_created", models.DateTimeField(auto_now_add=True)),
|
|
29
|
+
("pulp_last_updated", models.DateTimeField(auto_now=True, null=True)),
|
|
30
|
+
("name", models.TextField(default=None, null=True)),
|
|
31
|
+
("version", models.TextField(default=None, null=True)),
|
|
32
|
+
("filename", models.TextField(default=None, null=True)),
|
|
33
|
+
("added_by", models.TextField(default="")),
|
|
34
|
+
(
|
|
35
|
+
"repository",
|
|
36
|
+
models.ForeignKey(
|
|
37
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
38
|
+
related_name="blocklist_entries",
|
|
39
|
+
to="python.pythonrepository",
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
],
|
|
43
|
+
options={
|
|
44
|
+
"default_related_name": "%(app_label)s_%(model_name)s",
|
|
45
|
+
},
|
|
46
|
+
bases=(django_lifecycle.mixins.LifecycleModelMixin, models.Model),
|
|
47
|
+
),
|
|
48
|
+
]
|
|
@@ -1,43 +1,45 @@
|
|
|
1
1
|
import hashlib
|
|
2
2
|
import json
|
|
3
3
|
from logging import getLogger
|
|
4
|
+
from pathlib import PurePath
|
|
4
5
|
|
|
5
6
|
from aiohttp.web import json_response
|
|
7
|
+
from django.conf import settings
|
|
6
8
|
from django.contrib.postgres.fields import ArrayField
|
|
7
9
|
from django.core.exceptions import ObjectDoesNotExist
|
|
8
10
|
from django.db import models
|
|
9
|
-
from django.conf import settings
|
|
10
11
|
from django_lifecycle import (
|
|
11
12
|
BEFORE_SAVE,
|
|
12
13
|
hook,
|
|
13
14
|
)
|
|
14
15
|
from rest_framework.serializers import ValidationError
|
|
16
|
+
|
|
15
17
|
from pulpcore.plugin.models import (
|
|
16
18
|
AutoAddObjPermsMixin,
|
|
19
|
+
BaseModel,
|
|
17
20
|
Content,
|
|
18
|
-
Publication,
|
|
19
21
|
Distribution,
|
|
22
|
+
Publication,
|
|
20
23
|
Remote,
|
|
21
24
|
Repository,
|
|
22
25
|
)
|
|
26
|
+
from pulpcore.plugin.repo_version_utils import (
|
|
27
|
+
collect_duplicates,
|
|
28
|
+
remove_duplicates,
|
|
29
|
+
validate_repo_version,
|
|
30
|
+
)
|
|
23
31
|
from pulpcore.plugin.responses import ArtifactResponse
|
|
32
|
+
from pulpcore.plugin.util import get_domain, get_domain_pk
|
|
24
33
|
|
|
25
|
-
from pathlib import PurePath
|
|
26
34
|
from .provenance import Provenance
|
|
27
35
|
from .utils import (
|
|
28
|
-
|
|
36
|
+
PYPI_LAST_SERIAL,
|
|
37
|
+
PYPI_SERIAL_CONSTANT,
|
|
29
38
|
artifact_to_metadata_artifact,
|
|
39
|
+
artifact_to_python_content_data,
|
|
30
40
|
canonicalize_name,
|
|
31
41
|
python_content_to_json,
|
|
32
|
-
PYPI_LAST_SERIAL,
|
|
33
|
-
PYPI_SERIAL_CONSTANT,
|
|
34
|
-
)
|
|
35
|
-
from pulpcore.plugin.repo_version_utils import (
|
|
36
|
-
collect_duplicates,
|
|
37
|
-
remove_duplicates,
|
|
38
|
-
validate_repo_version,
|
|
39
42
|
)
|
|
40
|
-
from pulpcore.plugin.util import get_domain_pk, get_domain
|
|
41
43
|
|
|
42
44
|
log = getLogger(__name__)
|
|
43
45
|
|
|
@@ -399,9 +401,12 @@ class PythonRepository(Repository, AutoAddObjPermsMixin):
|
|
|
399
401
|
|
|
400
402
|
When allow_package_substitution is False, reject any new version that would implicitly
|
|
401
403
|
replace existing content with different checksums (content substitution).
|
|
404
|
+
|
|
405
|
+
Also checks newly added content against the repository's blocklist entries.
|
|
402
406
|
"""
|
|
403
407
|
if not self.allow_package_substitution:
|
|
404
408
|
self._check_for_package_substitution(new_version)
|
|
409
|
+
self._check_blocklist(new_version)
|
|
405
410
|
remove_duplicates(new_version)
|
|
406
411
|
validate_repo_version(new_version)
|
|
407
412
|
|
|
@@ -418,3 +423,64 @@ class PythonRepository(Repository, AutoAddObjPermsMixin):
|
|
|
418
423
|
"To allow this, set 'allow_package_substitution' to True on the repository. "
|
|
419
424
|
f"Conflicting packages: {duplicates}"
|
|
420
425
|
)
|
|
426
|
+
|
|
427
|
+
def _check_blocklist(self, new_version):
|
|
428
|
+
"""
|
|
429
|
+
Check newly added content in a repository version against the blocklist.
|
|
430
|
+
"""
|
|
431
|
+
added_content = PythonPackageContent.objects.filter(
|
|
432
|
+
pk__in=new_version.added().values_list("pk", flat=True)
|
|
433
|
+
).only("filename", "name_normalized", "version")
|
|
434
|
+
if added_content.exists():
|
|
435
|
+
self.check_blocklist_for_packages(added_content)
|
|
436
|
+
|
|
437
|
+
def check_blocklist_for_packages(self, packages):
|
|
438
|
+
"""
|
|
439
|
+
Raise a ValidationError if any of the given packages match a blocklist entry.
|
|
440
|
+
"""
|
|
441
|
+
entries = PythonBlocklistEntry.objects.filter(repository=self)
|
|
442
|
+
if not entries.exists():
|
|
443
|
+
return
|
|
444
|
+
|
|
445
|
+
blocked = []
|
|
446
|
+
for pkg in packages:
|
|
447
|
+
for entry in entries:
|
|
448
|
+
if entry.filename and entry.filename == pkg.filename:
|
|
449
|
+
blocked.append(pkg.filename)
|
|
450
|
+
break
|
|
451
|
+
if entry.name == pkg.name_normalized:
|
|
452
|
+
if not entry.version or entry.version == pkg.version:
|
|
453
|
+
blocked.append(pkg.filename)
|
|
454
|
+
break
|
|
455
|
+
if blocked:
|
|
456
|
+
raise ValidationError(
|
|
457
|
+
"Blocklisted packages cannot be added to this repository: {}".format(
|
|
458
|
+
", ".join(blocked)
|
|
459
|
+
)
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
class PythonBlocklistEntry(BaseModel):
|
|
464
|
+
"""
|
|
465
|
+
An entry in a PythonRepository's package blocklist.
|
|
466
|
+
|
|
467
|
+
Blocklist entries prevent packages from being added to the repository.
|
|
468
|
+
Entries can match by package `name` (all versions), package `name` + `version`,
|
|
469
|
+
or exact `filename`. Exactly one of `name` or `filename` must be provided.
|
|
470
|
+
"""
|
|
471
|
+
|
|
472
|
+
name = models.TextField(null=True, default=None)
|
|
473
|
+
version = models.TextField(null=True, default=None)
|
|
474
|
+
filename = models.TextField(null=True, default=None)
|
|
475
|
+
added_by = models.TextField(default="")
|
|
476
|
+
repository = models.ForeignKey(
|
|
477
|
+
PythonRepository, on_delete=models.CASCADE, related_name="blocklist_entries"
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
def __str__(self):
|
|
481
|
+
if self.filename:
|
|
482
|
+
return f"<{self._meta.object_name}: {self.filename}>"
|
|
483
|
+
return f"<{self._meta.object_name}: {self.name} [{self.version or 'all'}]>"
|
|
484
|
+
|
|
485
|
+
class Meta:
|
|
486
|
+
default_related_name = "%(app_label)s_%(model_name)s"
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from gettext import gettext as _
|
|
3
3
|
|
|
4
|
-
from
|
|
4
|
+
from django.db.utils import IntegrityError
|
|
5
5
|
from pydantic import TypeAdapter, ValidationError
|
|
6
|
-
from
|
|
7
|
-
|
|
6
|
+
from rest_framework import serializers
|
|
7
|
+
|
|
8
8
|
from pulpcore.plugin.models import Artifact
|
|
9
9
|
from pulpcore.plugin.util import get_domain
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
from pulp_python.app.provenance import Attestation
|
|
12
|
+
from pulp_python.app.utils import DIST_EXTENSIONS, SUPPORTED_METADATA_VERSIONS
|
|
11
13
|
|
|
12
14
|
log = logging.getLogger(__name__)
|
|
13
15
|
|
|
@@ -110,7 +112,7 @@ class PackageUploadSerializer(serializers.Serializer):
|
|
|
110
112
|
attestations = TypeAdapter(list[Attestation]).validate_python(attestations)
|
|
111
113
|
except ValidationError as e:
|
|
112
114
|
raise serializers.ValidationError(
|
|
113
|
-
{"attestations": _("The uploaded attestations are not valid: {}".format(e)
|
|
115
|
+
{"attestations": _("The uploaded attestations are not valid: {}").format(e)}
|
|
114
116
|
)
|
|
115
117
|
|
|
116
118
|
sha256 = data.get("sha256_digest")
|
|
@@ -1,60 +1,59 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
|
|
3
|
-
from
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from rest_framework.exceptions import NotAcceptable
|
|
7
|
-
from django.core.exceptions import ObjectDoesNotExist
|
|
8
|
-
from django.shortcuts import redirect
|
|
9
|
-
from datetime import datetime, timezone, timedelta
|
|
2
|
+
from datetime import datetime, timedelta, timezone
|
|
3
|
+
from itertools import chain
|
|
4
|
+
from pathlib import PurePath
|
|
5
|
+
from urllib.parse import urljoin, urlparse, urlunsplit
|
|
10
6
|
|
|
11
7
|
from django.contrib.sessions.models import Session
|
|
8
|
+
from django.core.exceptions import ObjectDoesNotExist
|
|
12
9
|
from django.db import transaction
|
|
13
10
|
from django.db.utils import DatabaseError
|
|
14
11
|
from django.http.response import (
|
|
15
12
|
Http404,
|
|
16
|
-
|
|
17
|
-
HttpResponseForbidden,
|
|
13
|
+
HttpResponse,
|
|
18
14
|
HttpResponseBadRequest,
|
|
15
|
+
HttpResponseForbidden,
|
|
16
|
+
HttpResponseNotFound,
|
|
19
17
|
StreamingHttpResponse,
|
|
20
|
-
HttpResponse,
|
|
21
18
|
)
|
|
19
|
+
from django.shortcuts import redirect
|
|
22
20
|
from drf_spectacular.utils import extend_schema
|
|
23
21
|
from dynaconf import settings
|
|
24
|
-
from itertools import chain
|
|
25
22
|
from packaging.utils import canonicalize_name
|
|
26
|
-
from
|
|
27
|
-
from
|
|
23
|
+
from rest_framework.exceptions import NotAcceptable
|
|
24
|
+
from rest_framework.renderers import BrowsableAPIRenderer, JSONRenderer, TemplateHTMLRenderer
|
|
25
|
+
from rest_framework.response import Response
|
|
26
|
+
from rest_framework.viewsets import ViewSet
|
|
28
27
|
|
|
29
|
-
from pulpcore.plugin.viewsets import OperationPostponedResponse
|
|
30
28
|
from pulpcore.plugin.tasking import dispatch
|
|
31
29
|
from pulpcore.plugin.util import get_domain, get_url
|
|
30
|
+
from pulpcore.plugin.viewsets import OperationPostponedResponse
|
|
31
|
+
|
|
32
|
+
from pulp_python.app import tasks
|
|
32
33
|
from pulp_python.app.models import (
|
|
34
|
+
PackageProvenance,
|
|
33
35
|
PythonDistribution,
|
|
34
36
|
PythonPackageContent,
|
|
35
37
|
PythonPublication,
|
|
36
|
-
PackageProvenance,
|
|
37
38
|
)
|
|
38
39
|
from pulp_python.app.pypi.serializers import (
|
|
39
|
-
SummarySerializer,
|
|
40
40
|
PackageMetadataSerializer,
|
|
41
41
|
PackageUploadSerializer,
|
|
42
42
|
PackageUploadTaskSerializer,
|
|
43
|
+
SummarySerializer,
|
|
43
44
|
)
|
|
44
45
|
from pulp_python.app.utils import (
|
|
45
|
-
write_simple_index,
|
|
46
|
-
write_simple_index_json,
|
|
47
|
-
write_simple_detail,
|
|
48
|
-
write_simple_detail_json,
|
|
49
|
-
python_content_to_json,
|
|
50
46
|
PYPI_LAST_SERIAL,
|
|
51
47
|
PYPI_SERIAL_CONSTANT,
|
|
52
48
|
get_remote_package_filter,
|
|
53
49
|
get_remote_simple_page,
|
|
50
|
+
python_content_to_json,
|
|
51
|
+
write_simple_detail,
|
|
52
|
+
write_simple_detail_json,
|
|
53
|
+
write_simple_index,
|
|
54
|
+
write_simple_index_json,
|
|
54
55
|
)
|
|
55
56
|
|
|
56
|
-
from pulp_python.app import tasks
|
|
57
|
-
|
|
58
57
|
log = logging.getLogger(__name__)
|
|
59
58
|
|
|
60
59
|
ORIGIN_HOST = settings.CONTENT_ORIGIN if settings.CONTENT_ORIGIN else settings.PYPI_API_HOSTNAME
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
from pulpcore.plugin.replica import Replicator
|
|
2
|
-
|
|
3
1
|
from pulp_glue.python.context import (
|
|
4
2
|
PulpPythonDistributionContext,
|
|
5
3
|
PulpPythonPublicationContext,
|
|
6
4
|
PulpPythonRepositoryContext,
|
|
7
5
|
)
|
|
6
|
+
|
|
7
|
+
from pulpcore.plugin.replica import Replicator
|
|
8
|
+
|
|
8
9
|
from pulp_python.app.models import PythonDistribution, PythonRemote, PythonRepository
|
|
9
10
|
from pulp_python.app.tasks import sync as python_sync
|
|
10
11
|
|