Added kube-controlplane binary

This adds a custom binary which contains all Kubernetes control plane
components. This is necessary since every control plane binary by itself
is around 130MiB and this combined one is only around 150MiB. This
can be cut in half to around 70MiB as soon as Kubernetes can be built
providerless by Bazel.

I'm not entirely happy with the integration, we may need gazelle
exclusions and a plan to deal with go mod since it can't resolve the
dependencies in a reasonable way.

Test Plan: Manual test with kubectl (this by itself is not runnable)

Bug: T485

X-Origin-Diff: phab/D256
GitOrigin-RevId: d76702f2cd0d71463ff891e5a44eac7b66be07f0
diff --git a/core/cmd/kube-controlplane/main.go b/core/cmd/kube-controlplane/main.go
new file mode 100644
index 0000000..aad7f04
--- /dev/null
+++ b/core/cmd/kube-controlplane/main.go
@@ -0,0 +1,121 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// 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.
+
+//+build ignore
+
+/*
+Copyright 2014 The Kubernetes Authors.
+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.
+*/
+
+// Adapted from https://github.com/dims/hyperkube
+
+package main
+
+import (
+	goflag "flag"
+	"math/rand"
+	"os"
+	"path/filepath"
+	"time"
+
+	"github.com/spf13/cobra"
+	"github.com/spf13/pflag"
+
+	cliflag "k8s.io/component-base/cli/flag"
+	"k8s.io/component-base/logs"
+	kubeapiserver "k8s.io/kubernetes/cmd/kube-apiserver/app"
+	kubecontrollermanager "k8s.io/kubernetes/cmd/kube-controller-manager/app"
+	kubescheduler "k8s.io/kubernetes/cmd/kube-scheduler/app"
+	_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
+	_ "k8s.io/kubernetes/pkg/version/prometheus"        // for version metric registration
+)
+
+func main() {
+	rand.Seed(time.Now().UnixNano())
+
+	hyperkubeCommand, allCommandFns := NewHyperKubeCommand()
+
+	// TODO: once we switch everything over to Cobra commands, we can go back to calling
+	// cliflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the
+	// normalize func and add the go flag set by hand.
+	pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
+	pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
+	// cliflag.InitFlags()
+	logs.InitLogs()
+	defer logs.FlushLogs()
+
+	basename := filepath.Base(os.Args[0])
+	if err := commandFor(basename, hyperkubeCommand, allCommandFns).Execute(); err != nil {
+		os.Exit(1)
+	}
+}
+
+func commandFor(basename string, defaultCommand *cobra.Command, commands []func() *cobra.Command) *cobra.Command {
+	for _, commandFn := range commands {
+		command := commandFn()
+		if command.Name() == basename {
+			return command
+		}
+		for _, alias := range command.Aliases {
+			if alias == basename {
+				return command
+			}
+		}
+	}
+
+	return defaultCommand
+}
+
+// NewHyperKubeCommand is the entry point for hyperkube
+func NewHyperKubeCommand() (*cobra.Command, []func() *cobra.Command) {
+	// these have to be functions since the command is polymorphic. Cobra wants you to be top level
+	// command to get executed
+	apiserver := func() *cobra.Command { return kubeapiserver.NewAPIServerCommand() }
+	controller := func() *cobra.Command { return kubecontrollermanager.NewControllerManagerCommand() }
+	scheduler := func() *cobra.Command { return kubescheduler.NewSchedulerCommand() }
+
+	commandFns := []func() *cobra.Command{
+		apiserver,
+		controller,
+		scheduler,
+	}
+
+	cmd := &cobra.Command{
+		Use:   "kube-controlplane",
+		Short: "Combines all Kubernetes Control Plane components in a single binary",
+		Run: func(cmd *cobra.Command, args []string) {
+			if len(args) != 0 {
+				cmd.Help()
+				os.Exit(1)
+			}
+		},
+	}
+
+	for i := range commandFns {
+		cmd.AddCommand(commandFns[i]())
+	}
+
+	return cmd, commandFns
+}