From 4485b5c6497d15b3cdd6113f1c5f3a8fc54987a8 Mon Sep 17 00:00:00 2001 From: Jeff Grafton Date: Wed, 13 Feb 2019 16:42:38 -0800 Subject: [PATCH] Add lots of comments --- build/platforms.bzl | 48 +++++++++++++++++++++++++++++++++++ build/release-tars/BUILD | 54 ++++++++++++++++++++++------------------ build/root/BUILD.root | 10 ++++++++ 3 files changed, 88 insertions(+), 24 deletions(-) diff --git a/build/platforms.bzl b/build/platforms.bzl index b641cd0dd4..0a6c8e4fba 100644 --- a/build/platforms.bzl +++ b/build/platforms.bzl @@ -77,6 +77,8 @@ TEST_PLATFORMS = { ], } +# Helper which produces the ALL_PLATFORMS dictionary, composed of the union of +# CLIENT, NODE, SERVER, and TEST platforms def _all_platforms(): all_platforms = {} for platforms in [CLIENT_PLATFORMS, NODE_PLATFORMS, SERVER_PLATFORMS, TEST_PLATFORMS]: @@ -94,6 +96,11 @@ ALL_PLATFORMS = _all_platforms() def go_platform_constraint(os, arch): return "@io_bazel_rules_go//go/platform:%s_%s" % (os, arch) +# Helper to for_platforms which updates the select() dictionary. +# d is the dictionary being updated. +# value is the value to set for each item of platforms, which should +# be a single platform category dictionary (e.g. SERVER_PLATFORMS). +# only_os selects one of the OSes in platforms. def _update_dict_for_platform_category(d, value, platforms, only_os = None): if not value: return @@ -122,6 +129,47 @@ def _update_dict_for_platform_category(d, value, platforms, only_os = None): # Hopefully this is just a string d[constraint] = value.format(**fmt_args) +# for_platforms returns a dictionary to be used with select(). +# select() is used for configurable attributes (most attributes, notably +# excluding output filenames), and takes a dictionary mapping a condition +# to a value for that attribute. +# select() is described in more detail in the Bazel documentation: +# https://docs.bazel.build/versions/master/be/functions.html#select +# +# One notable condition is the target platform (os and arch). +# Kubernetes binaries generally target particular platform categories, +# such as client binaries like kubectl, or node binaries like kubelet. +# Additionally, some build artifacts need specific configurations such as +# the appropriate arch-specific base image. +# +# This macro produces a dictionary where each of the platform categories +# (client, node, server, test, all) is enumerated and filled in +# the the provided arguments as the values. +# +# For example, a filegroup might want to include one binary for all client +# platforms and another binary for server platforms. The client and server +# platform lists have some shared items but also some disjoint items. +# The client binary can be provided in for_client and the server binary provided +# in for_server; this macro will then return a select() dictionary that +# includes the appropriate binaries based on the configured platform. +# +# Another example selecting the appropriate base image for a docker container. +# One can use select(for_platforms(for_server="base-image-{ARCH}//image")) +# to have the appropriate arch-specific image selected. +# +# The for_platform arguments can be lists, dictionaries, or strings, but +# they should all be the same type for a given call. +# The tokens {OS} and {ARCH} will be substituted with the corresponding values, +# but if a dictionary is provided, only the dictionary values will be formatted. +# +# If default is provided, a default condition will be added with the provided +# value. +# only_os can be used to select a single OS from a platform category that lists +# multiple OSes. For example, it doesn't make sense to build debs or RPMs for +# anything besides Linux, so you might supply only_os="linux" for those rules. +# +# For a complete example, consult something like the release-tars target in +# build/release-tars/BUILD. def for_platforms( for_client = None, for_node = None, diff --git a/build/release-tars/BUILD b/build/release-tars/BUILD index 249e02ea5f..7e1599ea97 100644 --- a/build/release-tars/BUILD +++ b/build/release-tars/BUILD @@ -12,6 +12,36 @@ load( load("@io_k8s_repo_infra//defs:build.bzl", "release_filegroup") load("@io_k8s_repo_infra//defs:pkg.bzl", "pkg_tar") +# Bazel doesn't make the output filename +# (such as kubernetes-server-{OS}-{ARCH}.tar.gz) configurable, so we instead +# create rules for all platforms and tag them manual. +# We then select the correct set of platform-specific tarballs in this filegroup +# using a select() statement. +# Thus the release-tars target always selects the correct set of tarballs +# for the configured platform being built. +release_filegroup( + name = "release-tars", + conditioned_srcs = for_platforms( + for_all = [ + ":kubernetes.tar.gz", + ":kubernetes-src.tar.gz", + ], + for_client = [":kubernetes-client-{OS}-{ARCH}.tar.gz"], + for_node = [":kubernetes-node-{OS}-{ARCH}.tar.gz"], + for_server = [ + ":kubernetes-server-{OS}-{ARCH}.tar.gz", + ":kubernetes-manifests.tar.gz", + ], + for_test = [ + ":kubernetes-test-portable.tar.gz", + ":kubernetes-test-{OS}-{ARCH}.tar.gz", + # TODO(ixdy): remove once the "mondo-test" tarball is deprecated. + # It isn't really mondo under Bazel anyway. + ":kubernetes-test.tar.gz", + ], + ), +) + filegroup( name = "package-srcs", srcs = glob(["**"]), @@ -267,7 +297,6 @@ pkg_tar( "manual", "no-cache", ], - tags = ["no-cache"], deps = select({go_platform_constraint(os, arch): [":_test-bin"]}), ) for arch in archs] for os, archs in TEST_PLATFORMS.items()] @@ -311,26 +340,3 @@ pkg_tar( "//cluster:manifests", ], ) - -release_filegroup( - name = "release-tars", - srcs = [ - ":kubernetes.tar.gz", - ":kubernetes-src.tar.gz", - ], - conditioned_srcs = for_platforms( - for_all = [ - ], - for_client = [":kubernetes-client-{OS}-{ARCH}.tar.gz"], - for_node = [":kubernetes-node-{OS}-{ARCH}.tar.gz"], - for_server = [ - ":kubernetes-server-{OS}-{ARCH}.tar.gz", - ":kubernetes-manifests.tar.gz", - ], - for_test = [ - ":kubernetes-test-portable.tar.gz", - ":kubernetes-test-{OS}-{ARCH}.tar.gz", - ":kubernetes-test.tar.gz", # FIXME - ], - ), -) diff --git a/build/root/BUILD.root b/build/root/BUILD.root index b0472b7678..66778a602b 100644 --- a/build/root/BUILD.root +++ b/build/root/BUILD.root @@ -40,6 +40,16 @@ gcs_upload( "//cluster/gce/gci:gcs-release-artifacts-and-hashes", ], tags = ["manual"], + # Use for_platforms to format the upload path based on the configured + # platform (os/arch). + # For example, this will turn into something like + # upload_paths = select({ + # "@io_bazel_rules_go//go/platform:windows_386": { + # ...,"//:binary-artifacts-and-hashes": "bin/windows/386"}, + # "@io_bazel_rules_go//go/platform:linux_ppc64le": { + # ...,"//:binary-artifacts-and-hashes": "bin/linux/ppc64le"}, + #}) + # and bazel will select the correct entry. upload_paths = select(for_platforms(for_all = { "//build/release-tars:release-tars-and-hashes": "", "//cluster/gce/gci:gcs-release-artifacts-and-hashes": "extra/gce",