hlb icon indicating copy to clipboard operation
hlb copied to clipboard

building/pushing multi-platform images

Open coryb opened this issue 4 years ago • 1 comments

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:

  1. Build each image (1 solve for each image) -> OK
  2. create a result object
  3. add all return values to result map
  4. 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.

coryb avatar Oct 09 '21 00:10 coryb

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?

coryb avatar Oct 11 '21 16:10 coryb