-
Notifications
You must be signed in to change notification settings - Fork 691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support index manifest to push multi-arch container images #2087
Support index manifest to push multi-arch container images #2087
Conversation
We could improve this new rule load( "@io_bazel_rules_docker//container:container.bzl", "container_push_index")
container_push_index(
name = "push_all",
format = "Docker",
image = "//:my_image",
platforms: [
"linux/amd64",
"linux/arm64/v8",
"linux/ppc64le",
],
registry = "localhost:5000",
repository = "docker/test",
tag = "{VERSION}",
) Where But this improvement requires before several modifications as suggested in #2073. |
Regarding using transitions: one benefit of not doing so, and allowing explicitly wiring up multiple images is that it enables non-traditional use cases such as storing things like K8s manifests (or binaries, or WASM artifacts, etc). I am not sure using transitions is worth losing the flexibility for other use cases. |
As I said on Slack, we can keep the We're able to keep the two differents ways:
And:
|
hey @lbcjbb, this is super useful! |
Hi. This project needs new maintainers as mentionened in this discussion #2038 |
So does this actually have maintainers now? |
This is a very useful addition to the rule. How can we get attention to this PR? |
I don't know :/ |
I can take a look soon :) |
Hi @uhthomas, just checking in, have you had an opportunity to take a look? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I think this looks mostly fine. Just a few code comments. With respect to the code itself, is it possible to unit test some of this to avoid regressions?
I also had another topic I want to discuss. How does this fit into transitions? Is this compatible with a single target which could transition to different target platforms?
Sorry for the delay.
These components will also be used by the 'index' version of the pusher binary. - The function to check and initialize the docker client configuration. - The function to compute the list of options to give to remote.Write*() functions. We now use three new options: - remote.WithContext() to make the push cancellable. - remote.WithUserAgent() to help the registry to known the origin of requests. - remote.WithJobs() to define the number of parralel jobs to use. We give the value returned by runtime.NumCPU() to override the hardcoded value in the library go-containerregistry which is 4.
The main goal of this refactoring is to make available several functions. These functions will be used by the 'index' version of the `container_push` rule. Unless I am mistaken, the code is exactly the same.
Thank you very much for the review @uhthomas ❤️. For all comments related to the Go errors 1.13 (the use of
If I recall, i don't think. But we will be able to easily add this feature. |
@uhthomas please 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's some issue in digester_index
.
On Mac OS Ventura 13.1, Intel chip: I give up waiting after 10 minutes. digester_index
is the top CPU consumer that whole time.
On Ubuntu 20.04 in a container run on K8S, x86_64: digester_index
is killed after about 3 minutes.
To reproduce, I put together a simple build that merely repackages the NGINX container.
BUILD
load("@io_bazel_rules_docker//container:container.bzl", "container_push_index")
container_push_index(
name = "push-all",
format = "Docker",
images = {
"@nginx-linux-amd64//image": "linux/amd64",
"@nginx-linux-arm64v8//image": "linux/arm64/v8",
},
registry = "<my private repo>.amazonaws.com",
repository = "test",
stamp = "@io_bazel_rules_docker//stamp:always",
tag = "latest"
)
pr2087.patch
diff --git a/container/push.bzl b/container/push.bzl
index 9be8d89..83b8b96 100644
--- a/container/push.bzl
+++ b/container/push.bzl
@@ -282,6 +282,7 @@ def _container_push_index_impl(ctx):
stamp = ctx.attr.stamp[StampSettingInfo].value,
format = ctx.attr.format,
skip_unchanged_digest = ctx.attr.skip_unchanged_digest,
+ insecure_repository = ctx.attr.insecure_repository
),
)
(That final blank line is important)
WORKSPACE
workspace(
name = "pr2087",
)
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
],
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
RULES_DOCKER_VERSION = "c079c0ddad54d34205c0a94fbb7cf9c6e7a6f48b"
http_archive(
name = "io_bazel_rules_docker",
patch_args = ["-p1"],
patches = [
"//:pr2087.patch",
],
strip_prefix = "bazel-rules_docker-%s" % RULES_DOCKER_VERSION,
type = "zip",
url = "https://github.com/leboncoin/bazel-rules_docker/archive/%s.zip" % RULES_DOCKER_VERSION,
)
load("@io_bazel_rules_docker//repositories:repositories.bzl", container_repositories = "repositories")
container_repositories()
load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps")
container_deps()
load("@io_bazel_rules_docker//container:container.bzl", "container_pull")
# https://hub.docker.com/_/nginx
# 1.23.3-alpine
container_pull(
name = "nginx-linux-amd64",
digest = "sha256:c1b9fe3c0c015486cf1e4a0ecabe78d05864475e279638e9713eb55f013f907f",
registry = "index.docker.io",
repository = "library/nginx",
)
container_pull(
name = "nginx-linux-arm64v8",
digest = "sha256:5fbf2392cd98bf322ff24e5de9a74e732ebeb4873c06f29ed801b2bed1b11019",
registry = "index.docker.io",
repository = "library/nginx",
)
I forgot: That's with Bazel 6.0.0 |
I add the new rule `container_push_index` to push a docker image multi platforms. We can use this new rule like this: container_push_index( name = "push_index", format = "Docker", images = { "//:my_image_amd64": "linux/amd64", "//:my_image_arm64": "linux/arm/v6", "//:my_image_ppc64le": "ppc64le", }, registry = "localhost:5000", repository = "docker/myimage", tag = "{STABLE_VERSION}", )
@Topher-the-Geek It's now fixed. Sorry for this stupid mistake. You can apply this patch in your test workspace:
|
Thanks for the quick fix @lbcjbb. For me, this is working as advertised. I'm not an owner of this repo tho, so we still need @uhthomas |
What does it take to get this merged? @uhthomas can you give an update? |
I don't known. Maybe just some time to review, or find new maintainers of this repository (#2038). |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
The rule
container_push
is able to push a single container to a registry but isn't able to push a multi-arch containers, aka index or fat manifest.The specification of an index manifest can be found here:
Issue Number: #1599
What is the new behavior?
I add a new rule named
container_push_index
to push a multi-arch containers.This new rule can be used like that:
Does this PR introduce a breaking change?
The
container_push
rule is not impacted and still works fine as always.