Installing kubernetes-cli via Homebrew on Apple Silicon

One of the final pieces of software I still hadn't been able to install on my new MacBook Pro M1 was kubectl also known as kubernetes-cli. Today I came across this issue on GitHub in which someone noted the architecture is just missing from one of the files and adding it in allows it to build properly. Using my limited knowledge of how Homebrew formula work, I was able to get it working.

First edit the formula for kubernetes-cli:

brew edit kubernetes-cli

Then at about line 25 add patch :DATA so it looks like:

  uses_from_macos "rsync" => :build

  patch :DATA

  def install
    # Don't dirty the git tree
    rm_rf ".brew_home"

Then go to the bottom of the file and add:

__END__
index bef1d837..154eecfd 100755
--- a/hack/lib/golang.sh
+++ b/hack/lib/golang.sh
@@ -49,6 +49,7 @@ readonly KUBE_SUPPORTED_CLIENT_PLATFORMS=(
   linux/s390x
   linux/ppc64le
   darwin/amd64
+  darwin/arm64
   windows/amd64
   windows/386
 )

Save and exit the file. The full file looks like this:

class KubernetesCli < Formula
  desc "Kubernetes command-line interface"
  homepage "https://kubernetes.io/"
  url "https://github.com/kubernetes/kubernetes.git",
      tag:      "v1.20.1",
      revision: "c4d752765b3bbac2237bf87cf0b1c2e307844666"
  license "Apache-2.0"
  head "https://github.com/kubernetes/kubernetes.git"

  livecheck do
    url :head
    regex(/^v([\d.]+)$/i)
  end

  bottle do
    cellar :any_skip_relocation
    sha256 "0b4f08bd1d47cb913d7cd4571e3394c6747dfbad7ff114c5589c8396c1085ecf" => :big_sur
    sha256 "f49639875a924ccbb15b5f36aa2ef48a2ed94ee67f72e7bd6fed22ae1186f977" => :catalina
    sha256 "4a3eaef3932d86024175fd6c53d3664e6674c3c93b1d4ceedd734366cce8e503" => :mojave
  end

  depends_on "go" => :build

  uses_from_macos "rsync" => :build
  patch :DATA
  def install
    # Don't dirty the git tree
    rm_rf ".brew_home"

    # Make binary
    system "make", "WHAT=cmd/kubectl"
    bin.install "_output/bin/kubectl"

    # Install bash completion
    output = Utils.safe_popen_read("#{bin}/kubectl", "completion", "bash")
    (bash_completion/"kubectl").write output

    # Install zsh completion
    output = Utils.safe_popen_read("#{bin}/kubectl", "completion", "zsh")
    (zsh_completion/"_kubectl").write output

    # Install man pages
    # Leave this step for the end as this dirties the git tree
    system "hack/generate-docs.sh"
    man1.install Dir["docs/man/man1/*.1"]
  end

  test do
    run_output = shell_output("#{bin}/kubectl 2>&1")
    assert_match "kubectl controls the Kubernetes cluster manager.", run_output

    version_output = shell_output("#{bin}/kubectl version --client 2>&1")
    assert_match "GitTreeState:\"clean\"", version_output
    if build.stable?
      assert_match stable.instance_variable_get(:@resource)
                         .instance_variable_get(:@specs)[:revision],
                   version_output
    end
  end
end
__END__
index bef1d837..154eecfd 100755
--- a/hack/lib/golang.sh
+++ b/hack/lib/golang.sh
@@ -49,6 +49,7 @@ readonly KUBE_SUPPORTED_CLIENT_PLATFORMS=(
   linux/s390x
   linux/ppc64le
   darwin/amd64
+  darwin/arm64
   windows/amd64
   windows/386
 )

Run this command to install kubernetes-cli:

brew install --build-from-source kubernetes-cli

Once completed you should be able to run the following command to get the version:

kubectl version
Client Version: version.Info{Major:"1", Minor:"20+", GitVersion:"v1.20.1-dirty", GitCommit:"c4d752765b3bbac2237bf87cf0b1c2e307844666", GitTreeState:"dirty", BuildDate:"2021-01-04T16:45:01Z", GoVersion:"go1.16beta1", Compiler:"gc", Platform:"darwin/arm64"}

You may get some further output about there being a connection issue, but that's okay if you haven't setup your Kubernetes configuration file yet.