Skip to content
This repository has been archived by the owner on Oct 2, 2023. It is now read-only.

Commit

Permalink
toolchain: allow to configure build_tar target (#1937)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dataoleg committed Dec 6, 2021
1 parent 029b9a1 commit 86c54e5
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl",
)
docker_toolchain_configure(
name = "docker_config",
# OPTIONAL: Bazel target for the build_tar tool, must be compatible with build_tar.py
build_tar_target="<enter absolute path (i.e., must start with repo name @...//:...) to an executable build_tar target>",
# OPTIONAL: Path to a directory which has a custom docker client config.json.
# See https://docs.docker.com/engine/reference/commandline/cli/#configuration-files
# for more details.
Expand Down
5 changes: 4 additions & 1 deletion container/layer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ def build_layer(
"""
toolchain_info = ctx.toolchains["@io_bazel_rules_docker//toolchains/docker:toolchain_type"].info
layer = output_layer
build_layer_exec = ctx.executable.build_layer
if toolchain_info.build_tar_target:
build_layer_exec = toolchain_info.build_tar_target.files_to_run.executable
else:
build_layer_exec = ctx.executable.build_layer
args = ctx.actions.args()
args.add(layer, format = "--output=%s")
args.add(directory, format = "--directory=%s")
Expand Down
5 changes: 5 additions & 0 deletions testing/default_toolchain/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ load(
"local_tool",
)

local_tool(
name = "build_tar",
)

local_tool(
name = "xz",
)
Expand All @@ -37,6 +41,7 @@ load(

docker_toolchain_configure(
name = "docker_config",
build_tar_target = "@build_tar//:build_tar",
xz_target = "@xz//:xz",
)

Expand Down
1 change: 1 addition & 0 deletions toolchains/docker/BUILD.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl", "docker_toolchai
docker_toolchain(
name = "toolchain",
client_config = "%{DOCKER_CONFIG}",
%{BUILD_TAR_ATTR}
%{GZIP_ATTR}
%{TOOL_ATTR}
docker_flags = ["%{DOCKER_FLAGS}"],
Expand Down
20 changes: 20 additions & 0 deletions toolchains/docker/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This module defines docker toolchain rules
DockerToolchainInfo = provider(
doc = "Docker toolchain rule parameters",
fields = {
"build_tar_target": "Optional Bazel target for the build_tar tool",
"client_config": "A custom directory for the docker client " +
"config.json. If DOCKER_CONFIG is not specified, " +
"the value of the DOCKER_CONFIG environment variable " +
Expand All @@ -41,6 +42,7 @@ DockerToolchainInfo = provider(
def _docker_toolchain_impl(ctx):
toolchain_info = platform_common.ToolchainInfo(
info = DockerToolchainInfo(
build_tar_target = ctx.attr.build_tar_target,
docker_flags = ctx.attr.docker_flags,
client_config = ctx.attr.client_config,
gzip_path = ctx.attr.gzip_path,
Expand All @@ -58,6 +60,12 @@ def _docker_toolchain_impl(ctx):
docker_toolchain = rule(
implementation = _docker_toolchain_impl,
attrs = {
"build_tar_target": attr.label(
allow_files = True,
doc = "Bazel target for the build_tar tool.",
cfg = "host",
executable = True,
),
"client_config": attr.string(
default = "",
doc = "A custom directory for the docker client config.json. If " +
Expand Down Expand Up @@ -136,13 +144,18 @@ def _toolchain_configure_impl(repository_ctx):
docker_flags = []
docker_flags += repository_ctx.attr.docker_flags

build_tar_attr = ""
if repository_ctx.attr.build_tar_target:
build_tar_attr = "build_tar_target = \"%s\"," % repository_ctx.attr.build_tar_target

# If client_config is not set we need to pass an empty string to the
# template.
client_config = repository_ctx.attr.client_config or ""
repository_ctx.template(
"BUILD",
Label("@io_bazel_rules_docker//toolchains/docker:BUILD.tpl"),
{
"%{BUILD_TAR_ATTR}": "%s" % build_tar_attr,
"%{DOCKER_CONFIG}": "%s" % client_config,
"%{DOCKER_FLAGS}": "%s" % "\", \"".join(docker_flags),
"%{TOOL_ATTR}": "%s" % tool_attr,
Expand All @@ -167,6 +180,13 @@ def _toolchain_configure_impl(repository_ctx):
# Repository rule to generate a docker_toolchain target
toolchain_configure = repository_rule(
attrs = {
"build_tar_target": attr.label(
executable = True,
cfg = "host",
allow_files = True,
mandatory = False,
doc = "The bazel target for the build_tar tool.",
),
"client_config": attr.string(
mandatory = False,
doc = "A custom directory for the docker client " +
Expand Down

0 comments on commit 86c54e5

Please sign in to comment.