Skip to content

Commit 86c54e5

Browse files
authored
toolchain: allow to configure build_tar target (#1937)
python/cpython#18080 hasn't been back-ported to python3.8, which happens to be the default interpreter version in a lot of popular base docker images. This change in python's tarfile implementation affects the behavior of https://github.com/bazelbuild/rules_docker/blob/bdea23404dd256c7ae2f8e02d346428044cc7d91/container/archive.py#L144 used by a popular container_image rule. This means that images built by bazel in environments with different python3 versions will result in different image digests. Until the hermeticity of python toolchains is guaranteed, it may be useful to have a workaround for users who can provide their own build_tar tool, akin to https://github.com/kubernetes/repo-infra/blob/72a6f5d05659f7d255b51f152e0725adfe970718/tools/build_tar/buildtar.go
1 parent 029b9a1 commit 86c54e5

File tree

5 files changed

+32
-1
lines changed

5 files changed

+32
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl",
125125
)
126126
docker_toolchain_configure(
127127
name = "docker_config",
128+
# OPTIONAL: Bazel target for the build_tar tool, must be compatible with build_tar.py
129+
build_tar_target="<enter absolute path (i.e., must start with repo name @...//:...) to an executable build_tar target>",
128130
# OPTIONAL: Path to a directory which has a custom docker client config.json.
129131
# See https://docs.docker.com/engine/reference/commandline/cli/#configuration-files
130132
# for more details.

container/layer.bzl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ def build_layer(
102102
"""
103103
toolchain_info = ctx.toolchains["@io_bazel_rules_docker//toolchains/docker:toolchain_type"].info
104104
layer = output_layer
105-
build_layer_exec = ctx.executable.build_layer
105+
if toolchain_info.build_tar_target:
106+
build_layer_exec = toolchain_info.build_tar_target.files_to_run.executable
107+
else:
108+
build_layer_exec = ctx.executable.build_layer
106109
args = ctx.actions.args()
107110
args.add(layer, format = "--output=%s")
108111
args.add(directory, format = "--directory=%s")

testing/default_toolchain/WORKSPACE

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ load(
2626
"local_tool",
2727
)
2828

29+
local_tool(
30+
name = "build_tar",
31+
)
32+
2933
local_tool(
3034
name = "xz",
3135
)
@@ -37,6 +41,7 @@ load(
3741

3842
docker_toolchain_configure(
3943
name = "docker_config",
44+
build_tar_target = "@build_tar//:build_tar",
4045
xz_target = "@xz//:xz",
4146
)
4247

toolchains/docker/BUILD.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl", "docker_toolchai
2121
docker_toolchain(
2222
name = "toolchain",
2323
client_config = "%{DOCKER_CONFIG}",
24+
%{BUILD_TAR_ATTR}
2425
%{GZIP_ATTR}
2526
%{TOOL_ATTR}
2627
docker_flags = ["%{DOCKER_FLAGS}"],

toolchains/docker/toolchain.bzl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This module defines docker toolchain rules
1818
DockerToolchainInfo = provider(
1919
doc = "Docker toolchain rule parameters",
2020
fields = {
21+
"build_tar_target": "Optional Bazel target for the build_tar tool",
2122
"client_config": "A custom directory for the docker client " +
2223
"config.json. If DOCKER_CONFIG is not specified, " +
2324
"the value of the DOCKER_CONFIG environment variable " +
@@ -41,6 +42,7 @@ DockerToolchainInfo = provider(
4142
def _docker_toolchain_impl(ctx):
4243
toolchain_info = platform_common.ToolchainInfo(
4344
info = DockerToolchainInfo(
45+
build_tar_target = ctx.attr.build_tar_target,
4446
docker_flags = ctx.attr.docker_flags,
4547
client_config = ctx.attr.client_config,
4648
gzip_path = ctx.attr.gzip_path,
@@ -58,6 +60,12 @@ def _docker_toolchain_impl(ctx):
5860
docker_toolchain = rule(
5961
implementation = _docker_toolchain_impl,
6062
attrs = {
63+
"build_tar_target": attr.label(
64+
allow_files = True,
65+
doc = "Bazel target for the build_tar tool.",
66+
cfg = "host",
67+
executable = True,
68+
),
6169
"client_config": attr.string(
6270
default = "",
6371
doc = "A custom directory for the docker client config.json. If " +
@@ -136,13 +144,18 @@ def _toolchain_configure_impl(repository_ctx):
136144
docker_flags = []
137145
docker_flags += repository_ctx.attr.docker_flags
138146

147+
build_tar_attr = ""
148+
if repository_ctx.attr.build_tar_target:
149+
build_tar_attr = "build_tar_target = \"%s\"," % repository_ctx.attr.build_tar_target
150+
139151
# If client_config is not set we need to pass an empty string to the
140152
# template.
141153
client_config = repository_ctx.attr.client_config or ""
142154
repository_ctx.template(
143155
"BUILD",
144156
Label("@io_bazel_rules_docker//toolchains/docker:BUILD.tpl"),
145157
{
158+
"%{BUILD_TAR_ATTR}": "%s" % build_tar_attr,
146159
"%{DOCKER_CONFIG}": "%s" % client_config,
147160
"%{DOCKER_FLAGS}": "%s" % "\", \"".join(docker_flags),
148161
"%{TOOL_ATTR}": "%s" % tool_attr,
@@ -167,6 +180,13 @@ def _toolchain_configure_impl(repository_ctx):
167180
# Repository rule to generate a docker_toolchain target
168181
toolchain_configure = repository_rule(
169182
attrs = {
183+
"build_tar_target": attr.label(
184+
executable = True,
185+
cfg = "host",
186+
allow_files = True,
187+
mandatory = False,
188+
doc = "The bazel target for the build_tar tool.",
189+
),
170190
"client_config": attr.string(
171191
mandatory = False,
172192
doc = "A custom directory for the docker client " +

0 commit comments

Comments
 (0)