building/pushing multi-platform images
Multi-platform image publishing has become a more common use-case. We need to figure out how to represent multi-platform images via HLB. I recently added an option::image platform to let us use platform-specific images in a multi-platform manfiest, but we also need to figure out how to build and publish multi-platform images.
There was are recent thread on slack: https://dockercommunity.slack.com/archives/C7S7A40MP/p1633007913196000
Which Tonis summarized as:
- Build each image (1 solve for each image) -> OK
- create a result object
- add all return values to result map
- return result
The dockerfile frontend does this here.
Via pipeline and stage we can build a bunch of images in parallel, but currently they are separate results. We need to think about a syntax that allows us to merge multiple results into a single result so that we can export it.
option::image linuxAmd64() {
platform "linux" "amd64"
}
option::image linuxArm64() {
platform "linux" "arm64"
}
fs cowsay(option::image plat) {
image "ubuntu:focal" with plat
run "apt update && apt install -y cowsay"
}
fs default() {
dockerPush "mycowsay:latest" with option {
platform "linux" "amd64" cowsay(linuxAmd64)
platform "linux" "arm64" cowsay(linuxArm64)
}
}
This would add an option::dockerPush platform(string os, string arch, fs myfs)
I dont like this much... any suggestions for other/better ideas on syntax? I would also like some sort of "foreach" syntax, so in the example above I could run apt update && apt install -y cowsay in all existing registered platforms for the ubuntu:focal image where each platform would run in parallel, then we could push all platforms to preserve the "multi-platform" nature of the base image.
Thinking on this a bit more, perhaps it makes sense to add dockerPush to the pipeline context, so a multi-platform push could look something like this:
option::image linuxAmd64() {
platform "linux" "amd64"
}
option::image linuxArm64() {
platform "linux" "arm64"
}
fs cowsay(option::image plat) {
image "ubuntu:focal" with plat
run "apt update && apt install -y cowsay"
}
pipeline default() {
stage cowsay(linuxAmd64) cowsay(linuxArm64)
dockerPush "mycowsay:latest"
}
Then we could have stage add all the return values from each solve to a new result map which dockerPush could use?