On Wed, Nov 11, 2020 at 10:27:49AM +0100, Alexander Wellbrock via Podman wrote:
Hey there, since buildx is not a thing yet to build multi-arch images on one host I'd like to make use of the multi-arch feature of registries like docker.io and quay.io.
I'm using the podman manifest command for this purpose but struggle to get it to work properly. I hope someone can point me in the right direction.
I've get it to work (kind-of) by building two images on two different hosts architecture wise and then used podman manifest create to create a multi-arch manifest of both images. I then used podman manifest push to get it onto quay.io. This works and I'm able to use it, but unfortunately there is a catch right now.
If I'm doing this multiple times, it complains that since a manifest for example-image:latest is already present. So it only work if the manifest does not already exist. I can't update it with newer images. Only if I remove the manifest :latest manually beforehand it obviously works again, but I'd like to avoid that. Apart from that it makes sense I suppose, because I'd rather like to update the manifest with new images then to override the old manifest, right?
I then tried to use podman manifest add, remove etc. Podman then complains about manifest version not supported. E.g. I tried to update the actual images per architecture and then add the new ones to the manifest which I couldn't get to work. I'm highly confused about the podman manifest command man page.
Someone asked a similar question on IRC a few days ago, and I didn't have a good answer then, so had to poke at it a bit. Anyway, the sequence of steps for creating a list using images that have previously been pushed to a registry looks something like this: on a box of each $arch: podman build -t docker://registry/repo:$arch-tag on one box: podman manifest create $listname repeat for each $arch on that one box: podman manifest add $listname docker://registry/repo:$arch-tag finally, on that one box: podman manifest push [--all] $listname docker://registry/repo:$single-tag Now, if you build a new image and want to replace it in the list, you should be able to start with the list you already have, or you can do this to start to build a new, updated version of the list: podman manifest create updated-list podman manifest add --all updated-list docker://registry/repo:$single-tag Note: "podman manifest add" (and "buildah manifest add") looks like it just looks at a locally-stored image if it finds one with the same name as the reference being passed on the command line. That locally-stored image isn't going to include all of the other entries in the copy of the list that the registry has, and that can cause some problems. I think we'll need to fix that. If it works as intended (or you started with the list you already had), you should have a copy of the list that's up at the registry, and "podman manifest inspect" should show you several entries in that list. The spec doesn't say anything about what to do when there are multiple entries in a list for the same platform, so we'll want to remove the entry that the list has for the current machine before we try to add our newly-built image to the list as its replacement. arch=$(go env GOARCH) instance=$(podman manifest inspect updated-list | jq -r \ '.manifests|map(select(.platform.architecture=="'$arch'"))[].digest') podman manifest remove updated-list $instance Now you can go ahead and add your new image to the list and push the updated list to the registry. If the new image has already been pushed to the registry: podman manifest add updated-list docker://registry/repo:$arch-tag podman manifest push updated-list docker://registry/repo:$single-tag If not: podman manifest add updated-list local-$arch-image podman manifest push --all updated-list docker://registry/repo:$single-tag The main difference between these two cases is that the --all flag tells podman to push the images that the list references, in addition to the list itself. That can take a while, since for every image, even though the pushing logic checks if a part of an image has already been uploaded to the registry before trying to upload it, it's still a lot of parts, and that can require a lot of round trips to the registry. But if the image wasn't pushed first, the registry will probably reject the new list because it references things that the registry doesn't have, so it's required. I've got a couple of ideas of things we can do to help simplify this process, so that it requires less typing at the CLI, but none of that's implemented yet. If you run into trouble, please follow up with the specific errors you're getting, and we'll see where they point us. Cheers, Nalin