RFC: Container Registry Push

Hello community!

We’ve made some designs for adding push functionality to our container registry and I would like to share it with you all.

For some background, currently, in Katello, you can sync “container repositories” and interact with them using podman/docker. While we allow you to upload manifests and retag them with Katello, we have no support for podman push. With podman push you can create your own container manifests, tag them, and deliver them to the container registry.

Pulp 3 implements podman push support using something called “push repositories”. Rather than push container content to an existing repository, a user pushes to the Pulp container registry and a new repository is created under-the-hood in Pulp. If a user pushes to an existing repository, then the old push repository is used and a new repository version is generated. There are a couple caveats though:

  1. Content is pushed to a push repository type. A push repository does not support mirroring of the remote content via the Pulp API.
  2. Rollback to the previous repository versions is not possible with a push repository. Its latest version will always be served.

So, content in these push repositories require special handling.

Here’s the design in short:

  1. A user initiates the sequence by pushing content to Katello’s registry.
  2. Katello ensures the user is allowed to push content and then redirects the request to Pulp.
  3. Once Pulp has created the push repository, Katello finds it and copies the contents to a normal container repository.
  4. Katello creates a product and a repository as necessary and associates the new Pulp repository to it.
  5. Katello distributes the new Pulp repository and follows the custom container repository naming scheme if there is one set.
  6. The user interacts with the new repository just like any other container repository in Katello.

Now here are some details:

How will Katello know if a user is allowed to push content?

A user can have varying kinds of access to creating repositories in Katello. At the most basic level, Katello will need to know what Organization a user is pushing to. So, we’re proposing to use a sort of namespacing system:

  • If a user wants to push to an Organization’s auto-created container push Product (this is part of the new design), they’ll do something like:
podman push <image ID> docker://foreman.example.com/My_Org/busybox:latest
  • If a user wants to push to a specific product:
podman push <image ID> docker://foreman.example.com/My_Org/My_Product/busybox:latest 

The user details should come along in the headers, so we shouldn’t have to have users push with their username in the command itself.

How will pushes to the same repository work?

Assuming that the Pulp registry returns no information about the container push repository that is created at push time, Katello will find and use the existing container push repository. We’ll just need to run another copy command to bring over the new contents, reindex the repository, and redistribute it.

How will Katello handle the old container push repositories?

When a repository is deleted, the related container push repository will be deleted as well.

How will authentication work?

Just like with podman pull, a user will first podman login and go from there.

Will there be smart proxy support?

Only via smart proxy syncing. We’re only targeting podman push for the main Foreman+Katello instance. A smart proxy mirrors what’s in Katello, so users can perform a smart proxy sync to get their push repositories onto their smart proxies.

If anyone is curious, I have a PoC branch that allows for pushing content to Pulp through Katello’s registry proxy. I’m still figuring out Pulp’s tokenless authentication for pushing, so in the meantime, you need to comment out some of Pulp’s auth code to test.

There are certainly some details that I’ve left out, so please ask questions if you have any. Now is the time to get concerns sorted!



Hello Ian, thank you for the detailed info! One question pops in my mind:

A smart proxy mirrors what’s in Katello, so users can perform a smart proxy sync to get their push repositories onto their smart proxies.

Based on the Foreman settings, will the smart proxy be autosynced after a docker push repo is created? Or will that be handled using the copy (not push) docker repository, just the same way like any other repo? Actually, do we need both, push and copy, repos get synced on the smart proxy, isn’t the the copy repo enough?

Thank you for clarification.


If a user has set the “Sync Smart Proxies after content view promotion” setting, the push contents should get synced to a smart proxy after pushing to Katello. You bring up a good point there, we’ll need to add that step to our container push orchestration.

The push creates a “container push” repository in Pulp. Then, since that repository type has limitations, we have to copy to another repository so we can use it like a normal Katello container repo. After that, the pushed contents will be in Library / Default Organization View. Once that is done, then we’re ready to optionally sync the content to a remote smart proxy if the user has any.

In short, the “push and copy” part is the minimum we need to use pushed container content on the Katello instance itself.

1 Like

Can a push flow through the reverse proxy that lives on the foreman-proxy?

Question on what the user sees when it comes to the push repository and the container repository. Is the push repository transparent to the user? Do they ever know they are interacting with it?

I’m not sure, but I imagine that any registry related commands would end up getting routed to the smart proxy container gateway. Perhaps it could be set up to flow to the main Foreman server rather than to the smart proxy.

The user won’t know that the container push repository exists. It would be something happening outside of their view in the background. They’ll see it if they like poking around with the Pulp CLI, however.