Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Enable building kubectl hermetically as part of toolchain setup #229

Merged
merged 13 commits into from
Nov 21, 2018
10 changes: 6 additions & 4 deletions k8s/k8s.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ py_library(
strip_prefix = "PyYAML-3.12/lib/yaml",
)

# Register the default kubectl toolchain that expects the 'kubectl'
# executable to be in the PATH
# Register the default kubectl toolchain targets for supported platforms
# note these work with the autoconfigured toolchain
native.register_toolchains(
"@io_bazel_rules_k8s//toolchains/kubectl:kubectl_linux_toolchain",
"@io_bazel_rules_k8s//toolchains/kubectl:kubectl_osx_toolchain",
"@io_bazel_rules_k8s//toolchains/kubectl:kubectl_windows_toolchain",
)

# WORKSPACE target to configure the kubectl tool
kubectl_configure(name = "local_k8s_config")
excludes = native.existing_rules().keys()
if "k8s_config" not in excludes:
# WORKSPACE target to configure the kubectl tool
kubectl_configure(name = "k8s_config", build_srcs = True)
6 changes: 5 additions & 1 deletion k8s/object.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,13 @@ def _common_impl(ctx):
namespace_arg = "--namespace=\"" + namespace_arg + "\""

kubectl_tool_info = ctx.toolchains["@io_bazel_rules_k8s//toolchains/kubectl:toolchain_type"].kubectlinfo
nlopezgi marked this conversation as resolved.
Show resolved Hide resolved
kubectl_tool = kubectl_tool_info.tool_path
if not kubectl_tool_info.tool_path:
kubectl_tool = _runfiles(ctx, kubectl_tool_info.tool_target.files.to_list()[0])
files += kubectl_tool_info.tool_target.files.to_list()

substitutions = {
"%{kubectl_tool}": kubectl_tool_info.tool_path,
"%{kubectl_tool}": kubectl_tool,
"%{cluster}": cluster_arg,
"%{context}": context_arg,
"%{user}": user_arg,
Expand Down
6 changes: 3 additions & 3 deletions toolchains/kubectl/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ toolchain(
"@bazel_tools//platforms:linux",
"@bazel_tools//platforms:x86_64",
],
toolchain = "@local_k8s_config//:toolchain",
toolchain = "@k8s_config//:toolchain",
toolchain_type = ":toolchain_type",
)

Expand All @@ -42,7 +42,7 @@ toolchain(
"@bazel_tools//platforms:osx",
"@bazel_tools//platforms:x86_64",
],
toolchain = "@local_k8s_config//:toolchain",
toolchain = "@k8s_config//:toolchain",
toolchain_type = ":toolchain_type",
)

Expand All @@ -52,6 +52,6 @@ toolchain(
"@bazel_tools//platforms:windows",
"@bazel_tools//platforms:x86_64",
],
toolchain = "@local_k8s_config//:toolchain",
toolchain = "@k8s_config//:toolchain",
toolchain_type = ":toolchain_type",
)
25 changes: 25 additions & 0 deletions toolchains/kubectl/BUILD.target.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This BUILD file is auto-generated from toolchains/kubectl/BUILD.tpl
"""

package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_k8s//toolchains/kubectl:kubectl_toolchain.bzl", "kubectl_toolchain")

kubectl_toolchain(
name = "toolchain",
tool_target = "%{KUBECTL_TARGET}",
)
75 changes: 69 additions & 6 deletions toolchains/kubectl/kubectl_configure.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,79 @@ Defines a repository rule for configuring the kubectl tool.
"""

def _impl(repository_ctx):

kubectl_tool_path = repository_ctx.which("kubectl")
substitutions = None
label = None
if repository_ctx.attr.build_srcs:
kubectl_target = "@io_kubernetes//cmd/kubectl:kubectl"
substitutions = {"%{KUBECTL_TARGET}": "%s" % kubectl_target}
template = Label("@io_bazel_rules_k8s//toolchains/kubectl:BUILD.target.tpl")
else:
kubectl_tool_path = repository_ctx.which("kubectl")
substitutions = {"%{KUBECTL_TOOL}": "%s" % kubectl_tool_path}
template = Label("@io_bazel_rules_k8s//toolchains/kubectl:BUILD.path.tpl")

repository_ctx.template(
"BUILD",
Label("@io_bazel_rules_k8s//toolchains/kubectl:BUILD.tpl"),
{"%{KUBECTL_TOOL}": "%s" % kubectl_tool_path},
False
template,
substitutions,
False,
)

kubectl_configure = repository_rule(
_kubectl_configure = repository_rule(
implementation = _impl,
attrs = {
"build_srcs": attr.bool(
doc = "Optional. Set to true to build kubectl from sources.",
default = False,
mandatory = False,
),
},
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

def kubectl_configure(name, **kwargs):
"""
Creates an external repository with a kubectl_toolchain target
properly configured.

Args:
**kwargs:
Required Args
name: A unique name for this rule.
Default Args:
build_srcs: Optional. Set to true to build kubectl from sources. Default: False
k8s_commit: Otional. Commit / release tag at which to build kubectl
from. Default "v1.13.0-beta.1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need an issue to update this when 1.13 is out.

Also we need docs that only = or gt 1.13 is supported

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do docs in upcoming PR to avoid re-triggering CI.

k8s_sha256: Otional. sha256 of commit at which to build kubectl from.
Default <valid sha for default version>.
k8s_prefix: Otional. Prefix to strip from commit / release archive.
Typically the same as the commit, or Kubernetes-<release tag>.
Default <valid prefix for default version>.
Note: Not all versions/commits of kubernetes project can be used to compile
kubectl from an external repo. Notably, we have only tested with v1.13.0-beta.1
or above. Note this rule has a hardcoded pointer to io_kubernetes_build repo
if your commit (above v1.13.0-beta.1) does not work due to problems,
related to @io_kubernetes_build repo, please send a PR to update these values.
"""
build_srcs = False
if "build_srcs" in kwargs and kwargs["build_srcs"]:
build_srcs = True

# We keep these defaults here as they are only used by in this macro and not by the repo rule.
k8s_commit = kwargs["k8s_commit"] if "k8s_commit" in kwargs else "v1.13.0-beta.1"
k8s_sha256 = kwargs["k8s_sha256"] if "k8s_sha256" in kwargs else "dfb39ce36284c1ce228954ca12bf016c09be61e40a875e8af4fff84e116bd3a7"
k8s_prefix = kwargs["k8s_prefix"] if "k8s_prefix" in kwargs else "kubernetes-1.13.0-beta.1"
http_archive(
name = "io_kubernetes",
sha256 = k8s_sha256,
strip_prefix = k8s_prefix,
urls = [("https://github.com/kubernetes/kubernetes/archive/%s.tar.gz" % k8s_commit)],
)
http_archive(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this?

Copy link
Contributor Author

@nlopezgi nlopezgi Nov 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this is what Jeff Grafton was referring to as problematic with the kubernetes repo and which would be solved by the abandoned cl (kubernetes/kubernetes#71290 (comment))

name = "io_kubernetes_build",
sha256 = "21160531ea8a9a4001610223ad815622bf60671d308988c7057168a495a7e2e8",
strip_prefix = "repo-infra-b4bc4f1552c7fc1d4654753ca9b0e5e13883429f",
urls = ["https://github.com/kubernetes/repo-infra/archive/b4bc4f1552c7fc1d4654753ca9b0e5e13883429f.tar.gz"],
)
_kubectl_configure(name = name, build_srcs = build_srcs)
13 changes: 12 additions & 1 deletion toolchains/kubectl/kubectl_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,31 @@ KubectlInfo = provider(
doc = "Information about how to invoke the kubectl tool.",
fields = {
"tool_path": "Path to the kubectl executable",
"tool_target": "Target to build kubectl executable",
},
)

def _kubectl_toolchain_impl(ctx):
if not ctx.attr.tool_path and not ctx.attr.tool_target:
fail("Invalid kubectl_toolchain. kubectl_toolchain must have either tool_path or tool_target.")
toolchain_info = platform_common.ToolchainInfo(
kubectlinfo = KubectlInfo(
tool_path = ctx.attr.tool_path,
tool_target = ctx.attr.tool_target,
),
)
return [toolchain_info]

kubectl_toolchain = rule(
implementation = _kubectl_toolchain_impl,
attrs = {
"tool_path": attr.string(),
"tool_path": attr.string(
doc = "Absolute path to a pre-installed kubectl binary.",
mandatory = False,
),
"tool_target": attr.label(
doc = "Target to build kubectl from source.",
mandatory = False,
),
},
)