Skip to content

Commit ed996a1

Browse files
committed
Switch push created repo to ContainerRepository
https://redhat.atlassian.net/browse/PULP-1748 Assisted by: cursor composer 2
1 parent 8479d52 commit ed996a1

14 files changed

Lines changed: 142 additions & 57 deletions

CHANGES/+default-push-repo.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Changed the default created repository on push to be a ContainerRepository instead of a ContainerPushRepository. ContainerPushRepository will eventually be phased out in future releases.

pulp_container/app/registry_api.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,15 @@
4545
from pulpcore.plugin import pulp_hashlib
4646
from pulpcore.plugin.exceptions import TimeoutException
4747
from pulpcore.plugin.files import PulpTemporaryUploadedFile
48-
from pulpcore.plugin.models import Artifact, ContentArtifact, RemoteArtifact, UploadChunk
48+
from pulpcore.plugin.models import (
49+
Artifact,
50+
ContentArtifact,
51+
RemoteArtifact,
52+
Repository,
53+
UploadChunk,
54+
)
4955
from pulpcore.plugin.tasking import dispatch
50-
from pulpcore.plugin.util import get_domain, get_objects_for_user, get_url
56+
from pulpcore.plugin.util import get_domain, get_objects_for_user
5157

5258
from pulp_container.app import models, serializers
5359
from pulp_container.app.authorization import AuthorizationService, PermissionChecker
@@ -423,6 +429,7 @@ def get_dr_push(self, request, path, create=False):
423429
Optionally create them if not found.
424430
"""
425431
domain = get_domain()
432+
print("user:", request.user)
426433
try:
427434
distribution = models.ContainerDistribution.objects.get(
428435
base_path=path, pulp_domain=domain
@@ -436,12 +443,10 @@ def get_dr_push(self, request, path, create=False):
436443
repository = distribution.repository
437444
if repository:
438445
repository = repository.cast()
439-
if not repository.PUSH_ENABLED:
440-
raise RepositoryInvalid(name=path, message="Repository is read-only.")
441446
elif create:
442447
with transaction.atomic():
443-
repository = serializers.ContainerPushRepositorySerializer.get_or_create(
444-
{"name": path, "pulp_domain": domain}
448+
repository, _ = models.ContainerRepository.objects.get_or_create(
449+
name=path, pulp_domain=domain
445450
)
446451
distribution.repository = repository
447452
distribution.save()
@@ -451,22 +456,36 @@ def get_dr_push(self, request, path, create=False):
451456

452457
def create_dr(self, path, request):
453458
domain = get_domain()
459+
repository_types = [
460+
models.ContainerRepository.get_pulp_type(),
461+
models.ContainerPushRepository.get_pulp_type(),
462+
]
454463
with transaction.atomic():
455464
try:
456-
repository = serializers.ContainerPushRepositorySerializer.get_or_create(
457-
{"name": path, "pulp_domain": domain}
458-
)
459-
distribution = serializers.ContainerDistributionSerializer.get_or_create(
460-
{"base_path": path, "name": path, "pulp_domain": domain},
461-
{"repository": get_url(repository)},
465+
# Handle new default of ContainerRepository and fallback old ContainerPushRepository
466+
repository = Repository.objects.filter(name=path, pulp_domain=domain).first()
467+
if repository:
468+
if repository.pulp_type not in repository_types:
469+
raise RepositoryInvalid(name=path, message="Repository is read-only.")
470+
repository = repository.cast()
471+
else:
472+
repository, _ = models.ContainerRepository.objects.get_or_create(
473+
name=path, pulp_domain=domain
474+
)
475+
distribution, _ = models.ContainerDistribution.objects.get_or_create(
476+
base_path=path,
477+
name=path,
478+
pulp_domain=domain,
479+
defaults={"repository": repository},
462480
)
463481
except ObjectDoesNotExist:
464482
raise RepositoryInvalid(name=path, message="Repository is read-only.")
465483

466484
if distribution.repository:
467-
dist_repository = distribution.repository.cast()
468-
if not dist_repository.PUSH_ENABLED or repository != dist_repository:
469-
raise RepositoryInvalid(name=path, message="Repository is read-only.")
485+
if repository.pk != distribution.repository.pk:
486+
raise RepositoryInvalid(
487+
name=path, message="Repository is not available for push."
488+
)
470489
else:
471490
distribution.repository = repository
472491
distribution.save()

pulp_container/app/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ class Meta:
248248
model = models.ContainerNamespace
249249

250250

251-
class ContainerRepositorySerializer(RepositorySerializer):
251+
class ContainerRepositorySerializer(RepositorySerializer, GetOrCreateSerializerMixin):
252252
"""
253253
Serializer for Container Repositories.
254254
"""

pulp_container/tests/functional/api/test_domains.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def mount_blob(blob, source, dest):
179179

180180
local_repo = f"{domain1.name}/{source_repo}"
181181
local_registry.tag_and_push(image_path, local_repo)
182-
repository = container_bindings.RepositoriesContainerPushApi.list(
182+
repository = container_bindings.RepositoriesContainerApi.list(
183183
name=source_repo, pulp_domain=domain1.name
184184
).results[0]
185185
blobs = container_bindings.ContentBlobsApi.list(

pulp_container/tests/functional/api/test_flatpak.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def test_flatpak_install(
6161
registry_client,
6262
local_registry,
6363
container_namespace_api,
64-
container_push_repository_api,
64+
container_repository_api,
6565
container_tag_api,
6666
container_manifest_api,
6767
pulp_settings,
@@ -84,7 +84,7 @@ def test_flatpak_install(
8484
namespace = container_namespace_api.list(name="pulptest").results[0]
8585
add_to_cleanup(container_namespace_api, namespace.pulp_href)
8686

87-
repo = container_push_repository_api.list(name="pulptest/oci-net.fishsoup.hello").results[0]
87+
repo = container_repository_api.list(name="pulptest/oci-net.fishsoup.hello").results[0]
8888
tag = container_tag_api.list(repository_version=repo.latest_version_href).results[0]
8989
manifest = container_manifest_api.read(tag.tagged_manifest)
9090

pulp_container/tests/functional/api/test_push_content.py

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,20 @@ def test_push_with_dist_perms(
122122
},
123123
)
124124

125-
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
125+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
126126
with user_creator:
127-
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
127+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
128128
with user_dist_collaborator:
129-
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
129+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
130130
with user_dist_consumer:
131-
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
131+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
132132
with user_namespace_collaborator:
133-
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
133+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
134134
with user_reader:
135-
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
135+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
136136
with user_helpless:
137137
# "{repo_name}" turns out to be a public repository
138-
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
138+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
139139

140140

141141
def test_push_with_view_perms(
@@ -407,20 +407,49 @@ def test_push_to_existing_regular_repository(
407407
container_repository_factory,
408408
local_registry,
409409
registry_client,
410+
container_bindings,
410411
full_path,
411412
):
412-
"""
413-
Test the push to an existing non-push repository.
414-
415-
It should fail to create a new push repository.
416-
"""
417-
container_repository_factory(name="foo")
413+
"""Test that push succeeds when a container repository already exists."""
414+
repository = container_repository_factory(name="foo")
418415
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
419416
local_url = full_path("foo:1.0")
420417

421418
registry_client.pull(image_path)
422-
with pytest.raises(CalledProcessError):
423-
local_registry.tag_and_push(image_path, local_url)
419+
local_registry.tag_and_push(image_path, local_url)
420+
421+
repository = container_bindings.RepositoriesContainerApi.read(repository.pulp_href)
422+
tags = container_bindings.ContentTagsApi.list(repository_version=repository.latest_version_href)
423+
assert tags.count == 1
424+
425+
426+
def test_push_to_existing_push_repository(
427+
add_to_cleanup,
428+
container_push_repository_factory,
429+
local_registry,
430+
registry_client,
431+
container_bindings,
432+
full_path,
433+
):
434+
"""Test that push still works when a legacy ContainerPushRepository already exists."""
435+
repo_name = "legacy/push"
436+
container_push_repository_factory(name=repo_name)
437+
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
438+
local_url = full_path(f"{repo_name}:1.0")
439+
440+
registry_client.pull(image_path)
441+
local_registry.tag_and_push(image_path, local_url)
442+
443+
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
444+
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 0
445+
446+
repository = container_bindings.RepositoriesContainerPushApi.list(name=repo_name).results[0]
447+
tags = container_bindings.ContentTagsApi.list(repository_version=repository.latest_version_href)
448+
assert tags.count == 1
449+
450+
distribution = container_bindings.DistributionsContainerApi.list(name=repo_name).results[0]
451+
namespace = container_bindings.PulpContainerNamespacesApi.read(distribution.namespace)
452+
add_to_cleanup(container_bindings.PulpContainerNamespacesApi, namespace.pulp_href)
424453

425454

426455
class TestPushManifestList:
@@ -492,7 +521,7 @@ def test_push_manifest_list_v2s2(
492521
distribution = container_bindings.DistributionsContainerApi.list(name="foo_v2s2").results[0]
493522
add_to_cleanup(container_bindings.DistributionsContainerApi, distribution.pulp_href)
494523

495-
repo_version = container_bindings.RepositoriesContainerPushApi.read(
524+
repo_version = container_bindings.RepositoriesContainerApi.read(
496525
distribution.repository
497526
).latest_version_href
498527

@@ -544,7 +573,7 @@ def test_push_manifest_list_oci(
544573
distribution = container_bindings.DistributionsContainerApi.list(name="foo_oci").results[0]
545574
add_to_cleanup(container_bindings.DistributionsContainerApi, distribution.pulp_href)
546575

547-
repo_version = container_bindings.RepositoriesContainerPushApi.read(
576+
repo_version = container_bindings.RepositoriesContainerApi.read(
548577
distribution.repository
549578
).latest_version_href
550579

@@ -592,7 +621,7 @@ def test_push_empty_manifest_list(
592621
]
593622
add_to_cleanup(container_bindings.DistributionsContainerApi, distribution.pulp_href)
594623

595-
repo_version = container_bindings.RepositoriesContainerPushApi.read(
624+
repo_version = container_bindings.RepositoriesContainerApi.read(
596625
distribution.repository
597626
).latest_version_href
598627
latest_tag = container_bindings.ContentTagsApi.list(

pulp_container/tests/functional/api/test_push_signatures.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def distribution(
4141

4242
def test_assert_signed_image(
4343
local_registry,
44-
container_push_repository_api,
44+
container_repository_api,
4545
container_manifest_api,
4646
container_signature_api,
4747
signing_gpg_metadata,
@@ -51,7 +51,7 @@ def test_assert_signed_image(
5151
"""Test whether an admin user can fetch a signature from the Pulp Registry."""
5252
gpg, fingerprint, keyid = signing_gpg_metadata
5353

54-
repository = container_push_repository_api.read(distribution.repository)
54+
repository = container_repository_api.read(distribution.repository)
5555
manifest = container_manifest_api.list(
5656
repository_version=repository.latest_version_href
5757
).results[0]

pulp_container/tests/functional/api/test_rbac_push_repositories.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
def test_rbac_push_repository(
1111
add_to_cleanup,
12+
container_push_repository_factory,
1213
gen_user,
1314
registry_client,
1415
local_registry,
@@ -17,7 +18,7 @@ def test_rbac_push_repository(
1718
pulp_settings,
1819
monitor_task,
1920
):
20-
"""Verify RBAC for a ContainerPushRepository."""
21+
"""Verify RBAC for a legacy ContainerPushRepository."""
2122
if pulp_settings.TOKEN_AUTH_DISABLED:
2223
pytest.skip("RBAC cannot be tested when token authentication is disabled")
2324

@@ -34,7 +35,7 @@ def test_rbac_push_repository(
3435
user_reader = gen_user(model_roles=["container.containerdistribution_consumer"])
3536
user_helpless = gen_user()
3637

37-
# create a push repo
38+
container_push_repository_factory(name=repo_name)
3839
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_d"
3940
registry_client.pull(image_path)
4041
with user_creator:

pulp_container/tests/functional/api/test_rbac_repo_content.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,27 @@ def test_rbac_repository_content(
4848
user_reader3 = gen_user(model_roles=["container.containerdistribution_consumer"])
4949
user_helpless = gen_user()
5050

51-
# create a first push repo with user_creator
51+
# create a first pushed container repo with user_creator
5252
image_path1 = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
5353
registry_client.pull(image_path1)
5454
repo_name1 = "testcontent1/perms"
5555
local_url1 = full_path(f"{repo_name1}:1.0")
5656
with user_creator:
5757
local_registry.tag_and_push(image_path1, local_url1)
58-
push_repository1 = container_bindings.RepositoriesContainerPushApi.list(
58+
push_repository1 = container_bindings.RepositoriesContainerApi.list(
5959
name=repo_name1
6060
).results[0]
6161
distribution1 = container_bindings.DistributionsContainerApi.list(name=repo_name1).results[0]
6262
add_to_cleanup(container_bindings.PulpContainerNamespacesApi, distribution1.namespace)
6363

64-
# create a second push repo with user_creator2
64+
# create a second pushed container repo with user_creator2
6565
image_path2 = f"{REGISTRY_V2_REPO_PULP}:manifest_b"
6666
registry_client.pull(image_path2)
6767
repo_name2 = "testcontent2/perms"
6868
local_url2 = full_path(f"{repo_name2}:1.0")
6969
with user_creator2:
7070
local_registry.tag_and_push(image_path2, local_url2)
71-
push_repository2 = container_bindings.RepositoriesContainerPushApi.list(
71+
push_repository2 = container_bindings.RepositoriesContainerApi.list(
7272
name=repo_name2
7373
).results[0]
7474
distribution2 = container_bindings.DistributionsContainerApi.list(name=repo_name2).results[0]
@@ -85,10 +85,10 @@ def test_rbac_repository_content(
8585
monitor_task(sync_response.task)
8686

8787
# Test that users can list content if they have enough permissions.
88-
push_repository1_rv = container_bindings.RepositoriesContainerPushApi.read(
88+
push_repository1_rv = container_bindings.RepositoriesContainerApi.read(
8989
push_repository1.pulp_href
9090
).latest_version_href
91-
push_repository2_rv = container_bindings.RepositoriesContainerPushApi.read(
91+
push_repository2_rv = container_bindings.RepositoriesContainerApi.read(
9292
push_repository2.pulp_href
9393
).latest_version_href
9494
repository_rv = container_bindings.RepositoriesContainerApi.read(

pulp_container/tests/functional/api/test_rbac_repo_versions.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,15 @@ def create_new_repo_version():
132132

133133
def test_rbac_push_repository_version(
134134
add_to_cleanup,
135+
container_push_repository_factory,
135136
gen_user,
136137
registry_client,
137138
local_registry,
138139
container_bindings,
139140
full_path,
140141
pulp_settings,
141142
):
142-
"""Verify RBAC for a ContainerPushRepositoryVersion."""
143+
"""Verify RBAC for a legacy ContainerPushRepositoryVersion."""
143144
if pulp_settings.TOKEN_AUTH_DISABLED:
144145
pytest.skip("RBAC cannot be tested when token authentication is disabled")
145146

@@ -160,10 +161,10 @@ def test_rbac_push_repository_version(
160161
user_reader = gen_user(model_roles=["container.containerdistribution_consumer"])
161162
user_helpless = gen_user()
162163

163-
# create a push repo
164164
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_d"
165165
registry_client.pull(image_path)
166166
repo_name = "test_push_repo/perms"
167+
container_push_repository_factory(name=repo_name)
167168
local_url = full_path(f"{repo_name}:1.0")
168169
with user_creator:
169170
local_registry.tag_and_push(image_path, local_url)
@@ -231,7 +232,7 @@ def test_cross_repository_blob_mount(
231232
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
232233
registry_client.pull(image_path)
233234
local_registry.tag_and_push(image_path, local_url)
234-
repository = container_bindings.RepositoriesContainerPushApi.list(name=source_repo).results[0]
235+
repository = container_bindings.RepositoriesContainerApi.list(name=source_repo).results[0]
235236
blobs = container_bindings.ContentBlobsApi.list(
236237
repository_version=repository.latest_version_href
237238
).results

0 commit comments

Comments
 (0)