diff --git a/container/image.bzl b/container/image.bzl index b40c07620..447b736eb 100644 --- a/container/image.bzl +++ b/container/image.bzl @@ -324,6 +324,7 @@ def _impl( executable = True, outputs = _container.image.outputs, implementation = _impl, + cfg = _container.image.cfg, ) Args: @@ -625,7 +626,7 @@ _attrs = dicts.add(_layer.attrs, { Acceptable formats: Integer or floating point seconds since Unix Epoch, RFC 3339 date/time. This field supports stamp variables. - + If not set, defaults to {BUILD_TIMESTAMP} when stamp = True, otherwise 0""", ), "docker_run_flags": attr.string( @@ -637,14 +638,14 @@ _attrs = dicts.add(_layer.attrs, { doc = """List of entrypoints to add in the image. See https://docs.docker.com/engine/reference/builder/#entrypoint - + Set `entrypoint` to `None`, `[]` or `""` will set the `Entrypoint` of the image to be `null`. The behavior between using `""` and `[]` may differ. Please see [#1448](https://github.com/bazelbuild/rules_docker/issues/1448) for more details. - + This field supports stamp variables.""", ), "experimental_tarball_format": attr.string( @@ -667,12 +668,12 @@ _attrs = dicts.add(_layer.attrs, { ), "labels": attr.string_dict( doc = """Dictionary from custom metadata names to their values. - + See https://docs.docker.com/engine/reference/builder/#label - + You can also put a file name prefixed by '@' as a value. Then the value is replaced with the contents of the file. - + Example: labels = { @@ -699,7 +700,7 @@ _attrs = dicts.add(_layer.attrs, { ), "layers": attr.label_list( doc = """List of `container_layer` targets. - + The data from each `container_layer` will be part of container image, and the environment variable will be available in the image as well.""", providers = [LayerInfo], @@ -731,7 +732,7 @@ _attrs = dicts.add(_layer.attrs, { # Starlark doesn't support int_list... "ports": attr.string_list( doc = """List of ports to expose. - + See https://docs.docker.com/engine/reference/builder/#expose""", ), "repository": attr.string( @@ -741,7 +742,7 @@ _attrs = dicts.add(_layer.attrs, { Images generated by `container_image` are tagged by default to `bazel/package_name:target` for a `container_image` target at `//package/name:target`. - + Setting this attribute to `gcr.io/dummy` would set the default tag to `gcr.io/dummy/package_name:target`.""", ), @@ -767,19 +768,22 @@ _attrs = dicts.add(_layer.attrs, { ), "volumes": attr.string_list( doc = """List of volumes to mount. - + See https://docs.docker.com/engine/reference/builder/#volumes""", ), "workdir": attr.string( doc = """Initial working directory when running the Docker image. See https://docs.docker.com/engine/reference/builder/#workdir - + Because building the image never happens inside a Docker container, this working directory does not affect the other actions (e.g., adding files). This field supports stamp variables.""", ), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), "_digester": attr.label( default = "//container/go/cmd/digester", cfg = "host", @@ -799,19 +803,43 @@ _outputs["config_digest"] = "%{name}.json.sha256" _outputs["build_script"] = "%{name}.executable" +def _image_transition_impl(settings, attr): + return dicts.add(settings, { + "//command_line_option:platforms": "@io_bazel_rules_docker//platforms:image_transition", + "@io_bazel_rules_docker//platforms:image_transition_cpu": "@platforms//cpu:" + { + # Architecture aliases. + "386": "x86_32", + "amd64": "x86_64", + "ppc64le": "ppc", + }.get(attr.architecture, attr.architecture), + "@io_bazel_rules_docker//platforms:image_transition_os": "@platforms//os:" + attr.operating_system, + }) + +_image_transition = transition( + implementation = _image_transition_impl, + inputs = [], + outputs = [ + "//command_line_option:platforms", + "@io_bazel_rules_docker//platforms:image_transition_cpu", + "@io_bazel_rules_docker//platforms:image_transition_os", + ], +) + image = struct( attrs = _attrs, outputs = _outputs, implementation = _impl, + cfg = _image_transition, ) container_image_ = rule( - attrs = _attrs, + attrs = image.attrs, doc = "Called by the `container_image` macro with **kwargs, see below", executable = True, - outputs = _outputs, + outputs = image.outputs, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], - implementation = _impl, + implementation = image.implementation, + cfg = image.cfg, ) # This validates the two forms of value accepted by diff --git a/container/layer.bzl b/container/layer.bzl index 38e978395..4ef6b2bb0 100644 --- a/container/layer.bzl +++ b/container/layer.bzl @@ -294,7 +294,7 @@ _layer_attrs = dicts.add({ "compression_options": attr.string_list(), "data_path": attr.string( doc = """Root path of the files. - + The directory structure from the files is preserved inside the Docker image, but a prefix path determined by `data_path` is removed from the directory structure. This path can @@ -307,7 +307,7 @@ _layer_attrs = dicts.add({ "debs": attr.label_list( allow_files = deb_filetype, doc = """Debian packages to extract. - + Deprecated: A list of debian packages that will be extracted in the Docker image. Note that this doesn't actually install the packages. Installation needs apt or apt-get which need to be executed within a running container which @@ -316,7 +316,7 @@ _layer_attrs = dicts.add({ "directory": attr.string( default = "/", doc = """Target directory. - + The directory in which to expand the specified files, defaulting to '/'. Only makes sense accompanying one of files/tars/debs.""", ), @@ -326,7 +326,7 @@ _layer_attrs = dicts.add({ "enable_mtime_preservation": attr.bool(default = False), "env": attr.string_dict( doc = """Dictionary from environment variable names to their values when running the Docker image. - + See https://docs.docker.com/engine/reference/builder/#env For example, @@ -334,8 +334,8 @@ _layer_attrs = dicts.add({ env = { "FOO": "bar", ... - }, - + }, + The values of this field support make variables (e.g., `$(FOO)`) and stamp variables; keys support make variables as well.""", ), @@ -357,9 +357,9 @@ _layer_attrs = dicts.add({ "portable_mtime": attr.bool(default = False), "symlinks": attr.string_dict( doc = """Symlinks to create in the Docker image. - + For example, - + symlinks = { "/path/to/link": "/path/to/target", ... @@ -369,7 +369,7 @@ _layer_attrs = dicts.add({ "tars": attr.label_list( allow_files = tar_filetype, doc = """Tar file to extract in the layer. - + A list of tar files whose content should be in the Docker image.""", ), }, _hash_tools, _layer_tools, _zip_tools) @@ -387,10 +387,10 @@ layer = struct( container_layer_ = rule( doc = _DOC, - attrs = _layer_attrs, + attrs = layer.attrs, executable = False, - outputs = _layer_outputs, - implementation = _impl, + outputs = layer.outputs, + implementation = layer.implementation, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], ) diff --git a/contrib/repro_test.bzl b/contrib/repro_test.bzl index d4e1d512c..82337c4fa 100644 --- a/contrib/repro_test.bzl +++ b/contrib/repro_test.bzl @@ -328,4 +328,5 @@ container_repro_test = rule( }), test = True, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], + cfg = _container.image.cfg, ) diff --git a/docker/package_managers/apt_key.bzl b/docker/package_managers/apt_key.bzl index 37595833f..8a7da87ab 100644 --- a/docker/package_managers/apt_key.bzl +++ b/docker/package_managers/apt_key.bzl @@ -155,12 +155,14 @@ key = struct( attrs = _attrs, outputs = _outputs, implementation = _impl, + cfg = _container.image.cfg, ) add_apt_key = rule( - attrs = _attrs, - outputs = _outputs, - implementation = _impl, + attrs = key.attrs, + outputs = key.outputs, + implementation = key.implementation, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], executable = True, + cfg = key.cfg, ) diff --git a/docker/toolchain_container/toolchain_container.bzl b/docker/toolchain_container/toolchain_container.bzl index f8347d315..d93baf5aa 100644 --- a/docker/toolchain_container/toolchain_container.bzl +++ b/docker/toolchain_container/toolchain_container.bzl @@ -243,6 +243,7 @@ language_tool_layer_ = rule( outputs = _container.image.outputs, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], implementation = _language_tool_layer_impl, + cfg = _container.image.cfg, ) def language_tool_layer(**kwargs): @@ -350,6 +351,7 @@ toolchain_container_ = rule( outputs = _container.image.outputs, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], implementation = _toolchain_container_impl, + cfg = _container.image.cfg, ) def toolchain_container(**kwargs): diff --git a/docs/container.md b/docs/container.md index ee339ba33..57610ead7 100644 --- a/docs/container.md +++ b/docs/container.md @@ -108,7 +108,7 @@ A rule that assembles data into a tarball which can be use as in layers attr in | empty_dirs | - | List of strings | optional | [] | | empty_files | - | List of strings | optional | [] | | enable_mtime_preservation | - | Boolean | optional | False | -| env | Dictionary from environment variable names to their values when running the Docker image.

See https://docs.docker.com/engine/reference/builder/#env

For example,

env = { "FOO": "bar", ... },

The values of this field support make variables (e.g., $(FOO)) and stamp variables; keys support make variables as well. | Dictionary: String -> String | optional | {} | +| env | Dictionary from environment variable names to their values when running the Docker image.

See https://docs.docker.com/engine/reference/builder/#env

For example,

env = { "FOO": "bar", ... },

The values of this field support make variables (e.g., $(FOO)) and stamp variables; keys support make variables as well. | Dictionary: String -> String | optional | {} | | extract_config | - | Label | optional | //container/go/cmd/extract_config:extract_config | | files | File to add to the layer.

A list of files that should be included in the Docker image. | List of labels | optional | [] | | incremental_load_template | - | Label | optional | //container:incremental_load_template | @@ -414,6 +414,7 @@ You can write a customized container_image rule by writing something like: executable = True, outputs = _container.image.outputs, implementation = _impl, + cfg = _container.image.cfg, ) diff --git a/java/image.bzl b/java/image.bzl index 87b220ae4..c7b5a1be3 100644 --- a/java/image.bzl +++ b/java/image.bzl @@ -163,6 +163,7 @@ jar_dep_layer = rule( outputs = lang_image.outputs, toolchains = lang_image.toolchains, implementation = _jar_dep_layer_impl, + cfg = lang_image.cfg, ) def _jar_app_layer_impl(ctx): @@ -255,6 +256,7 @@ jar_app_layer = rule( outputs = _container.image.outputs, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], implementation = _jar_app_layer_impl, + cfg = _container.image.cfg, ) def java_image( @@ -362,6 +364,7 @@ _war_dep_layer = rule( outputs = _container.image.outputs, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], implementation = _war_dep_layer_impl, + cfg = _container.image.cfg, ) def _war_app_layer_impl(ctx): @@ -400,6 +403,7 @@ _war_app_layer = rule( outputs = _container.image.outputs, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], implementation = _war_app_layer_impl, + cfg = _container.image.cfg, ) def war_image(name, base = None, deps = [], layers = [], **kwargs): diff --git a/lang/image.bzl b/lang/image.bzl index c2db8f495..216ed9306 100644 --- a/lang/image.bzl +++ b/lang/image.bzl @@ -272,6 +272,7 @@ image = struct( outputs = _container.image.outputs, toolchains = ["@io_bazel_rules_docker//toolchains/docker:toolchain_type"], implementation = _app_layer_impl, + cfg = _container.image.cfg, ) _app_layer = rule( @@ -280,6 +281,7 @@ _app_layer = rule( outputs = image.outputs, toolchains = image.toolchains, implementation = image.implementation, + cfg = image.cfg, ) # Convenience function that instantiates the _app_layer rule and returns diff --git a/nodejs/image.bzl b/nodejs/image.bzl index 7c7259651..88a1169d4 100644 --- a/nodejs/image.bzl +++ b/nodejs/image.bzl @@ -86,6 +86,7 @@ _dep_layer = rule( outputs = lang_image.outputs, toolchains = lang_image.toolchains, implementation = _dep_layer_impl, + cfg = lang_image.cfg, ) def _npm_deps_runfiles(dep): @@ -107,6 +108,7 @@ _npm_deps_layer = rule( outputs = lang_image.outputs, toolchains = lang_image.toolchains, implementation = _npm_deps_layer_impl, + cfg = lang_image.cfg, ) def nodejs_image( diff --git a/platforms/BUILD b/platforms/BUILD index 50b8593ed..9298bf8f1 100644 --- a/platforms/BUILD +++ b/platforms/BUILD @@ -56,3 +56,29 @@ platform( ], parents = ["@buildkite_config//config:platform"], ) + +_IMAGE_TRANSITION_CONSTRAINTS = [ + ("cpu", "@platforms//cpu"), + ("os", "@platforms//os"), +] + +[[ + # Use a constraint value which will never be valid to prevent + # accidentally leaving the associated constraint setting unset. + constraint_value( + name = "image_transition_{}_unset".format(name), + constraint_setting = constraint_setting, + ), + label_setting( + name = "image_transition_{}".format(name), + build_setting_default = ":image_transition_{}_unset".format(name), + ), +] for name, constraint_setting in _IMAGE_TRANSITION_CONSTRAINTS] + +platform( + name = "image_transition", + constraint_values = [ + ":image_transition_{}".format(name) + for name, _ in _IMAGE_TRANSITION_CONSTRAINTS + ], +)