#10 Support publishing container images to registries (#4)
Merged by jcline. Opened by adamwill.
adamwill/cloud-image-uploader handle-containers  into  main

This adds support for publishing container images to registries.
It is intended to replace the sync-latest-container-base-image.sh
and sync-ostree-base-containers.sh scripts we currently use for
this purpose.

It finds "docker" or "ociarchive" type images in the compose and
matches them against a list of known "repos" (fedora-toolbox,
fedora-silverblue etc.) Images that match are pushed to the
registry using skopeo copy. Then a manifest is produced from
the published images, and published itself; if the compose is a
Rawhide compose, or a compose of the current stable release, a
manifest is also published under an alias ("rawhide" or "latest",
respectively).

This initial implementation is intentionally closely based on the
sync-latest-container-base-image.sh approach. The other script
uses a somewhat different approach where the release numbered
manifest is created from the local image files and then pushed
with --all, which also causes the image files to be pushed,
then the manifest is copied to the 'aliased' name. I think the
eventual outcome is really the same in both cases, though.

The container support can be activated by configuring at least
one registry in the consumer config. If this is not done,
container images will not be handled.

Signed-off-by: Adam Williamson awilliam@redhat.com

rebased onto 5adae5278acbf49cc7d4dc1bf67156f62781d241

For the record, here is the complete list of commands it would run for each compose. The reason why the atomic desktops are missed for the Rawhide compose is a bit interesting. That compose has aged out from the mirrors now, so fedfind - when asked for the images from that compose - falls back on getting the info from PDC (you can see this happening if you look at the pyvcr "cassette" for the test).

However, PDC doesn't actually contain the full data because of this bug - PDC doesn't just dump in the JSON file's contents unmodified, it wants to check or parse it somehow (I don't know why), and it doesn't know about ociarchive images, so it leaves them out. We are trying to get rid of PDC, so that bug won't likely ever get fixed (if PDC ever does go away, fedfind just won't be able to give you information on the images that were in a compose which is no longer present on the mirrors).

If I'd recorded the cassette while the compose was still on the mirrors, fedfind would've got the unmodified metadata from the compose tree and the ociarchive images would be there, but I didn't.

Rawhide commands:

skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.aarch64-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.aarch64-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.aarch64-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.aarch64-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora:41-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.aarch64-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.aarch64-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.x86_64-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.x86_64-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.x86_64-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.x86_64-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora:41-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.x86_64-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.x86_64-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.s390x-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.s390x-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.s390x-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.s390x-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora:41-s390x
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.s390x-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-s390x
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.s390x-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.ppc64le-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.ppc64le-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.ppc64le-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.ppc64le-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora:41-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.ppc64le-Rawhide-20240501.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.ppc64le-Rawhide-20240501.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-ppc64le
buildah rmi registry.fedoraproject.org/fedora-minimal:41
buildah manifest create registry.fedoraproject.org/fedora-minimal:41 registry.fedoraproject.org/fedora-minimal:41-aarch64 registry.fedoraproject.org/fedora-minimal:41-x86_64 registry.fedoraproject.org/fedora-minimal:41-s390x registry.fedoraproject.org/fedora-minimal:41-ppc64le
buildah manifest push registry.fedoraproject.org/fedora-minimal:41 docker://registry.fedoraproject.org/fedora-minimal:41 --all
buildah rmi registry.fedoraproject.org/fedora-minimal:rawhide
buildah manifest create registry.fedoraproject.org/fedora-minimal:rawhide registry.fedoraproject.org/fedora-minimal:41-aarch64 registry.fedoraproject.org/fedora-minimal:41-x86_64 registry.fedoraproject.org/fedora-minimal:41-s390x registry.fedoraproject.org/fedora-minimal:41-ppc64le
buildah manifest push registry.fedoraproject.org/fedora-minimal:rawhide docker://registry.fedoraproject.org/fedora-minimal:rawhide --all
buildah rmi quay.io/fedora/fedora-minimal:41
buildah manifest create quay.io/fedora/fedora-minimal:41 quay.io/fedora/fedora-minimal:41-aarch64 quay.io/fedora/fedora-minimal:41-x86_64 quay.io/fedora/fedora-minimal:41-s390x quay.io/fedora/fedora-minimal:41-ppc64le
buildah manifest push quay.io/fedora/fedora-minimal:41 docker://quay.io/fedora/fedora-minimal:41 --all
buildah rmi quay.io/fedora/fedora-minimal:rawhide
buildah manifest create quay.io/fedora/fedora-minimal:rawhide quay.io/fedora/fedora-minimal:41-aarch64 quay.io/fedora/fedora-minimal:41-x86_64 quay.io/fedora/fedora-minimal:41-s390x quay.io/fedora/fedora-minimal:41-ppc64le
buildah manifest push quay.io/fedora/fedora-minimal:rawhide docker://quay.io/fedora/fedora-minimal:rawhide --all
buildah rmi registry.fedoraproject.org/fedora:41
buildah manifest create registry.fedoraproject.org/fedora:41 registry.fedoraproject.org/fedora:41-aarch64 registry.fedoraproject.org/fedora:41-x86_64 registry.fedoraproject.org/fedora:41-s390x registry.fedoraproject.org/fedora:41-ppc64le
buildah manifest push registry.fedoraproject.org/fedora:41 docker://registry.fedoraproject.org/fedora:41 --all
buildah rmi registry.fedoraproject.org/fedora:rawhide
buildah manifest create registry.fedoraproject.org/fedora:rawhide registry.fedoraproject.org/fedora:41-aarch64 registry.fedoraproject.org/fedora:41-x86_64 registry.fedoraproject.org/fedora:41-s390x registry.fedoraproject.org/fedora:41-ppc64le
buildah manifest push registry.fedoraproject.org/fedora:rawhide docker://registry.fedoraproject.org/fedora:rawhide --all
buildah rmi quay.io/fedora/fedora:41
buildah manifest create quay.io/fedora/fedora:41 quay.io/fedora/fedora:41-aarch64 quay.io/fedora/fedora:41-x86_64 quay.io/fedora/fedora:41-s390x quay.io/fedora/fedora:41-ppc64le
buildah manifest push quay.io/fedora/fedora:41 docker://quay.io/fedora/fedora:41 --all
buildah rmi quay.io/fedora/fedora:rawhide
buildah manifest create quay.io/fedora/fedora:rawhide quay.io/fedora/fedora:41-aarch64 quay.io/fedora/fedora:41-x86_64 quay.io/fedora/fedora:41-s390x quay.io/fedora/fedora:41-ppc64le
buildah manifest push quay.io/fedora/fedora:rawhide docker://quay.io/fedora/fedora:rawhide --all
buildah rmi registry.fedoraproject.org/fedora-toolbox:41
buildah manifest create registry.fedoraproject.org/fedora-toolbox:41 registry.fedoraproject.org/fedora-toolbox:41-aarch64 registry.fedoraproject.org/fedora-toolbox:41-x86_64 registry.fedoraproject.org/fedora-toolbox:41-s390x registry.fedoraproject.org/fedora-toolbox:41-ppc64le
buildah manifest push registry.fedoraproject.org/fedora-toolbox:41 docker://registry.fedoraproject.org/fedora-toolbox:41 --all
buildah rmi registry.fedoraproject.org/fedora-toolbox:rawhide
buildah manifest create registry.fedoraproject.org/fedora-toolbox:rawhide registry.fedoraproject.org/fedora-toolbox:41-aarch64 registry.fedoraproject.org/fedora-toolbox:41-x86_64 registry.fedoraproject.org/fedora-toolbox:41-s390x registry.fedoraproject.org/fedora-toolbox:41-ppc64le
buildah manifest push registry.fedoraproject.org/fedora-toolbox:rawhide docker://registry.fedoraproject.org/fedora-toolbox:rawhide --all
buildah rmi quay.io/fedora/fedora-toolbox:41
buildah manifest create quay.io/fedora/fedora-toolbox:41 quay.io/fedora/fedora-toolbox:41-aarch64 quay.io/fedora/fedora-toolbox:41-x86_64 quay.io/fedora/fedora-toolbox:41-s390x quay.io/fedora/fedora-toolbox:41-ppc64le
buildah manifest push quay.io/fedora/fedora-toolbox:41 docker://quay.io/fedora/fedora-toolbox:41 --all
buildah rmi quay.io/fedora/fedora-toolbox:rawhide
buildah manifest create quay.io/fedora/fedora-toolbox:rawhide quay.io/fedora/fedora-toolbox:41-aarch64 quay.io/fedora/fedora-toolbox:41-x86_64 quay.io/fedora/fedora-toolbox:41-s390x quay.io/fedora/fedora-toolbox:41-ppc64le
buildah manifest push quay.io/fedora/fedora-toolbox:rawhide docker://quay.io/fedora/fedora-toolbox:rawhide --all

F40 candidate compose commands:

skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.aarch64-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-minimal:40-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.aarch64-40-1.14.oci.tar docker://quay.io/fedora/fedora-minimal:40-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.aarch64-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora:40-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.aarch64-40-1.14.oci.tar docker://quay.io/fedora/fedora:40-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.aarch64-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:40-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.aarch64-40-1.14.oci.tar docker://quay.io/fedora/fedora-toolbox:40-aarch64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.ppc64le-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-minimal:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.ppc64le-40-1.14.oci.tar docker://quay.io/fedora/fedora-minimal:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.ppc64le-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.ppc64le-40-1.14.oci.tar docker://quay.io/fedora/fedora:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.ppc64le-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.ppc64le-40-1.14.oci.tar docker://quay.io/fedora/fedora-toolbox:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.s390x-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-minimal:40-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.s390x-40-1.14.oci.tar docker://quay.io/fedora/fedora-minimal:40-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.s390x-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora:40-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.s390x-40-1.14.oci.tar docker://quay.io/fedora/fedora:40-s390x
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.s390x-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:40-s390x
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.s390x-40-1.14.oci.tar docker://quay.io/fedora/fedora-toolbox:40-s390x
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.x86_64-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-minimal:40-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic-Minimal.x86_64-40-1.14.oci.tar docker://quay.io/fedora/fedora-minimal:40-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.x86_64-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora:40-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Base-Generic.x86_64-40-1.14.oci.tar docker://quay.io/fedora/fedora:40-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.x86_64-40-1.14.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:40-x86_64
skopeo copy oci-archive:/test/Fedora-Container-Toolbox.x86_64-40-1.14.oci.tar docker://quay.io/fedora/fedora-toolbox:40-x86_64
skopeo copy oci-archive:/test/Fedora-Kinoite-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-kinoite:40-aarch64
skopeo copy oci-archive:/test/Fedora-Kinoite-40.1.14.ociarchive docker://quay.io/fedora/fedora-kinoite:40-aarch64
skopeo copy oci-archive:/test/Fedora-Kinoite-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-kinoite:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Kinoite-40.1.14.ociarchive docker://quay.io/fedora/fedora-kinoite:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Kinoite-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-kinoite:40-x86_64
skopeo copy oci-archive:/test/Fedora-Kinoite-40.1.14.ociarchive docker://quay.io/fedora/fedora-kinoite:40-x86_64
skopeo copy oci-archive:/test/Fedora-Onyx-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-onyx:40-x86_64
skopeo copy oci-archive:/test/Fedora-Onyx-40.1.14.ociarchive docker://quay.io/fedora/fedora-onyx:40-x86_64
skopeo copy oci-archive:/test/Fedora-Sericea-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-sericea:40-aarch64
skopeo copy oci-archive:/test/Fedora-Sericea-40.1.14.ociarchive docker://quay.io/fedora/fedora-sericea:40-aarch64
skopeo copy oci-archive:/test/Fedora-Sericea-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-sericea:40-x86_64
skopeo copy oci-archive:/test/Fedora-Sericea-40.1.14.ociarchive docker://quay.io/fedora/fedora-sericea:40-x86_64
skopeo copy oci-archive:/test/Fedora-Silverblue-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-silverblue:40-aarch64
skopeo copy oci-archive:/test/Fedora-Silverblue-40.1.14.ociarchive docker://quay.io/fedora/fedora-silverblue:40-aarch64
skopeo copy oci-archive:/test/Fedora-Silverblue-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-silverblue:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Silverblue-40.1.14.ociarchive docker://quay.io/fedora/fedora-silverblue:40-ppc64le
skopeo copy oci-archive:/test/Fedora-Silverblue-40.1.14.ociarchive docker://registry.fedoraproject.org/fedora-silverblue:40-x86_64
skopeo copy oci-archive:/test/Fedora-Silverblue-40.1.14.ociarchive docker://quay.io/fedora/fedora-silverblue:40-x86_64
buildah rmi registry.fedoraproject.org/fedora-minimal:40
buildah manifest create registry.fedoraproject.org/fedora-minimal:40 registry.fedoraproject.org/fedora-minimal:40-aarch64 registry.fedoraproject.org/fedora-minimal:40-ppc64le registry.fedoraproject.org/fedora-minimal:40-s390x registry.fedoraproject.org/fedora-minimal:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-minimal:40 docker://registry.fedoraproject.org/fedora-minimal:40 --all
buildah rmi registry.fedoraproject.org/fedora-minimal:latest
buildah manifest create registry.fedoraproject.org/fedora-minimal:latest registry.fedoraproject.org/fedora-minimal:40-aarch64 registry.fedoraproject.org/fedora-minimal:40-ppc64le registry.fedoraproject.org/fedora-minimal:40-s390x registry.fedoraproject.org/fedora-minimal:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-minimal:latest docker://registry.fedoraproject.org/fedora-minimal:latest --all
buildah rmi quay.io/fedora/fedora-minimal:40
buildah manifest create quay.io/fedora/fedora-minimal:40 quay.io/fedora/fedora-minimal:40-aarch64 quay.io/fedora/fedora-minimal:40-ppc64le quay.io/fedora/fedora-minimal:40-s390x quay.io/fedora/fedora-minimal:40-x86_64
buildah manifest push quay.io/fedora/fedora-minimal:40 docker://quay.io/fedora/fedora-minimal:40 --all
buildah rmi quay.io/fedora/fedora-minimal:latest
buildah manifest create quay.io/fedora/fedora-minimal:latest quay.io/fedora/fedora-minimal:40-aarch64 quay.io/fedora/fedora-minimal:40-ppc64le quay.io/fedora/fedora-minimal:40-s390x quay.io/fedora/fedora-minimal:40-x86_64
buildah manifest push quay.io/fedora/fedora-minimal:latest docker://quay.io/fedora/fedora-minimal:latest --all
buildah rmi registry.fedoraproject.org/fedora:40
buildah manifest create registry.fedoraproject.org/fedora:40 registry.fedoraproject.org/fedora:40-aarch64 registry.fedoraproject.org/fedora:40-ppc64le registry.fedoraproject.org/fedora:40-s390x registry.fedoraproject.org/fedora:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora:40 docker://registry.fedoraproject.org/fedora:40 --all
buildah rmi registry.fedoraproject.org/fedora:latest
buildah manifest create registry.fedoraproject.org/fedora:latest registry.fedoraproject.org/fedora:40-aarch64 registry.fedoraproject.org/fedora:40-ppc64le registry.fedoraproject.org/fedora:40-s390x registry.fedoraproject.org/fedora:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora:latest docker://registry.fedoraproject.org/fedora:latest --all
buildah rmi quay.io/fedora/fedora:40
buildah manifest create quay.io/fedora/fedora:40 quay.io/fedora/fedora:40-aarch64 quay.io/fedora/fedora:40-ppc64le quay.io/fedora/fedora:40-s390x quay.io/fedora/fedora:40-x86_64
buildah manifest push quay.io/fedora/fedora:40 docker://quay.io/fedora/fedora:40 --all
buildah rmi quay.io/fedora/fedora:latest
buildah manifest create quay.io/fedora/fedora:latest quay.io/fedora/fedora:40-aarch64 quay.io/fedora/fedora:40-ppc64le quay.io/fedora/fedora:40-s390x quay.io/fedora/fedora:40-x86_64
buildah manifest push quay.io/fedora/fedora:latest docker://quay.io/fedora/fedora:latest --all
buildah rmi registry.fedoraproject.org/fedora-toolbox:40
buildah manifest create registry.fedoraproject.org/fedora-toolbox:40 registry.fedoraproject.org/fedora-toolbox:40-aarch64 registry.fedoraproject.org/fedora-toolbox:40-ppc64le registry.fedoraproject.org/fedora-toolbox:40-s390x registry.fedoraproject.org/fedora-toolbox:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-toolbox:40 docker://registry.fedoraproject.org/fedora-toolbox:40 --all
buildah rmi registry.fedoraproject.org/fedora-toolbox:latest
buildah manifest create registry.fedoraproject.org/fedora-toolbox:latest registry.fedoraproject.org/fedora-toolbox:40-aarch64 registry.fedoraproject.org/fedora-toolbox:40-ppc64le registry.fedoraproject.org/fedora-toolbox:40-s390x registry.fedoraproject.org/fedora-toolbox:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-toolbox:latest docker://registry.fedoraproject.org/fedora-toolbox:latest --all
buildah rmi quay.io/fedora/fedora-toolbox:40
buildah manifest create quay.io/fedora/fedora-toolbox:40 quay.io/fedora/fedora-toolbox:40-aarch64 quay.io/fedora/fedora-toolbox:40-ppc64le quay.io/fedora/fedora-toolbox:40-s390x quay.io/fedora/fedora-toolbox:40-x86_64
buildah manifest push quay.io/fedora/fedora-toolbox:40 docker://quay.io/fedora/fedora-toolbox:40 --all
buildah rmi quay.io/fedora/fedora-toolbox:latest
buildah manifest create quay.io/fedora/fedora-toolbox:latest quay.io/fedora/fedora-toolbox:40-aarch64 quay.io/fedora/fedora-toolbox:40-ppc64le quay.io/fedora/fedora-toolbox:40-s390x quay.io/fedora/fedora-toolbox:40-x86_64
buildah manifest push quay.io/fedora/fedora-toolbox:latest docker://quay.io/fedora/fedora-toolbox:latest --all
buildah rmi registry.fedoraproject.org/fedora-kinoite:40
buildah manifest create registry.fedoraproject.org/fedora-kinoite:40 registry.fedoraproject.org/fedora-kinoite:40-aarch64 registry.fedoraproject.org/fedora-kinoite:40-ppc64le registry.fedoraproject.org/fedora-kinoite:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-kinoite:40 docker://registry.fedoraproject.org/fedora-kinoite:40 --all
buildah rmi registry.fedoraproject.org/fedora-kinoite:latest
buildah manifest create registry.fedoraproject.org/fedora-kinoite:latest registry.fedoraproject.org/fedora-kinoite:40-aarch64 registry.fedoraproject.org/fedora-kinoite:40-ppc64le registry.fedoraproject.org/fedora-kinoite:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-kinoite:latest docker://registry.fedoraproject.org/fedora-kinoite:latest --all
buildah rmi quay.io/fedora/fedora-kinoite:40
buildah manifest create quay.io/fedora/fedora-kinoite:40 quay.io/fedora/fedora-kinoite:40-aarch64 quay.io/fedora/fedora-kinoite:40-ppc64le quay.io/fedora/fedora-kinoite:40-x86_64
buildah manifest push quay.io/fedora/fedora-kinoite:40 docker://quay.io/fedora/fedora-kinoite:40 --all
buildah rmi quay.io/fedora/fedora-kinoite:latest
buildah manifest create quay.io/fedora/fedora-kinoite:latest quay.io/fedora/fedora-kinoite:40-aarch64 quay.io/fedora/fedora-kinoite:40-ppc64le quay.io/fedora/fedora-kinoite:40-x86_64
buildah manifest push quay.io/fedora/fedora-kinoite:latest docker://quay.io/fedora/fedora-kinoite:latest --all
buildah rmi registry.fedoraproject.org/fedora-onyx:40
buildah manifest create registry.fedoraproject.org/fedora-onyx:40 registry.fedoraproject.org/fedora-onyx:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-onyx:40 docker://registry.fedoraproject.org/fedora-onyx:40 --all
buildah rmi registry.fedoraproject.org/fedora-onyx:latest
buildah manifest create registry.fedoraproject.org/fedora-onyx:latest registry.fedoraproject.org/fedora-onyx:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-onyx:latest docker://registry.fedoraproject.org/fedora-onyx:latest --all
buildah rmi quay.io/fedora/fedora-onyx:40
buildah manifest create quay.io/fedora/fedora-onyx:40 quay.io/fedora/fedora-onyx:40-x86_64
buildah manifest push quay.io/fedora/fedora-onyx:40 docker://quay.io/fedora/fedora-onyx:40 --all
buildah rmi quay.io/fedora/fedora-onyx:latest
buildah manifest create quay.io/fedora/fedora-onyx:latest quay.io/fedora/fedora-onyx:40-x86_64
buildah manifest push quay.io/fedora/fedora-onyx:latest docker://quay.io/fedora/fedora-onyx:latest --all
buildah rmi registry.fedoraproject.org/fedora-sericea:40
buildah manifest create registry.fedoraproject.org/fedora-sericea:40 registry.fedoraproject.org/fedora-sericea:40-aarch64 registry.fedoraproject.org/fedora-sericea:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-sericea:40 docker://registry.fedoraproject.org/fedora-sericea:40 --all
buildah rmi registry.fedoraproject.org/fedora-sericea:latest
buildah manifest create registry.fedoraproject.org/fedora-sericea:latest registry.fedoraproject.org/fedora-sericea:40-aarch64 registry.fedoraproject.org/fedora-sericea:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-sericea:latest docker://registry.fedoraproject.org/fedora-sericea:latest --all
buildah rmi quay.io/fedora/fedora-sericea:40
buildah manifest create quay.io/fedora/fedora-sericea:40 quay.io/fedora/fedora-sericea:40-aarch64 quay.io/fedora/fedora-sericea:40-x86_64
buildah manifest push quay.io/fedora/fedora-sericea:40 docker://quay.io/fedora/fedora-sericea:40 --all
buildah rmi quay.io/fedora/fedora-sericea:latest
buildah manifest create quay.io/fedora/fedora-sericea:latest quay.io/fedora/fedora-sericea:40-aarch64 quay.io/fedora/fedora-sericea:40-x86_64
buildah manifest push quay.io/fedora/fedora-sericea:latest docker://quay.io/fedora/fedora-sericea:latest --all
buildah rmi registry.fedoraproject.org/fedora-silverblue:40
buildah manifest create registry.fedoraproject.org/fedora-silverblue:40 registry.fedoraproject.org/fedora-silverblue:40-aarch64 registry.fedoraproject.org/fedora-silverblue:40-ppc64le registry.fedoraproject.org/fedora-silverblue:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-silverblue:40 docker://registry.fedoraproject.org/fedora-silverblue:40 --all
buildah rmi registry.fedoraproject.org/fedora-silverblue:latest
buildah manifest create registry.fedoraproject.org/fedora-silverblue:latest registry.fedoraproject.org/fedora-silverblue:40-aarch64 registry.fedoraproject.org/fedora-silverblue:40-ppc64le registry.fedoraproject.org/fedora-silverblue:40-x86_64
buildah manifest push registry.fedoraproject.org/fedora-silverblue:latest docker://registry.fedoraproject.org/fedora-silverblue:latest --all
buildah rmi quay.io/fedora/fedora-silverblue:40
buildah manifest create quay.io/fedora/fedora-silverblue:40 quay.io/fedora/fedora-silverblue:40-aarch64 quay.io/fedora/fedora-silverblue:40-ppc64le quay.io/fedora/fedora-silverblue:40-x86_64
buildah manifest push quay.io/fedora/fedora-silverblue:40 docker://quay.io/fedora/fedora-silverblue:40 --all
buildah rmi quay.io/fedora/fedora-silverblue:latest
buildah manifest create quay.io/fedora/fedora-silverblue:latest quay.io/fedora/fedora-silverblue:40-aarch64 quay.io/fedora/fedora-silverblue:40-ppc64le quay.io/fedora/fedora-silverblue:40-x86_64
buildah manifest push quay.io/fedora/fedora-silverblue:latest docker://quay.io/fedora/fedora-silverblue:latest --all

obviously /test/ is just a test path, in reality it would download the images to a temporary directory and the path used in the skopeo commands would include that directory.

@walters @kevin @siosm if you could check this looks to be doing the right things, that'd be great.

I'd recommend adding a timeout to this call with timeout=<seconds>. I think it can be quite generous (hours even), but that way the service won't hang if a subprocess gets stuck.

Also, Python doesn't seem to document that the subprocess.run call can raise OSError-based exceptions beyond hinting it pipes things along to Popen, but it will do so if, for example, the executable doesn't exist:

>>> subprocess.run(["notinpath", "--oh-no"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.12/subprocess.py", line 548, in run
    with Popen(*popenargs, **kwargs) as process:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/subprocess.py", line 1026, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib64/python3.12/subprocess.py", line 1955, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'notinpath'

I'd recommend handling that exception in addition to the TimeoutError that's raised when a timeout is hit.

I'd recommend writing this as

registries = self.conf.get("container", {}).get("registries")

if you want it to be optional to have a container section of the config since at it currently is written, it'll raise an AttributeError when it calls get on the default None returned from the first get call.

Commands all look reasonable to me.

I tend to err on the side of just letting exceptions run, for message consumers, because it sure lets you know when something's wrong with the consumer. But as this is your project, how do you want to "handle" exceptions exactly, in this case? Hide them with error messages nobody will ever look at? Funnel them into the "wait 60 seconds, then raise Nack instead" mechanism? Something else?

rebased onto d859c3084a394e9aa416219e4525286be968eb2c

I'd recommend writing this as
registries = self.conf.get("container", {}).get("registries")
if you want it to be optional to have a container section of the config since at it currently is written, it'll raise an AttributeError when it calls get on the default None returned from the first get call.

Oh, yeah, I meant to do it that way but forgot. Thanks. Fixed.

I tend to err on the side of just letting exceptions run, for message consumers, because it sure lets you know when something's wrong with the consumer. But as this is your project, how do you want to "handle" exceptions exactly, in this case? Hide them with error messages nobody will ever look at? Funnel them into the "wait 60 seconds, then raise Nack instead" mechanism? Something else?

Ordinarily I'd wire something like this up to Sentry (or a similar error-aggregating service), but I guess the only way to get notified of a service problem is to crash the pod? Or can we at least alert off error-level logs?

I think for the timeout error that's likely a transient network issue and could be handled via a little wait and Nack. For the OSError, eh, crashing is okay I guess since the container would need re-building, but I would recommend including a comment on the call explicitly noting you're handling the OSError that way.

Ah, right, you're running the consumer as a pod. I tend to run consumers as services in a VM, which probably gives somewhat different behaviour.

This is documented at https://fedora-messaging.readthedocs.io/en/stable/user-guide/consuming.html#exceptions . The difference between "raising Nack" and "raising any non-special exception" seems to be that in the "Nack" case, the consumer is not "cancelled" (whatever that means to the server, exactly) and no error is logged. In the "any other exception" case, the consumer is "cancelled", and the exception is logged as an error.

In a VM, when the consumer raises an exception, in practice what happens is I get an email - because the consumer configuration says to email me error logs - then the consumer service dies, auto-restarts itself and immediately tries to consume the message again (so when something goes wrong overnight I wake up to several hundred emails, which sure lets me know something went wrong, unless I put in a backoff mechanism). I guess if you're running the consumer in a pod, when it dies, the pod dies...so then it depends whether you configure the pod to auto-restart?

So...on the whole, yeah, I agree if we can be sure an error looks like a network connectivity issue, we should wait and raise Nack, at least a few times (but maybe if this happens more than five times in a row we should crash). If we're not sure what the problem is, I don't think we should eat the original exception or raise Nack, I think it's probably best to crash on the initial exception, because otherwise the consumer might get stuck just looping over a message it can't handle every 60 seconds and not telling anyone about it. In which case we might not notice till someone realized the container images were stale, or the backlog of messages got so big it started triggering infra monitoring alerts. Or, I guess alternatively, we could log the exception trace as an error - and ensure the consumer config is set up to email somebody when that happens - and then wait and raise Nack?

oh, yeah, logging is very configurable via consumer config, to elaborate on that a bit. e.g. for the openQA consumers we have this stanza in the consumer config file:

[log_config.handlers.email]
class = "logging.handlers.SMTPHandler"
formatter = "simple"
level = "ERROR"
mailhost = "bastion"
fromaddr = "root@openqa.fedoraproject.org"
toaddrs = ["adamwill@fp.o","lruzicka@fp.o",]
subject = "openQA scheduler error"

which is what implements "email me and lukas if anything goes wrong".

Ah, I guess I should clarify what I was (ineffectually) inquiring about was if there was a better solution available than configuring the pod to email error logs to me. If that is what we've got, I can make that work.

I do get an email if the pod crashes and it will restart, however I don't love that as an intentional error handling strategy. My preference would be to catch the exception, log it at the error level (or even at the exception level for the traceback) with the assumption that the person running the service has a way to hear about errors, and Nack the message after introducing a little sleep.

Especially if there's no log aggregator, not crashing has the advantage of allowing the investigator to see the logs proceeding the error.

You can drop this if/else block if you switch self.container_repos to a defaultdict:

>>> from collections import defaultdict
>>> x = defaultdict(list)
>>> x["key"].append(1)
>>> x["key"].append(2)
>>> x
defaultdict(<class 'list'>, {'key': [1, 2]})
>>> x["key"]
[1, 2]
>>>

This is fine, but does:

consumer.container_handlers = []

not just work?

You can drop this if/else block if you switch self.container_repos to a defaultdict:
```

from collections import defaultdict
x = defaultdict(list)
x["key"].append(1)
x["key"].append(2)
x
defaultdict(, {'key': [1, 2]})
x["key"]
[1, 2]

```

yes, I know, but I tend to prefer the if/else for trivial implementations. IIRC defaultdict has been moved around before, which was a bit of a pain for code that uses it, so I tend to use it only when the alternative is really painful.

How about pushing the subvariant check down into the cloud handlers?

Since you've got a CantHandle exception which is being raised in some cases to indicate "I'm not the handler for this thing" I think it's clearer to use that as the one and only filtering mechanism. You can rename self.cloud_handlers to just self.handlers and add self.handle_container to the list.

This is fine, but does:
consumer.container_handlers = []
not just work?

oh, yeah, it probably would...overthinking...

How about pushing the subvariant check down into the cloud handlers?

Since you've got a CantHandle exception which is being raised in some cases to indicate "I'm not the handler for this thing" I think it's clearer to use that as the one and only filtering mechanism. You can rename self.cloud_handlers to just self.handlers and add self.handle_container to the list.

I mean, sure, we could, I just wasn't sure whether you'd want to, and it seemed potentially a slightly different scope from this PR. the existing code at least implies that the approach in this PR is what's "intended" when adding a new "class" of consumers; changing to a "we throw every consumer at every image and see what happens" model seems like kind of a separate change from "adding a new class of consumers", although I guess it's arguable.

if that's the way you want to go, it's fine with me, I might make it a separate, earlier commit, though...

note that would mean every cloud consumer would have to be careful not to try and handle non-cloud images, and every container consumer would have to be careful not to try and handle non-container images. in practice at present that's fine, it's just...worth noting.

rebased onto a40c3dc3ddbdf2c8caea7ae5a184334f458e9429

okay, rejigged with more error handling, and a handler vs. image battle royale! in the end I decided it was fine for it all to be in one commit.

This check needs to move before any other check as, if this runs before a handler that could deal with the image and there's no registries configured, the image will be incorrectly skipped.

Alternatively (or additionally), it might make sense to be rid of the NotHandled exception entirely, log it at info level, and just return early. As an interface it's a little tricky as this bug shows, and if all handlers are supposed to decide if they want to handle the image or not, one handler probably shouldn't be able to skip all remaining handlers.

To be clear, when you are talking about NACKing things, thats reject/put back on queue? Or is that drop message so it never gets processed?

As far as monitoring, yeah, we have openshift mailing on things like pod crashes, etc.
It should also notify on health checks failing, so we could perhaps add a health check, if we get errors/issues, start reporting unhealthy so it alerts?

We are also slowly ramping up zabbix, and could probibly do some monitoring from there longer term.

To be clear, when you are talking about NACKing things, thats reject/put back on queue? Or is that drop message so it never gets processed?

Yeah, it'll tell the broker to re-queue the message and try again later. While I don't recall if the specification indicates whether or not it goes at the back of the queue, in practice other queued messages will get delivered first so it's an okay strategy if the message is the problem.

We could implement more clever client-side retrying, buuuut when you've got a hammer and something that looks vaguely like a nail...

As far as monitoring, yeah, we have openshift mailing on things like pod crashes, etc.
It should also notify on health checks failing, so we could perhaps add a health check, if we get errors/issues, start reporting unhealthy so it alerts?

We are also slowly ramping up zabbix, and could probibly do some monitoring from there longer term.

I think email is fine for the short-term (assuming the pods have the ability to connect to "bastion" for email). A health check would be nice, but I think would require a bit more work - my memory says it needs to be HTTP?

rebased onto 8a526d64b8d1bea39188fb2326b7a1993819cfa7

rebased onto e286e1e8159e1d320e689b36086bbe8e4cf70217

IIRC container healthcheck is just an arbitrary command. it's very common to have it be just a curl command that tries to hit an endpoint of the webapp running in the container, but it doesn't have to be.

This check needs to move before any other check as, if this runs before a handler that could deal with the image and there's no registries configured, the image will be incorrectly skipped.

Good catch, fixed.

Alternatively (or additionally), it might make sense to be rid of the NotHandled exception entirely, log it at info level, and just return early. As an interface it's a little tricky as this bug shows, and if all handlers are supposed to decide if they want to handle the image or not, one handler probably shouldn't be able to skip all remaining handlers.

Yeah, I understand the point, I'm a bit on the fence about it. Honestly the initial reason I invented NotHandled was to avoid incorrectly logging "no handler found" when we fell out of the loop, but I had to sacrifice that log message for the new approach anyway (because we now really iterate over all images in the compose, so we won't find a handler for tons of them).

I guess conceptually it kinda depends whether our model is "there should be exactly one correct handler for each image" (in which case it seems defensible for the handler that has decided it is The Handler for the given image to declare it NotHandled), or "any number of handlers might possibly handle any given image" (in which case that isn't really defensible). I guess the current code kinda implicitly splits the difference (because we don't drop out of the loop once any single handler decides to handle an image, but we do have NotHandled). WDYT?

I suppose we can't really enforce One Handler Per Image unless we get fancier about it, which is harder with the "handlers are just callables" model. With the "handlers are classes" design we could have the handlers have a match method and have __call__ call that first, and if it gets more than one "match" for an image it could blow up (this was my initial design, with the class-y approach, before I simplified it to just do both the filtering and actual handling within a single method). But with "handlers are callables" it's difficult.

So...I guess that angles towards "declare the model is 'multiple handlers can potentially handle the same image' and get rid of NotHandled"?

I don't think there's a particular reason to require one handler per image. In practice it'll likely be that way, but if more than one handler wants to do a thing with an image that's not a problem.

...and I suppose if we get rid of NotHandled we don't really need CantHandle either, we just have the handlers return...

rebased onto f639d0e259bf526152269a0683631fd69609a8f4

okay, rebased with the CantHandle and NotHandled concepts now dropped, handlers just return if they don't want to handle the image. We could have more logging of this, I guess, but it'd get kinda verbose as we'd log on dozens of images per compose. I think it might be better to just add logging on the fly if we actually run into a problem.

rebased onto 2ca7189c3012f5fc8efb4d10234299a640727ae9

For comparison, I hacked up sync-latest-container-base-image.sh to just print out the commands it runs, and also cut out candidate-registry for a closer comparison, and this is what it would do right now, for Rawhide (so it's finding images from the current Rawhide compose):

skopeo copy oci-archive:Fedora-Container-Base-Generic.aarch64-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-aarch64
skopeo copy oci-archive:Fedora-Container-Base-Generic.aarch64-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora:41-aarch64
skopeo copy oci-archive:Fedora-Container-Base-Generic.ppc64le-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-ppc64le
skopeo copy oci-archive:Fedora-Container-Base-Generic.ppc64le-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora:41-ppc64le
skopeo copy oci-archive:Fedora-Container-Base-Generic.s390x-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-s390x
skopeo copy oci-archive:Fedora-Container-Base-Generic.s390x-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora:41-s390x
skopeo copy oci-archive:Fedora-Container-Base-Generic.x86_64-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora:41-x86_64
skopeo copy oci-archive:Fedora-Container-Base-Generic.x86_64-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora:41-x86_64
buildah rmi registry.fedoraproject.org/fedora:rawhide
buildah manifest create registry.fedoraproject.org/fedora:rawhide docker://registry.fedoraproject.org/fedora:41-aarch64 docker://registry.fedoraproject.org/fedora:41-ppc64le docker://registry.fedoraproject.org/fedora:41-s390x docker://registry.fedoraproject.org/fedora:41-x86_64
buildah manifest push registry.fedoraproject.org/fedora:rawhide docker://registry.fedoraproject.org/fedora:rawhide --all
buildah rmi registry.fedoraproject.org/fedora:41
buildah manifest create registry.fedoraproject.org/fedora:41 docker://registry.fedoraproject.org/fedora:41-aarch64 docker://registry.fedoraproject.org/fedora:41-ppc64le docker://registry.fedoraproject.org/fedora:41-s390x docker://registry.fedoraproject.org/fedora:41-x86_64
buildah manifest push registry.fedoraproject.org/fedora:41 docker://registry.fedoraproject.org/fedora:41 --all
buildah rmi quay.io/fedora/fedora:rawhide
buildah manifest create quay.io/fedora/fedora:rawhide docker://quay.io/fedora/fedora:41-aarch64 docker://quay.io/fedora/fedora:41-ppc64le docker://quay.io/fedora/fedora:41-s390x docker://quay.io/fedora/fedora:41-x86_64
buildah manifest push quay.io/fedora/fedora:rawhide docker://quay.io/fedora/fedora:rawhide --all
buildah rmi quay.io/fedora/fedora:41
buildah manifest create quay.io/fedora/fedora:41 docker://quay.io/fedora/fedora:41-aarch64 docker://quay.io/fedora/fedora:41-ppc64le docker://quay.io/fedora/fedora:41-s390x docker://quay.io/fedora/fedora:41-x86_64
buildah manifest push quay.io/fedora/fedora:41 docker://quay.io/fedora/fedora:41 --all
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.aarch64-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-aarch64
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.aarch64-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-aarch64
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.ppc64le-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-ppc64le
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.ppc64le-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-ppc64le
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.s390x-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-s390x
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.s390x-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-s390x
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.x86_64-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-minimal:41-x86_64
skopeo copy oci-archive:Fedora-Container-Base-Generic-Minimal.x86_64-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-minimal:41-x86_64
buildah rmi registry.fedoraproject.org/fedora-minimal:rawhide
buildah manifest create registry.fedoraproject.org/fedora-minimal:rawhide docker://registry.fedoraproject.org/fedora-minimal:41-aarch64 docker://registry.fedoraproject.org/fedora-minimal:41-ppc64le docker://registry.fedoraproject.org/fedora-minimal:41-s390x docker://registry.fedoraproject.org/fedora-minimal:41-x86_64
buildah manifest push registry.fedoraproject.org/fedora-minimal:rawhide docker://registry.fedoraproject.org/fedora-minimal:rawhide --all
buildah rmi registry.fedoraproject.org/fedora-minimal:41
buildah manifest create registry.fedoraproject.org/fedora-minimal:41 docker://registry.fedoraproject.org/fedora-minimal:41-aarch64 docker://registry.fedoraproject.org/fedora-minimal:41-ppc64le docker://registry.fedoraproject.org/fedora-minimal:41-s390x docker://registry.fedoraproject.org/fedora-minimal:41-x86_64
buildah manifest push registry.fedoraproject.org/fedora-minimal:41 docker://registry.fedoraproject.org/fedora-minimal:41 --all
buildah rmi quay.io/fedora/fedora-minimal:rawhide
buildah manifest create quay.io/fedora/fedora-minimal:rawhide docker://quay.io/fedora/fedora-minimal:41-aarch64 docker://quay.io/fedora/fedora-minimal:41-ppc64le docker://quay.io/fedora/fedora-minimal:41-s390x docker://quay.io/fedora/fedora-minimal:41-x86_64
buildah manifest push quay.io/fedora/fedora-minimal:rawhide docker://quay.io/fedora/fedora-minimal:rawhide --all
buildah rmi quay.io/fedora/fedora-minimal:41
buildah manifest create quay.io/fedora/fedora-minimal:41 docker://quay.io/fedora/fedora-minimal:41-aarch64 docker://quay.io/fedora/fedora-minimal:41-ppc64le docker://quay.io/fedora/fedora-minimal:41-s390x docker://quay.io/fedora/fedora-minimal:41-x86_64
buildah manifest push quay.io/fedora/fedora-minimal:41 docker://quay.io/fedora/fedora-minimal:41 --all
skopeo copy oci-archive:Fedora-Container-Toolbox.aarch64-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-aarch64
skopeo copy oci-archive:Fedora-Container-Toolbox.aarch64-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-aarch64
skopeo copy oci-archive:Fedora-Container-Toolbox.ppc64le-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-ppc64le
skopeo copy oci-archive:Fedora-Container-Toolbox.ppc64le-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-ppc64le
skopeo copy oci-archive:Fedora-Container-Toolbox.s390x-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-s390x
skopeo copy oci-archive:Fedora-Container-Toolbox.s390x-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-s390x
skopeo copy oci-archive:Fedora-Container-Toolbox.x86_64-Rawhide-20240528.n.0.oci.tar docker://registry.fedoraproject.org/fedora-toolbox:41-x86_64
skopeo copy oci-archive:Fedora-Container-Toolbox.x86_64-Rawhide-20240528.n.0.oci.tar docker://quay.io/fedora/fedora-toolbox:41-x86_64
buildah rmi registry.fedoraproject.org/fedora-toolbox:rawhide
buildah manifest create registry.fedoraproject.org/fedora-toolbox:rawhide docker://registry.fedoraproject.org/fedora-toolbox:41-aarch64 docker://registry.fedoraproject.org/fedora-toolbox:41-ppc64le docker://registry.fedoraproject.org/fedora-toolbox:41-s390x docker://registry.fedoraproject.org/fedora-toolbox:41-x86_64
buildah manifest push registry.fedoraproject.org/fedora-toolbox:rawhide docker://registry.fedoraproject.org/fedora-toolbox:rawhide --all
buildah rmi registry.fedoraproject.org/fedora-toolbox:41
buildah manifest create registry.fedoraproject.org/fedora-toolbox:41 docker://registry.fedoraproject.org/fedora-toolbox:41-aarch64 docker://registry.fedoraproject.org/fedora-toolbox:41-ppc64le docker://registry.fedoraproject.org/fedora-toolbox:41-s390x docker://registry.fedoraproject.org/fedora-toolbox:41-x86_64
buildah manifest push registry.fedoraproject.org/fedora-toolbox:41 docker://registry.fedoraproject.org/fedora-toolbox:41 --all
buildah rmi quay.io/fedora/fedora-toolbox:rawhide
buildah manifest create quay.io/fedora/fedora-toolbox:rawhide docker://quay.io/fedora/fedora-toolbox:41-aarch64 docker://quay.io/fedora/fedora-toolbox:41-ppc64le docker://quay.io/fedora/fedora-toolbox:41-s390x docker://quay.io/fedora/fedora-toolbox:41-x86_64
buildah manifest push quay.io/fedora/fedora-toolbox:rawhide docker://quay.io/fedora/fedora-toolbox:rawhide --all
buildah rmi quay.io/fedora/fedora-toolbox:41
buildah manifest create quay.io/fedora/fedora-toolbox:41 docker://quay.io/fedora/fedora-toolbox:41-aarch64 docker://quay.io/fedora/fedora-toolbox:41-ppc64le docker://quay.io/fedora/fedora-toolbox:41-s390x docker://quay.io/fedora/fedora-toolbox:41-x86_64
buildah manifest push quay.io/fedora/fedora-toolbox:41 docker://quay.io/fedora/fedora-toolbox:41 --all

Thanks Adam for the work here. I'll try to take a look at this PR tomorrow.

rebased onto 282de09ab798d3e312104067a1ea62cc009013e4

i did not review the full code changes but the output listed above looks in https://pagure.io/cloud-image-uploader/pull-request/10#comment-203462 good to me.

I think we'll have to give it a try and resolve the issues "live" in the staging environment.

I do want to change the fedfind cache disabling approach today (to use an env var, which should be much simpler and less potentially polluting of your home dir), so I'll do one more rebase today.

OK, I just rebased this again with the env var approach, which I've released in fedfind 5.3.0 (updates coming soon). This is much simpler than the magic file approach and doesn't have the risk of leaving the change 'live' if the test process fails in an unfortunate way.

Things look good to me, tests all pass now!

Pull-Request has been merged by jcline

Filed https://pagure.io/releng/issue/12142 to discuss deployment.