diff --git a/CHANGES/1648.feature b/CHANGES/1648.feature new file mode 100644 index 000000000..82c36acb2 --- /dev/null +++ b/CHANGES/1648.feature @@ -0,0 +1,3 @@ +Added support for the Replication feature. The replication process allows a Pulp instance to +replicate container repositories from an upstream Pulp, creating the required remotes, +repositories (those will always be read-only), and distributions. diff --git a/pulp_container/app/replica.py b/pulp_container/app/replica.py new file mode 100644 index 000000000..85fab2254 --- /dev/null +++ b/pulp_container/app/replica.py @@ -0,0 +1,53 @@ +from pulpcore.plugin.replica import Replicator +from pulpcore.plugin.util import get_url + +from pulp_glue.container.context import ( + PulpContainerDistributionContext, + PulpContainerRepositoryContext, +) + +from pulp_container.app.models import ContainerDistribution, ContainerRemote, ContainerRepository +from pulp_container.app.tasks import synchronize as container_synchronize + + +class ContainerReplicator(Replicator): + distribution_ctx_cls = PulpContainerDistributionContext + repository_ctx_cls = PulpContainerRepositoryContext + remote_model_cls = ContainerRemote + repository_model_cls = ContainerRepository + distribution_model_cls = ContainerDistribution + distribution_serializer_name = "ContainerDistributionSerializer" + repository_serializer_name = "ContainerRepositorySerializer" + remote_serializer_name = "ContainerRemoteSerializer" + app_label = "container" + sync_task = container_synchronize + + def sync_params(self, repository, remote): + """Returns a dictionary where key is a parameter for the sync task.""" + return dict( + remote_pk=str(remote.pk), + repository_pk=str(repository.pk), + signed_only=False, + mirror=True, + ) + + def url(self, upstream_distribution): + return self.pulp_ctx._api_kwargs["base_url"] + + def remote_extra_fields(self, upstream_distribution): + upstream_name = upstream_distribution["registry_path"].split("/", 1)[1] + return {"upstream_name": upstream_name} + + def distribution_data(self, repository, upstream_distribution): + """ + Return the fields that need to be updated/cleared on distributions for idempotence. + """ + return { + "repository": get_url(repository), + "base_path": upstream_distribution["base_path"], + "private": upstream_distribution["private"], + "description": upstream_distribution["description"], + } + + +REPLICATION_ORDER = [ContainerReplicator] diff --git a/requirements.txt b/requirements.txt index 193823f9c..f3e149f1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ jsonschema>=4.4,<4.23 -pulpcore>=3.46.0,<3.55 +pulpcore>=3.49.0,<3.55 pyjwt[crypto]>=2.4,<2.9 diff --git a/staging_docs/user/tutorials/00-overview.md b/staging_docs/user/tutorials/00-overview.md index a9c148f68..5e2c0a842 100644 --- a/staging_docs/user/tutorials/00-overview.md +++ b/staging_docs/user/tutorials/00-overview.md @@ -31,3 +31,4 @@ If you'd like to watch a recent talk about Pulp Container and see it in action, - Sign images and host Cosign signatures, SBOMS and attestations - Sign images and host Atomic signature type via extensions API - Host content via pull-through caching distributions +- Discover and replicate distributions to serve the same content as the upstream Pulp