Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/+default-push-repo.feature
Original file line number Diff line number Diff line change
@@ -0,0 +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.
31 changes: 21 additions & 10 deletions pulp_container/app/registry_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
from pulpcore.plugin import pulp_hashlib
from pulpcore.plugin.exceptions import TimeoutException
from pulpcore.plugin.files import PulpTemporaryUploadedFile
from pulpcore.plugin.models import Artifact, ContentArtifact, UploadChunk
from pulpcore.plugin.models import Artifact, ContentArtifact, Repository, UploadChunk
from pulpcore.plugin.tasking import dispatch
from pulpcore.plugin.util import get_domain, get_objects_for_user, get_url

Expand Down Expand Up @@ -393,11 +393,9 @@ def get_dr_push(self, request, path, create=False):
repository = distribution.repository
if repository:
repository = repository.cast()
if not repository.PUSH_ENABLED:
raise RepositoryInvalid(name=path, message="Repository is read-only.")
elif create:
with transaction.atomic():
repository = serializers.ContainerPushRepositorySerializer.get_or_create(
repository = serializers.ContainerRepositorySerializer.get_or_create(
{"name": path, "pulp_domain": domain}
)
distribution.repository = repository
Expand All @@ -408,11 +406,23 @@ def get_dr_push(self, request, path, create=False):

def create_dr(self, path, request):
domain = get_domain()
repository_types = [
models.ContainerRepository.get_pulp_type(),
models.ContainerPushRepository.get_pulp_type(),
]
with transaction.atomic():
try:
repository = serializers.ContainerPushRepositorySerializer.get_or_create(
{"name": path, "pulp_domain": domain}
)
# Handle new default of ContainerRepository and fallback old ContainerPushRepository
repository = Repository.objects.filter(name=path, pulp_domain=domain).first()
if repository:
if repository.pulp_type not in repository_types:
raise RepositoryInvalid(name=path, message="Repository is read-only.")
repository = repository.cast()
else:
repository, _ = models.ContainerRepository.objects.get_or_create(
name=path, pulp_domain=domain
)

distribution = serializers.ContainerDistributionSerializer.get_or_create(
{"base_path": path, "name": path, "pulp_domain": domain},
{"repository": get_url(repository)},
Expand All @@ -421,9 +431,10 @@ def create_dr(self, path, request):
raise RepositoryInvalid(name=path, message="Repository is read-only.")

if distribution.repository:
dist_repository = distribution.repository.cast()
if not dist_repository.PUSH_ENABLED or repository != dist_repository:
raise RepositoryInvalid(name=path, message="Repository is read-only.")
if repository.pk != distribution.repository.pk:
raise RepositoryInvalid(
name=path, message="Repository is not available for push."
)
else:
distribution.repository = repository
distribution.save()
Expand Down
2 changes: 1 addition & 1 deletion pulp_container/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class Meta:
model = models.ContainerNamespace


class ContainerRepositorySerializer(RepositorySerializer):
class ContainerRepositorySerializer(RepositorySerializer, GetOrCreateSerializerMixin):
"""
Serializer for Container Repositories.
"""
Expand Down
2 changes: 1 addition & 1 deletion pulp_container/tests/functional/api/test_domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def mount_blob(blob, source, dest):

local_repo = f"{domain1.name}/{source_repo}"
local_registry.tag_and_push(image_path, local_repo)
repository = container_bindings.RepositoriesContainerPushApi.list(
repository = container_bindings.RepositoriesContainerApi.list(
name=source_repo, pulp_domain=domain1.name
).results[0]
blobs = container_bindings.ContentBlobsApi.list(
Expand Down
4 changes: 2 additions & 2 deletions pulp_container/tests/functional/api/test_flatpak.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def test_flatpak_install(
registry_client,
local_registry,
container_namespace_api,
container_push_repository_api,
container_repository_api,
container_tag_api,
container_manifest_api,
pulp_settings,
Expand All @@ -84,7 +84,7 @@ def test_flatpak_install(
namespace = container_namespace_api.list(name="pulptest").results[0]
add_to_cleanup(container_namespace_api, namespace.pulp_href)

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

Expand Down
65 changes: 47 additions & 18 deletions pulp_container/tests/functional/api/test_push_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,20 +122,20 @@ def test_push_with_dist_perms(
},
)

assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
with user_creator:
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
with user_dist_collaborator:
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
with user_dist_consumer:
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
with user_namespace_collaborator:
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
with user_reader:
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1
with user_helpless:
# "{repo_name}" turns out to be a public repository
assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 1


def test_push_with_view_perms(
Expand Down Expand Up @@ -407,20 +407,49 @@ def test_push_to_existing_regular_repository(
container_repository_factory,
local_registry,
registry_client,
container_bindings,
full_path,
):
"""
Test the push to an existing non-push repository.

It should fail to create a new push repository.
"""
container_repository_factory(name="foo")
"""Test that push succeeds when a container repository already exists."""
repository = container_repository_factory(name="foo")
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
local_url = full_path("foo:1.0")

registry_client.pull(image_path)
with pytest.raises(CalledProcessError):
local_registry.tag_and_push(image_path, local_url)
local_registry.tag_and_push(image_path, local_url)

repository = container_bindings.RepositoriesContainerApi.read(repository.pulp_href)
tags = container_bindings.ContentTagsApi.list(repository_version=repository.latest_version_href)
assert tags.count == 1


def test_push_to_existing_push_repository(
add_to_cleanup,
container_push_repository_factory,
local_registry,
registry_client,
container_bindings,
full_path,
):
"""Test that push still works when a legacy ContainerPushRepository already exists."""
repo_name = "legacy/push"
container_push_repository_factory(name=repo_name)
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
local_url = full_path(f"{repo_name}:1.0")

registry_client.pull(image_path)
local_registry.tag_and_push(image_path, local_url)

assert container_bindings.RepositoriesContainerPushApi.list(name=repo_name).count == 1
assert container_bindings.RepositoriesContainerApi.list(name=repo_name).count == 0

repository = container_bindings.RepositoriesContainerPushApi.list(name=repo_name).results[0]
tags = container_bindings.ContentTagsApi.list(repository_version=repository.latest_version_href)
assert tags.count == 1

distribution = container_bindings.DistributionsContainerApi.list(name=repo_name).results[0]
namespace = container_bindings.PulpContainerNamespacesApi.read(distribution.namespace)
add_to_cleanup(container_bindings.PulpContainerNamespacesApi, namespace.pulp_href)


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

repo_version = container_bindings.RepositoriesContainerPushApi.read(
repo_version = container_bindings.RepositoriesContainerApi.read(
distribution.repository
).latest_version_href

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

repo_version = container_bindings.RepositoriesContainerPushApi.read(
repo_version = container_bindings.RepositoriesContainerApi.read(
distribution.repository
).latest_version_href

Expand Down Expand Up @@ -592,7 +621,7 @@ def test_push_empty_manifest_list(
]
add_to_cleanup(container_bindings.DistributionsContainerApi, distribution.pulp_href)

repo_version = container_bindings.RepositoriesContainerPushApi.read(
repo_version = container_bindings.RepositoriesContainerApi.read(
distribution.repository
).latest_version_href
latest_tag = container_bindings.ContentTagsApi.list(
Expand Down
4 changes: 2 additions & 2 deletions pulp_container/tests/functional/api/test_push_signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def distribution(

def test_assert_signed_image(
local_registry,
container_push_repository_api,
container_repository_api,
container_manifest_api,
container_signature_api,
signing_gpg_metadata,
Expand All @@ -51,7 +51,7 @@ def test_assert_signed_image(
"""Test whether an admin user can fetch a signature from the Pulp Registry."""
gpg, fingerprint, keyid = signing_gpg_metadata

repository = container_push_repository_api.read(distribution.repository)
repository = container_repository_api.read(distribution.repository)
manifest = container_manifest_api.list(
repository_version=repository.latest_version_href
).results[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

def test_rbac_push_repository(
add_to_cleanup,
container_push_repository_factory,
gen_user,
registry_client,
local_registry,
Expand All @@ -17,7 +18,7 @@ def test_rbac_push_repository(
pulp_settings,
monitor_task,
):
"""Verify RBAC for a ContainerPushRepository."""
"""Verify RBAC for a legacy ContainerPushRepository."""
if pulp_settings.TOKEN_AUTH_DISABLED:
pytest.skip("RBAC cannot be tested when token authentication is disabled")

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

# create a push repo
container_push_repository_factory(name=repo_name)
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_d"
registry_client.pull(image_path)
with user_creator:
Expand Down
12 changes: 6 additions & 6 deletions pulp_container/tests/functional/api/test_rbac_repo_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,27 @@ def test_rbac_repository_content(
user_reader3 = gen_user(model_roles=["container.containerdistribution_consumer"])
user_helpless = gen_user()

# create a first push repo with user_creator
# create a first pushed container repo with user_creator
image_path1 = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
registry_client.pull(image_path1)
repo_name1 = "testcontent1/perms"
local_url1 = full_path(f"{repo_name1}:1.0")
with user_creator:
local_registry.tag_and_push(image_path1, local_url1)
push_repository1 = container_bindings.RepositoriesContainerPushApi.list(
push_repository1 = container_bindings.RepositoriesContainerApi.list(
name=repo_name1
).results[0]
distribution1 = container_bindings.DistributionsContainerApi.list(name=repo_name1).results[0]
add_to_cleanup(container_bindings.PulpContainerNamespacesApi, distribution1.namespace)

# create a second push repo with user_creator2
# create a second pushed container repo with user_creator2
image_path2 = f"{REGISTRY_V2_REPO_PULP}:manifest_b"
registry_client.pull(image_path2)
repo_name2 = "testcontent2/perms"
local_url2 = full_path(f"{repo_name2}:1.0")
with user_creator2:
local_registry.tag_and_push(image_path2, local_url2)
push_repository2 = container_bindings.RepositoriesContainerPushApi.list(
push_repository2 = container_bindings.RepositoriesContainerApi.list(
name=repo_name2
).results[0]
distribution2 = container_bindings.DistributionsContainerApi.list(name=repo_name2).results[0]
Expand All @@ -85,10 +85,10 @@ def test_rbac_repository_content(
monitor_task(sync_response.task)

# Test that users can list content if they have enough permissions.
push_repository1_rv = container_bindings.RepositoriesContainerPushApi.read(
push_repository1_rv = container_bindings.RepositoriesContainerApi.read(
push_repository1.pulp_href
).latest_version_href
push_repository2_rv = container_bindings.RepositoriesContainerPushApi.read(
push_repository2_rv = container_bindings.RepositoriesContainerApi.read(
push_repository2.pulp_href
).latest_version_href
repository_rv = container_bindings.RepositoriesContainerApi.read(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,15 @@ def create_new_repo_version():

def test_rbac_push_repository_version(
add_to_cleanup,
container_push_repository_factory,
gen_user,
registry_client,
local_registry,
container_bindings,
full_path,
pulp_settings,
):
"""Verify RBAC for a ContainerPushRepositoryVersion."""
"""Verify RBAC for a legacy ContainerPushRepositoryVersion."""
if pulp_settings.TOKEN_AUTH_DISABLED:
pytest.skip("RBAC cannot be tested when token authentication is disabled")

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

# create a push repo
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_d"
registry_client.pull(image_path)
repo_name = "test_push_repo/perms"
container_push_repository_factory(name=repo_name)
local_url = full_path(f"{repo_name}:1.0")
with user_creator:
local_registry.tag_and_push(image_path, local_url)
Expand Down Expand Up @@ -231,7 +232,7 @@ def test_cross_repository_blob_mount(
image_path = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
registry_client.pull(image_path)
local_registry.tag_and_push(image_path, local_url)
repository = container_bindings.RepositoriesContainerPushApi.list(name=source_repo).results[0]
repository = container_bindings.RepositoriesContainerApi.list(name=source_repo).results[0]
blobs = container_bindings.ContentBlobsApi.list(
repository_version=repository.latest_version_href
).results
Expand Down
11 changes: 9 additions & 2 deletions pulp_container/tests/functional/api/test_recursive_remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,10 +429,17 @@ def test_cannot_remove_tagged_manifest(


def test_remove_image_push_repo(
container_bindings, local_registry, registry_client, full_path, add_to_cleanup, monitor_task
container_push_repository_factory,
container_bindings,
local_registry,
registry_client,
full_path,
add_to_cleanup,
monitor_task,
):
"""Test the image removal within a push repository."""
"""Test the image removal within a legacy push repository."""
# the image tagged as 'manifest_a' consists of 3 blobs, 1 manifest, and 1 tag
container_push_repository_factory(name="foo/bar")
manifest_a_path = f"{REGISTRY_V2_REPO_PULP}:manifest_a"
registry_client.pull(manifest_a_path)
local_registry.tag_and_push(manifest_a_path, full_path("foo/bar:tag"))
Expand Down
6 changes: 3 additions & 3 deletions pulp_container/tests/functional/api/test_sign_manifests.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
def distribution(
registry_client, local_registry, container_distribution_api, full_path, add_to_cleanup
):
"""The fixture for a distribution that references a repository of the push type."""
"""The fixture for a distribution created by pushing an image to the registry."""
image_path = f"{REGISTRY_V2_REPO_PULP}:{MANIFEST_TAG}"
registry_client.pull(image_path)
local_registry.tag_and_push(image_path, full_path(f"test-1:{MANIFEST_TAG}"))
Expand All @@ -25,7 +25,7 @@ def test_sign_manifest(
signing_gpg_metadata,
distribution,
container_signing_service,
container_push_repository_api,
container_repository_api,
container_signature_api,
container_tag_api,
container_manifest_api,
Expand All @@ -35,7 +35,7 @@ def test_sign_manifest(
_, _, keyid = signing_gpg_metadata
sign_data = {"manifest_signing_service": container_signing_service.pulp_href}

response = container_push_repository_api.sign(distribution.repository, sign_data)
response = container_repository_api.sign(distribution.repository, sign_data)
created_resources = monitor_task(response.task).created_resources

tags = container_tag_api.list(repository_version=created_resources[0])
Expand Down
Loading
Loading