From df9428a357db73ad67636db3fe0f70fec017a93f Mon Sep 17 00:00:00 2001 From: Adam Plumer Date: Wed, 28 Jan 2026 19:41:58 -0500 Subject: [PATCH] chore: add utilities for Windows Docker image publishing Currently, Buildbarn repos publish the artifacts from cross-compiled builds of the various ecosystem binaries. However, this leaves the user to manage pulling those artifacts and distributing/consuming them in their respective environments. For customers leveraging Kubernetes or other containerized settings, this creates a greater burden than Linux consumers. In a previous commit, the image handling was moved to rules_img, however rules_img does not allow for the necessary manifest layering to include a Windows image (with a distinct base layer). Therefore, we add an additional macro that reverts back to the original rules_oci publish stream, until rules_img can be updated to support that behavior. For images that do not benefit from a Windows build-out (e.g. the non-RBE images), the new path can still be safely utilized. --- MODULE.bazel | 46 +++++++++++++++++++++++++++++ MODULE.bazel.lock | 12 ++++++-- tools/container.bzl | 71 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 3 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index beb4b7c0..42e0929e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -3,9 +3,11 @@ module(name = "com_github_buildbarn_bb_storage") bazel_dep(name = "aspect_bazel_lib", version = "2.22.5") bazel_dep(name = "aspect_rules_js", version = "2.9.2") bazel_dep(name = "bazel_remote_apis", version = "0") +bazel_dep(name = "bazel_skylib", version = "1.9.0") bazel_dep(name = "gazelle", version = "0.47.0") bazel_dep(name = "googleapis", version = "0.0.0-20260109-6145b5ff") bazel_dep(name = "grpc", version = "1.76.0.bcr.1") +bazel_dep(name = "hermetic_cc_toolchain", version = "4.1.0") bazel_dep(name = "jsonnet_go", version = "0.21.0") bazel_dep(name = "opentelemetry-proto", version = "1.8.0") bazel_dep(name = "platforms", version = "1.0.0") @@ -16,6 +18,8 @@ bazel_dep(name = "rules_go", version = "0.59.0") bazel_dep(name = "rules_img", version = "0.3.3") bazel_dep(name = "rules_jsonnet", version = "0.7.2") bazel_dep(name = "rules_nodejs", version = "6.7.3") +bazel_dep(name = "rules_oci", version = "2.2.7") +bazel_dep(name = "rules_pkg", version = "1.2.0") bazel_dep(name = "rules_proto", version = "7.1.0") bazel_dep(name = "rules_shell", version = "0.6.1") bazel_dep(name = "toolchains_llvm", version = "1.6.0") @@ -26,6 +30,13 @@ git_override( remote = "https://github.com/bazelbuild/remote-apis.git", ) +# TODO: remove when https://github.com/bazel-contrib/rules_oci/pull/886 lands +git_override( + module_name = "rules_oci", + commit = "2df143255d8e25c09a53707a7ff4fd768021d796", + remote = "https://github.com/bazel-contrib/rules_oci.git", +) + single_version_override( module_name = "gazelle", patches = ["//:patches/gazelle/dont-flatten-srcs.diff"], @@ -163,3 +174,38 @@ pull( registry = "gcr.io", repository = "distroless/static", ) + +pull( + name = "nanoserver", + digest = "sha256:4bfc3ec32a8b9bb5e7a182440c517b0706267d88fda77b54acddf819920400ad", + registry = "mcr.microsoft.com", + repository = "windows/nanoserver", +) + +oci = use_extension("@rules_oci//oci:extensions.bzl", "oci") +oci.pull( + name = "distroless_static_oci", + digest = "sha256:7e5c6a2a4ae854242874d36171b31d26e0539c98fc6080f942f16b03e82851ab", + image = "gcr.io/distroless/static", + platforms = [ + "linux/amd64", + "linux/arm64/v8", + ], +) +use_repo(oci, "distroless_static_oci") + +oci.pull( + name = "nanoserver_oci", + digest = "sha256:723a61e89a2c8c88ceeb92986ab1d895c9ae5278789417a2c768f61d6a70f2c7", + image = "mcr.microsoft.com/windows/nanoserver", +) +use_repo(oci, "nanoserver_oci") + +toolchains = use_extension("@hermetic_cc_toolchain//toolchain:ext.bzl", "toolchains") +use_repo(toolchains, "zig_sdk") +register_toolchains( + "@zig_sdk//libc_aware/toolchain:linux_amd64_gnu.2.31", + "@zig_sdk//libc_aware/toolchain:linux_arm64_gnu.2.31", + "@zig_sdk//toolchain:windows_amd64", + "@zig_sdk//toolchain:windows_arm64", +) \ No newline at end of file diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 48fb5ce6..0ea23cd7 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -36,6 +36,7 @@ "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/MODULE.bazel": "004ba890363d05372a97248c37205ae64b6fa31047629cd2c0895a9d0c7779e8", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/source.json": "ac2c3213df8f985785f1d0aeb7f0f73d5324e6e67d593d9b9470fb74a25d4a9b", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", "https://bcr.bazel.build/modules/aspect_rules_js/1.33.1/MODULE.bazel": "db3e7f16e471cf6827059d03af7c21859e7a0d2bc65429a3a11f005d46fc501b", "https://bcr.bazel.build/modules/aspect_rules_js/1.39.0/MODULE.bazel": "aece421d479e3c31dc3e5f6d49a12acc2700457c03c556650ec7a0ff23fc0d95", @@ -166,6 +167,8 @@ "https://bcr.bazel.build/modules/grpc/1.76.0.bcr.1/source.json": "2bf69a9f31b8f680f767eb434ef3f854abf47eb426f8a5caf74a59a7db4aadde", "https://bcr.bazel.build/modules/helly25_bzl/0.3.1/MODULE.bazel": "3a4be20f6fc13be32ad44643b8252ef5af09eee936f1d943cd4fd7867fa92826", "https://bcr.bazel.build/modules/helly25_bzl/0.3.1/source.json": "b129ab1828492de2c163785bbeb4065c166de52d932524b4317beb5b7f917994", + "https://bcr.bazel.build/modules/hermetic_cc_toolchain/4.1.0/MODULE.bazel": "b512c9698968bd4548eecec8fb9bab4327c6f50fb0d12cc56e9a4d32a9a78458", + "https://bcr.bazel.build/modules/hermetic_cc_toolchain/4.1.0/source.json": "25ec6993f3acde436250883f3ab7945ff90a2fe42407af2c66f65f0f3e5b2959", "https://bcr.bazel.build/modules/hermetic_launcher/0.0.3/MODULE.bazel": "757a101698a76a39defeb07a2bae8fd6ea1af8a819e1734a559b71bcb118a53d", "https://bcr.bazel.build/modules/hermetic_launcher/0.0.3/source.json": "4882d1d02a04973cd11a0e61812ec9c96ce3d8ce5e275a7ff7d03409bf04c456", "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", @@ -205,7 +208,8 @@ "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/source.json": "da1cb1add160f5e5074b7272e9db6fd8f1b3336c15032cd0a653af9d2f484aed", "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", - "https://bcr.bazel.build/modules/package_metadata/0.0.5/source.json": "2326db2f6592578177751c3e1f74786b79382cd6008834c9d01ec865b9126a85", + "https://bcr.bazel.build/modules/package_metadata/0.0.6/MODULE.bazel": "341dab6f417197494517d54c8e557c0baee1de7aec83543a4fbefe57900acb7e", + "https://bcr.bazel.build/modules/package_metadata/0.0.6/source.json": "9581d8b22db43550ac75ecc314ee4fa0a33400bfdc77d1317d8af6b18dca7756", "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", @@ -362,7 +366,8 @@ "https://bcr.bazel.build/modules/rules_perl/0.2.4/source.json": "574317d6b3c7e4843fe611b76f15e62a1889949f5570702e1ee4ad335ea3c339", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", @@ -425,7 +430,8 @@ "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", - "https://bcr.bazel.build/modules/tar.bzl/0.6.0/source.json": "4a620381df075a16cb3a7ed57bd1d05f7480222394c64a20fa51bdb636fda658", + "https://bcr.bazel.build/modules/tar.bzl/0.7.0/MODULE.bazel": "cc1acd85da33c80e430b65219a620d54d114628df24a618c3a5fa0b65e988da9", + "https://bcr.bazel.build/modules/tar.bzl/0.7.0/source.json": "9becb80306f42d4810bfa16379fb48aad0b01ce5342bc12fe47dcd6af3ac4d7a", "https://bcr.bazel.build/modules/toolchains_llvm/1.6.0/MODULE.bazel": "39603859cafb1c6830160fcd6370552e836790e6abb2bfb8d13bff53c0c10a64", "https://bcr.bazel.build/modules/toolchains_llvm/1.6.0/source.json": "6bd3ef95a288dd2bb1582eca332af850c9a5428a23bb92cb1c57c2dfe6cb7369", "https://bcr.bazel.build/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "6cced416be2dc5b9c05efd5b997049ba795e5e4e6fafbe1624f4587767638928", diff --git a/tools/container.bzl b/tools/container.bzl index 2ad42d57..4620644c 100644 --- a/tools/container.bzl +++ b/tools/container.bzl @@ -1,6 +1,10 @@ +load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_filegroup") +load("@bazel_skylib//rules:write_file.bzl", "write_file") load("@rules_img//img:image.bzl", "image_index", "image_manifest") load("@rules_img//img:layer.bzl", "image_layer") load("@rules_img//img:push.bzl", "image_push") +load("@rules_oci//oci:defs.bzl", "oci_image", "oci_image_index", "oci_push") +load("@rules_pkg//pkg:tar.bzl", "pkg_tar") def multiarch_go_image(name, binary): """Create a container image with two variants of the given go_binary target. @@ -45,6 +49,62 @@ def multiarch_go_image(name, binary): tags = ["manual"], ) +def multiarch_go_image_with_windows(name, binary): + """Create a container image with three variants of the given go_binary target. + + Args: + name: resulting oci_image_index target + binary: label of a go_binary target; it may be transitioned to another architecture + """ + images = [] + tar_target = "_{}.tar".format(name) + image_target = "_{}.image".format(name) + unix_binary_entrypoint = ["/app/{}".format(native.package_relative_label(binary).name)] + windows_binary_entrypoint = ["C:\\app\\{}".format(native.package_relative_label(binary).name)] + + pkg_tar( + name = tar_target, + srcs = [binary], + include_runfiles = True, + package_dir = "app", + ) + + write_file( + name = image_target + "_entrypoint", + content = select({ + "@rules_go//go/platform:linux_amd64": unix_binary_entrypoint, + "@rules_go//go/platform:linux_arm64": unix_binary_entrypoint, + "@rules_go//go/platform:windows_amd64": windows_binary_entrypoint, + }), + out = "entrypoints.txt" + ) + + oci_image( + name = image_target, + base = select({ + "@rules_go//go/platform:linux_amd64": Label("@distroless_static_oci"), + "@rules_go//go/platform:linux_arm64": Label("@distroless_static_oci"), + "@rules_go//go/platform:windows_amd64": Label("@nanoserver_oci"), + }), + entrypoint = image_target + "_entrypoint", + tars = [tar_target], + # Don't build un-transitioned images, as the default target architecture might be unsupported + # For example when building on linux-i386. + tags = ["manual"], + ) + + oci_image_index( + name = name, + images = [image_target], + platforms = [ + Label("//tools/platforms:linux_amd64"), + # TODO: re-enable when rules_oci supports this pattern +# Label("//tools/platforms:linux_amd64_v3"), + Label("//tools/platforms:linux_arm64"), + Label("//tools/platforms:windows_amd64"), + ] + ) + def container_push_official(name, image, component): image_push( name = name, @@ -56,3 +116,14 @@ def container_push_official(name, image, component): # building all variants can be time-consuming. tags = ["manual"], ) + +def container_push_official_with_windows(name, image, component): + oci_push( + name = name, + image = image, + repository = "ghcr.io/buildbarn/" + component, + remote_tags = "@com_github_buildbarn_bb_storage//tools:stamped_tags", + # Don't build container image unless explicitly requested, as + # building all variants can be time-consuming. + tags = ["manual"], + ) \ No newline at end of file