From f2894576c137ab1a1fd898258dc84a16825673a6 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 7 Feb 2015 20:35:02 -0800 Subject: [PATCH] get rid of pkg/hyperkube --- cmd/hyperkube/hyperkube.go | 185 +++++++++++++++++++-- {pkg => cmd}/hyperkube/hyperkube_test.go | 2 +- cmd/hyperkube/kube-apiserver.go | 7 +- cmd/hyperkube/kube-controller-manager.go | 7 +- cmd/hyperkube/kube-proxy.go | 7 +- cmd/hyperkube/kube-scheduler.go | 7 +- cmd/hyperkube/kubelet.go | 7 +- cmd/hyperkube/main.go | 38 +++++ {pkg => cmd}/hyperkube/server.go | 2 +- pkg/hyperkube/hyperkube.go | 202 ----------------------- 10 files changed, 227 insertions(+), 237 deletions(-) rename {pkg => cmd}/hyperkube/hyperkube_test.go (99%) create mode 100644 cmd/hyperkube/main.go rename {pkg => cmd}/hyperkube/server.go (99%) delete mode 100644 pkg/hyperkube/hyperkube.go diff --git a/cmd/hyperkube/hyperkube.go b/cmd/hyperkube/hyperkube.go index b8ed0ab46fe..d8499e5990b 100644 --- a/cmd/hyperkube/hyperkube.go +++ b/cmd/hyperkube/hyperkube.go @@ -14,27 +14,186 @@ See the License for the specific language governing permissions and limitations under the License. */ -// A binary that can morph into all of the other kubernetes binaries. You can -// also soft-link to it busybox style. package main import ( + "errors" + "flag" + "fmt" + "io" + "io/ioutil" "os" + "path" - "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag" + + "github.com/spf13/pflag" ) -func main() { - hk := hyperkube.HyperKube{ - Name: "hyperkube", - Long: "This is an all-in-one binary that can run any of the various Kubernetes servers.", +// HyperKube represents a single binary that can morph/manage into multiple +// servers. +type HyperKube struct { + Name string // The executable name, used for help and soft-link invocation + Long string // A long description of the binary. It will be world wrapped before output. + + servers []Server + baseFlags *pflag.FlagSet + out io.Writer + helpFlagVal bool +} + +// AddServer adds a server to the HyperKube object. +func (hk *HyperKube) AddServer(s *Server) { + hk.servers = append(hk.servers, *s) + hk.servers[len(hk.servers)-1].hk = hk +} + +// FindServer will find a specific server named name. +func (hk *HyperKube) FindServer(name string) (*Server, error) { + for _, s := range hk.servers { + if s.Name() == name { + return &s, nil + } + } + return nil, fmt.Errorf("Server not found: %s", name) +} + +// Servers returns a list of all of the registred servers +func (hk *HyperKube) Servers() []Server { + return hk.servers +} + +// Flags returns a flagset for "global" flags. +func (hk *HyperKube) Flags() *pflag.FlagSet { + if hk.baseFlags == nil { + hk.baseFlags = pflag.NewFlagSet(hk.Name, pflag.ContinueOnError) + hk.baseFlags.SetOutput(ioutil.Discard) + hk.baseFlags.BoolVarP(&hk.helpFlagVal, "help", "h", false, "help for "+hk.Name) + + // These will add all of the "global" flags (defined with both the + // flag and pflag packages) to the new flag set we have. + util.AddFlagSetToPFlagSet(flag.CommandLine, hk.baseFlags) + util.AddPFlagSetToPFlagSet(pflag.CommandLine, hk.baseFlags) + + } + return hk.baseFlags +} + +// Out returns the io.Writer that is used for all usage/error information +func (hk *HyperKube) Out() io.Writer { + if hk.out == nil { + hk.out = os.Stderr + } + return hk.out +} + +// SetOut sets the output writer for all usage/error information +func (hk *HyperKube) SetOut(w io.Writer) { + hk.out = w +} + +// Print is a convenience method to Print to the defined output +func (hk *HyperKube) Print(i ...interface{}) { + fmt.Fprint(hk.Out(), i...) +} + +// Println is a convenience method to Println to the defined output +func (hk *HyperKube) Println(i ...interface{}) { + fmt.Fprintln(hk.Out(), i...) +} + +// Printf is a convenience method to Printf to the defined output +func (hk *HyperKube) Printf(format string, i ...interface{}) { + fmt.Fprintf(hk.Out(), format, i...) +} + +// Run the server. This will pick the appropriate server and run it. +func (hk *HyperKube) Run(args []string) error { + // If we are called directly, parse all flags up to the first real + // argument. That should be the server to run. + baseCommand := path.Base(args[0]) + serverName := baseCommand + if serverName == hk.Name { + args = args[1:] + + baseFlags := hk.Flags() + baseFlags.SetInterspersed(false) // Only parse flags up to the next real command + err := baseFlags.Parse(args) + if err != nil || hk.helpFlagVal { + if err != nil { + hk.Println("Error:", err) + } + hk.Usage() + return err + } + + verflag.PrintAndExitIfRequested() + + args = baseFlags.Args() + if len(args) > 0 && len(args[0]) > 0 { + serverName = args[0] + baseCommand = baseCommand + " " + serverName + args = args[1:] + } else { + err = errors.New("No server specified") + hk.Printf("Error: %v\n\n", err) + hk.Usage() + return err + } } - hk.AddServer(NewKubeAPIServer()) - hk.AddServer(NewKubeControllerManager()) - hk.AddServer(NewScheduler()) - hk.AddServer(NewKubelet()) - hk.AddServer(NewKubeProxy()) + s, err := hk.FindServer(serverName) + if err != nil { + hk.Printf("Error: %v\n\n", err) + hk.Usage() + return err + } - hk.RunToExit(os.Args) + util.AddPFlagSetToPFlagSet(hk.Flags(), s.Flags()) + err = s.Flags().Parse(args) + if err != nil || hk.helpFlagVal { + if err != nil { + hk.Printf("Error: %v\n\n", err) + } + s.Usage() + return err + } + + verflag.PrintAndExitIfRequested() + + util.InitLogs() + defer util.FlushLogs() + + err = s.Run(s, s.Flags().Args()) + if err != nil { + hk.Println("Error:", err) + } + + return err +} + +// RunToExit will run the hyperkube and then call os.Exit with an appropriate exit code. +func (hk *HyperKube) RunToExit(args []string) { + err := hk.Run(args) + if err != nil { + os.Exit(1) + } + os.Exit(0) +} + +// Usage will write out a summary for all servers that this binary supports. +func (hk *HyperKube) Usage() { + tt := `{{if .Long}}{{.Long | trim | wrap ""}} +{{end}}Usage + + {{.Name}} [flags] + +Servers +{{range .Servers}} + {{.Name}} +{{.Long | trim | wrap " "}}{{end}} +Call '{{.Name}} --help' for help on a specific server. +` + util.ExecuteTemplate(hk.Out(), tt, hk) } diff --git a/pkg/hyperkube/hyperkube_test.go b/cmd/hyperkube/hyperkube_test.go similarity index 99% rename from pkg/hyperkube/hyperkube_test.go rename to cmd/hyperkube/hyperkube_test.go index c88336c0537..ccd83217c9b 100644 --- a/pkg/hyperkube/hyperkube_test.go +++ b/cmd/hyperkube/hyperkube_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package hyperkube +package main import ( "bytes" diff --git a/cmd/hyperkube/kube-apiserver.go b/cmd/hyperkube/kube-apiserver.go index 666db8f8ec4..0d8ee9ac530 100644 --- a/cmd/hyperkube/kube-apiserver.go +++ b/cmd/hyperkube/kube-apiserver.go @@ -18,18 +18,17 @@ package main import ( kubeapiserver "github.com/GoogleCloudPlatform/kubernetes/cmd/kube-apiserver/app" - "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" ) // NewKubeAPIServer creates a new hyperkube Server object that includes the // description and flags. -func NewKubeAPIServer() *hyperkube.Server { +func NewKubeAPIServer() *Server { s := kubeapiserver.NewAPIServer() - hks := hyperkube.Server{ + hks := Server{ SimpleUsage: "apiserver", Long: "The main API entrypoint and interface to the storage system. The API server is also the focal point for all authorization decisions.", - Run: func(_ *hyperkube.Server, args []string) error { + Run: func(_ *Server, args []string) error { return s.Run(args) }, } diff --git a/cmd/hyperkube/kube-controller-manager.go b/cmd/hyperkube/kube-controller-manager.go index c59928687e9..b501c3d5de2 100644 --- a/cmd/hyperkube/kube-controller-manager.go +++ b/cmd/hyperkube/kube-controller-manager.go @@ -18,18 +18,17 @@ package main import ( controllermgr "github.com/GoogleCloudPlatform/kubernetes/cmd/kube-controller-manager/app" - "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" ) // NewKubeControllerManager creates a new hyperkube Server object that includes the // description and flags. -func NewKubeControllerManager() *hyperkube.Server { +func NewKubeControllerManager() *Server { s := controllermgr.NewCMServer() - hks := hyperkube.Server{ + hks := Server{ SimpleUsage: "controller-manager", Long: "A server that runs a set of active components. This includes replication controllers, service endpoints and nodes.", - Run: func(_ *hyperkube.Server, args []string) error { + Run: func(_ *Server, args []string) error { return s.Run(args) }, } diff --git a/cmd/hyperkube/kube-proxy.go b/cmd/hyperkube/kube-proxy.go index 088f25368b8..4e3daf609d9 100644 --- a/cmd/hyperkube/kube-proxy.go +++ b/cmd/hyperkube/kube-proxy.go @@ -18,21 +18,20 @@ package main import ( kubeproxy "github.com/GoogleCloudPlatform/kubernetes/cmd/kube-proxy/app" - "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" ) // NewKubeProxy creates a new hyperkube Server object that includes the // description and flags. -func NewKubeProxy() *hyperkube.Server { +func NewKubeProxy() *Server { s := kubeproxy.NewProxyServer() - hks := hyperkube.Server{ + hks := Server{ SimpleUsage: "proxy", Long: `The Kubernetes proxy server is responsible for taking traffic directed at services and forwarding it to the appropriate pods. It generally runs on nodes next to the Kubelet and proxies traffic from local pods to remote pods. It is also used when handling incoming external traffic.`, - Run: func(_ *hyperkube.Server, args []string) error { + Run: func(_ *Server, args []string) error { return s.Run(args) }, } diff --git a/cmd/hyperkube/kube-scheduler.go b/cmd/hyperkube/kube-scheduler.go index 3bf4f491809..cff643fc65e 100644 --- a/cmd/hyperkube/kube-scheduler.go +++ b/cmd/hyperkube/kube-scheduler.go @@ -17,19 +17,18 @@ limitations under the License. package main import ( - "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" scheduler "github.com/GoogleCloudPlatform/kubernetes/plugin/cmd/kube-scheduler/app" ) // NewScheduler creates a new hyperkube Server object that includes the // description and flags. -func NewScheduler() *hyperkube.Server { +func NewScheduler() *Server { s := scheduler.NewSchedulerServer() - hks := hyperkube.Server{ + hks := Server{ SimpleUsage: "scheduler", Long: "Implements a Kubernetes scheduler. This will assign pods to kubelets based on capacity and constraints.", - Run: func(_ *hyperkube.Server, args []string) error { + Run: func(_ *Server, args []string) error { return s.Run(args) }, } diff --git a/cmd/hyperkube/kubelet.go b/cmd/hyperkube/kubelet.go index 13c2c062a71..b9c404f1988 100644 --- a/cmd/hyperkube/kubelet.go +++ b/cmd/hyperkube/kubelet.go @@ -18,14 +18,13 @@ package main import ( kubelet "github.com/GoogleCloudPlatform/kubernetes/cmd/kubelet/app" - "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" ) // NewKubelet creates a new hyperkube Server object that includes the // description and flags. -func NewKubelet() *hyperkube.Server { +func NewKubelet() *Server { s := kubelet.NewKubeletServer() - hks := hyperkube.Server{ + hks := Server{ SimpleUsage: "kubelet", Long: `The kubelet binary is responsible for maintaining a set of containers on a particular node. It syncs data from a variety of sources including a @@ -33,7 +32,7 @@ func NewKubelet() *hyperkube.Server { queries Docker to see what is currently running. It synchronizes the configuration data, with the running set of containers by starting or stopping Docker containers.`, - Run: func(_ *hyperkube.Server, args []string) error { + Run: func(_ *Server, args []string) error { return s.Run(args) }, } diff --git a/cmd/hyperkube/main.go b/cmd/hyperkube/main.go new file mode 100644 index 00000000000..36927889896 --- /dev/null +++ b/cmd/hyperkube/main.go @@ -0,0 +1,38 @@ +/* +Copyright 2014 Google Inc. 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. +*/ + +// A binary that can morph into all of the other kubernetes binaries. You can +// also soft-link to it busybox style. +package main + +import ( + "os" +) + +func main() { + hk := HyperKube{ + Name: "hyperkube", + Long: "This is an all-in-one binary that can run any of the various Kubernetes servers.", + } + + hk.AddServer(NewKubeAPIServer()) + hk.AddServer(NewKubeControllerManager()) + hk.AddServer(NewScheduler()) + hk.AddServer(NewKubelet()) + hk.AddServer(NewKubeProxy()) + + hk.RunToExit(os.Args) +} diff --git a/pkg/hyperkube/server.go b/cmd/hyperkube/server.go similarity index 99% rename from pkg/hyperkube/server.go rename to cmd/hyperkube/server.go index 697211b5f19..4c29f1df321 100644 --- a/pkg/hyperkube/server.go +++ b/cmd/hyperkube/server.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package hyperkube +package main import ( "io/ioutil" diff --git a/pkg/hyperkube/hyperkube.go b/pkg/hyperkube/hyperkube.go deleted file mode 100644 index f38aec289e2..00000000000 --- a/pkg/hyperkube/hyperkube.go +++ /dev/null @@ -1,202 +0,0 @@ -/* -Copyright 2014 Google Inc. 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. -*/ - -package hyperkube - -import ( - "errors" - "flag" - "fmt" - "io" - "io/ioutil" - "os" - "path" - "runtime" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag" - - "github.com/spf13/pflag" -) - -// HyperKube represents a single binary that can morph/manage into multiple -// servers. -type HyperKube struct { - Name string // The executable name, used for help and soft-link invocation - Long string // A long description of the binary. It will be world wrapped before output. - - servers []Server - baseFlags *pflag.FlagSet - out io.Writer - helpFlagVal bool -} - -// AddServer adds a server to the HyperKube object. -func (hk *HyperKube) AddServer(s *Server) { - hk.servers = append(hk.servers, *s) - hk.servers[len(hk.servers)-1].hk = hk -} - -// FindServer will find a specific server named name. -func (hk *HyperKube) FindServer(name string) (*Server, error) { - for _, s := range hk.servers { - if s.Name() == name { - return &s, nil - } - } - return nil, fmt.Errorf("Server not found: %s", name) -} - -// Servers returns a list of all of the registred servers -func (hk *HyperKube) Servers() []Server { - return hk.servers -} - -// Flags returns a flagset for "global" flags. -func (hk *HyperKube) Flags() *pflag.FlagSet { - if hk.baseFlags == nil { - hk.baseFlags = pflag.NewFlagSet(hk.Name, pflag.ContinueOnError) - hk.baseFlags.SetOutput(ioutil.Discard) - hk.baseFlags.BoolVarP(&hk.helpFlagVal, "help", "h", false, "help for "+hk.Name) - - // These will add all of the "global" flags (defined with both the - // flag and pflag packages) to the new flag set we have. - util.AddFlagSetToPFlagSet(flag.CommandLine, hk.baseFlags) - util.AddPFlagSetToPFlagSet(pflag.CommandLine, hk.baseFlags) - - } - return hk.baseFlags -} - -// Out returns the io.Writer that is used for all usage/error information -func (hk *HyperKube) Out() io.Writer { - if hk.out == nil { - hk.out = os.Stderr - } - return hk.out -} - -// SetOut sets the output writer for all usage/error information -func (hk *HyperKube) SetOut(w io.Writer) { - hk.out = w -} - -// Print is a convenience method to Print to the defined output -func (hk *HyperKube) Print(i ...interface{}) { - fmt.Fprint(hk.Out(), i...) -} - -// Println is a convenience method to Println to the defined output -func (hk *HyperKube) Println(i ...interface{}) { - fmt.Fprintln(hk.Out(), i...) -} - -// Printf is a convenience method to Printf to the defined output -func (hk *HyperKube) Printf(format string, i ...interface{}) { - fmt.Fprintf(hk.Out(), format, i...) -} - -// Run the server. This will pick the appropriate server and run it. -func (hk *HyperKube) Run(args []string) error { - // If we are called directly, parse all flags up to the first real - // argument. That should be the server to run. - baseCommand := path.Base(args[0]) - serverName := baseCommand - if serverName == hk.Name { - args = args[1:] - - baseFlags := hk.Flags() - baseFlags.SetInterspersed(false) // Only parse flags up to the next real command - err := baseFlags.Parse(args) - if err != nil || hk.helpFlagVal { - if err != nil { - hk.Println("Error:", err) - } - hk.Usage() - return err - } - - verflag.PrintAndExitIfRequested() - - args = baseFlags.Args() - if len(args) > 0 && len(args[0]) > 0 { - serverName = args[0] - baseCommand = baseCommand + " " + serverName - args = args[1:] - } else { - err = errors.New("No server specified") - hk.Printf("Error: %v\n\n", err) - hk.Usage() - return err - } - } - - s, err := hk.FindServer(serverName) - if err != nil { - hk.Printf("Error: %v\n\n", err) - hk.Usage() - return err - } - - util.AddPFlagSetToPFlagSet(hk.Flags(), s.Flags()) - err = s.Flags().Parse(args) - if err != nil || hk.helpFlagVal { - if err != nil { - hk.Printf("Error: %v\n\n", err) - } - s.Usage() - return err - } - - verflag.PrintAndExitIfRequested() - - util.InitLogs() - defer util.FlushLogs() - - err = s.Run(s, s.Flags().Args()) - if err != nil { - hk.Println("Error:", err) - } - - return err -} - -// RunToExit will run the hyperkube and then call os.Exit with an appropriate exit code. -func (hk *HyperKube) RunToExit(args []string) { - runtime.GOMAXPROCS(runtime.NumCPU()) - err := hk.Run(args) - if err != nil { - fmt.Fprint(os.Stderr, err.Error()) - os.Exit(1) - } - os.Exit(0) -} - -// Usage will write out a summary for all servers that this binary supports. -func (hk *HyperKube) Usage() { - tt := `{{if .Long}}{{.Long | trim | wrap ""}} -{{end}}Usage - - {{.Name}} [flags] - -Servers -{{range .Servers}} - {{.Name}} -{{.Long | trim | wrap " "}}{{end}} -Call '{{.Name}} --help' for help on a specific server. -` - util.ExecuteTemplate(hk.Out(), tt, hk) -}