Skip to content

Commit 7d34678

Browse files
authored
image.bzl: implement tag_name (#2205)
rules_docker decides the name of the resulting docker image: bazel/{target}:{name} The repository (`bazel/` by default) and `{target}` are fine. However, we want to customize the tag part -- the thing after the colon. This patch allows customizing the last part. Why? ==== In our case, we are always building two images for two architectures using transitions. Here is an extract of a macro that builds two containers: Then we build two containers using outgoing transitions: container_image( name = "{name}-post_transition".format(name = name), ..., ) multiplatform_image( name = "{name}-amd64".format(name), src_image = ":{name}-post_transition".format(name = name), ..., ) multiplatform_image( name = "{name}-arm64".format(name = name), src_image = ":{name}-post_transition".format(name = name), ..., ) Both images (`-amd64` and `-arm64`) build correctly, but the resulting image name, according to Docker, happens to be `bazel/{target}:{name}-post_transition`. So the internal implementation details of the transitions leak to the resulting images. This patch makes it possible to rename the post-transition image name to something we like more, e.g. the architecture name, or remove the suffix altogether.
1 parent 48ad6d6 commit 7d34678

File tree

5 files changed

+28
-5
lines changed

5 files changed

+28
-5
lines changed

container/image.bzl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@ def _impl(
288288
workdir = None,
289289
user = None,
290290
null_cmd = None,
291-
null_entrypoint = None):
291+
null_entrypoint = None,
292+
tag_name = None):
292293
"""Implementation for the container_image rule.
293294
294295
You can write a customized container_image rule by writing something like:
@@ -346,6 +347,7 @@ def _impl(
346347
user: str, overrides ctx.attr.user
347348
null_cmd: bool, overrides ctx.attr.null_cmd
348349
null_entrypoint: bool, overrides ctx.attr.null_entrypoint
350+
tag_name: str, overrides ctx.attr.tag_name
349351
"""
350352
name = name or ctx.label.name
351353
base = base or ctx.attr.base
@@ -367,6 +369,7 @@ def _impl(
367369
build_script = ctx.outputs.build_script
368370
null_cmd = null_cmd or ctx.attr.null_cmd
369371
null_entrypoint = null_entrypoint or ctx.attr.null_entrypoint
372+
tag_name = tag_name or ctx.attr.tag_name
370373

371374
# If this target specifies docker_run_flags, they are always used.
372375
# Fall back to the base image's run flags if present, otherwise use the default value.
@@ -459,8 +462,10 @@ def _impl(
459462
null_cmd = null_cmd,
460463
)
461464

462-
# Construct a temporary name based on the build target.
463-
tag_name = "{}:{}".format(_repository_name(ctx), name)
465+
# Construct a temporary name based on the build target. This is the name
466+
# of the docker container.
467+
final_tag = tag_name if tag_name else name
468+
container_name = "{}:{}".format(_repository_name(ctx), final_tag)
464469

465470
# These are the constituent parts of the Container image, which each
466471
# rule in the chain must preserve.
@@ -497,7 +502,7 @@ def _impl(
497502
# We support incrementally loading or assembling this single image
498503
# with a temporary name given by its build rule.
499504
images = {
500-
tag_name: container_parts,
505+
container_name: container_parts,
501506
}
502507

503508
_incr_load(
@@ -744,6 +749,9 @@ _attrs = dicts.add(_layer.attrs, {
744749
745750
This field supports stamp variables.""",
746751
),
752+
"tag_name": attr.string(
753+
doc = """Override final tag name. If unspecified, is set to name.""",
754+
),
747755
"_allowlist_function_transition": attr.label(
748756
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
749757
),

docs/container.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ image.implementation(<a href="#image.implementation-ctx">ctx</a>, <a href="#imag
404404
<a href="#image.implementation-compression_options">compression_options</a>, <a href="#image.implementation-experimental_tarball_format">experimental_tarball_format</a>, <a href="#image.implementation-debs">debs</a>, <a href="#image.implementation-tars">tars</a>, <a href="#image.implementation-architecture">architecture</a>,
405405
<a href="#image.implementation-operating_system">operating_system</a>, <a href="#image.implementation-os_version">os_version</a>, <a href="#image.implementation-output_executable">output_executable</a>, <a href="#image.implementation-output_tarball">output_tarball</a>, <a href="#image.implementation-output_config">output_config</a>,
406406
<a href="#image.implementation-output_config_digest">output_config_digest</a>, <a href="#image.implementation-output_digest">output_digest</a>, <a href="#image.implementation-output_layer">output_layer</a>, <a href="#image.implementation-workdir">workdir</a>, <a href="#image.implementation-user">user</a>, <a href="#image.implementation-null_cmd">null_cmd</a>,
407-
<a href="#image.implementation-null_entrypoint">null_entrypoint</a>)
407+
<a href="#image.implementation-null_entrypoint">null_entrypoint</a>, <a href="#image.implementation-tag_name">tag_name</a>)
408408
</pre>
409409

410410
Implementation for the container_image rule.
@@ -469,5 +469,6 @@ You can write a customized container_image rule by writing something like:
469469
| <a id="image.implementation-user"></a>user | str, overrides ctx.attr.user | <code>None</code> |
470470
| <a id="image.implementation-null_cmd"></a>null_cmd | bool, overrides ctx.attr.null_cmd | <code>None</code> |
471471
| <a id="image.implementation-null_entrypoint"></a>null_entrypoint | bool, overrides ctx.attr.null_entrypoint | <code>None</code> |
472+
| <a id="image.implementation-tag_name"></a>tag_name | str, overrides ctx.attr.tag_name | <code>None</code> |
472473

473474

testdata/BUILD

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ container_image(
9797
repository = "gcr.io/dummy",
9898
)
9999

100+
container_image(
101+
name = "tag_name",
102+
files = ["foo"],
103+
tag_name = "this-tag-instead",
104+
)
105+
100106
container_image(
101107
name = "no_data_path_image",
102108
files = ["//testdata/test:test-data"],

tests/container/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,7 @@ TEST_TARGETS = [
935935
":absolute_data_path_image",
936936
":root_data_path_image",
937937
":dummy_repository",
938+
":tag_name",
938939
# TODO(mattmoor): Re-enable once archive is visible
939940
# "extras_with_deb",
940941
":bundle_test",

tests/container/image_test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,13 @@ def test_dummy_repository(self):
301301
self.assertEqual(1, len(img.fs_layers()))
302302
self.assertTopLayerContains(img, ['.', './foo'])
303303

304+
def test_tag_name(self):
305+
# users may override the tag that comes after ':'
306+
name = 'bazel/%s:this-tag-instead' % TEST_DATA_TARGET_BASE
307+
with TestBundleImage('tag_name', name) as img:
308+
self.assertEqual(1, len(img.fs_layers()))
309+
self.assertTopLayerContains(img, ['.', './foo'])
310+
304311
def test_with_double_env(self):
305312
with TestImage('with_double_env') as img:
306313
self.assertEqual(3, len(img.fs_layers()))

0 commit comments

Comments
 (0)