diff --git a/cmd/cloud-controller-manager/BUILD b/cmd/cloud-controller-manager/BUILD index d637599ba00..0a30843ab69 100644 --- a/cmd/cloud-controller-manager/BUILD +++ b/cmd/cloud-controller-manager/BUILD @@ -28,11 +28,9 @@ go_library( "//cmd/cloud-controller-manager/app:go_default_library", "//cmd/cloud-controller-manager/app/options:go_default_library", "//pkg/client/metrics/prometheus:go_default_library", - "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers:go_default_library", "//pkg/version/prometheus:go_default_library", "//pkg/version/verflag:go_default_library", - "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/logs:go_default_library", diff --git a/cmd/cloud-controller-manager/app/controllermanager.go b/cmd/cloud-controller-manager/app/controllermanager.go index 5c1e4c78fad..c93da56dad5 100644 --- a/cmd/cloud-controller-manager/app/controllermanager.go +++ b/cmd/cloud-controller-manager/app/controllermanager.go @@ -83,7 +83,24 @@ func resyncPeriod(s *options.CloudControllerManagerServer) func() time.Duration } // Run runs the ExternalCMServer. This should never exit. -func Run(s *options.CloudControllerManagerServer, cloud cloudprovider.Interface) error { +func Run(s *options.CloudControllerManagerServer) error { + if s.CloudProvider == "" { + glog.Fatalf("--cloud-provider cannot be empty") + } + + cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile) + if err != nil { + glog.Fatalf("Cloud provider could not be initialized: %v", err) + } + + if cloud.HasClusterID() == false { + if s.AllowUntaggedCloud == true { + glog.Warning("detected a cluster without a ClusterID. A ClusterID will be required in the future. Please tag your cluster to avoid any future issues") + } else { + glog.Fatalf("no ClusterID found. A ClusterID is required for the cloud provider to function properly. This check can be bypassed by setting the allow-untagged-cloud option") + } + } + if c, err := configz.New("componentconfig"); err == nil { c.Set(s.KubeControllerManagerConfiguration) } else { diff --git a/cmd/cloud-controller-manager/controller-manager.go b/cmd/cloud-controller-manager/controller-manager.go index 60bac4ac729..1d8b498fbf1 100644 --- a/cmd/cloud-controller-manager/controller-manager.go +++ b/cmd/cloud-controller-manager/controller-manager.go @@ -28,14 +28,12 @@ import ( "k8s.io/kubernetes/cmd/cloud-controller-manager/app" "k8s.io/kubernetes/cmd/cloud-controller-manager/app/options" _ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration - "k8s.io/kubernetes/pkg/cloudprovider" // NOTE: Importing all in-tree cloud-providers is not required when // implementing an out-of-tree cloud-provider. _ "k8s.io/kubernetes/pkg/cloudprovider/providers" _ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration "k8s.io/kubernetes/pkg/version/verflag" - "github.com/golang/glog" "github.com/spf13/pflag" ) @@ -49,24 +47,7 @@ func main() { verflag.PrintAndExitIfRequested() - if s.CloudProvider == "" { - glog.Errorf("--cloud-provider cannot be empty") - } - - cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile) - if err != nil { - glog.Fatalf("Cloud provider could not be initialized: %v", err) - } - - if cloud.HasClusterID() == false { - if s.AllowUntaggedCloud == true { - glog.Warning("detected a cluster without a ClusterID. A ClusterID will be required in the future. Please tag your cluster to avoid any future issues") - } else { - glog.Fatalf("no ClusterID found. A ClusterID is required for the cloud provider to function properly. This check can be bypassed by setting the allow-untagged-cloud option") - } - } - - if err := app.Run(s, cloud); err != nil { + if err := app.Run(s); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } diff --git a/cmd/hyperkube/BUILD b/cmd/hyperkube/BUILD index c74587b0571..af3f17aae7f 100644 --- a/cmd/hyperkube/BUILD +++ b/cmd/hyperkube/BUILD @@ -30,6 +30,7 @@ go_test( go_library( name = "go_default_library", srcs = [ + "cloud-controller-manager.go", "hyperkube.go", "kube-aggregator.go", "kube-apiserver.go", @@ -43,6 +44,8 @@ go_library( ], importpath = "k8s.io/kubernetes/cmd/hyperkube", deps = [ + "//cmd/cloud-controller-manager/app:go_default_library", + "//cmd/cloud-controller-manager/app/options:go_default_library", "//cmd/kube-apiserver/app:go_default_library", "//cmd/kube-apiserver/app/options:go_default_library", "//cmd/kube-controller-manager/app:go_default_library", diff --git a/cmd/hyperkube/cloud-controller-manager.go b/cmd/hyperkube/cloud-controller-manager.go new file mode 100644 index 00000000000..fd3266beeaa --- /dev/null +++ b/cmd/hyperkube/cloud-controller-manager.go @@ -0,0 +1,39 @@ +/* +Copyright 2017 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. +*/ + +package main + +import ( + "k8s.io/kubernetes/cmd/cloud-controller-manager/app" + "k8s.io/kubernetes/cmd/cloud-controller-manager/app/options" +) + +// NewCloudControllerManager creates a new hyperkube Server object that includes the +// description and flags. +func NewCloudControllerManager() *Server { + s := options.NewCloudControllerManagerServer() + + hks := Server{ + name: "cloud-controller-manager", + SimpleUsage: "cloud-controller-manager", + Long: "A server that acts as an external cloud provider.", + Run: func(_ *Server, args []string, stopCh <-chan struct{}) error { + return app.Run(s) + }, + } + s.AddFlags(hks.Flags()) + return &hks +} diff --git a/cmd/hyperkube/hyperkube.go b/cmd/hyperkube/hyperkube.go index 556711d5d8a..a4de5c7af24 100644 --- a/cmd/hyperkube/hyperkube.go +++ b/cmd/hyperkube/hyperkube.go @@ -42,6 +42,7 @@ type HyperKube struct { Long string // A long description of the binary. It will be world wrapped before output. servers []Server + alphaServers []Server baseFlags *pflag.FlagSet out io.Writer helpFlagVal bool @@ -54,9 +55,24 @@ func (hk *HyperKube) AddServer(s *Server) { hk.servers[len(hk.servers)-1].hk = hk } +// AddServer adds an alpha server to the HyperKube object. +func (hk *HyperKube) AddAlphaServer(s *Server) { + hk.alphaServers = append(hk.alphaServers, *s) + hk.alphaServers[len(hk.alphaServers)-1].hk = hk +} + // FindServer will find a specific server named name. func (hk *HyperKube) FindServer(name string) (*Server, error) { - for _, s := range hk.servers { + return findServer(name, hk.servers) +} + +// FindServer will find a specific alpha server named name. +func (hk *HyperKube) FindAlphaServer(name string) (*Server, error) { + return findServer(name, hk.alphaServers) +} + +func findServer(name string, servers []Server) (*Server, error) { + for _, s := range servers { if s.Name() == name || s.AlternativeName == name { return &s, nil } @@ -154,7 +170,23 @@ func (hk *HyperKube) Run(args []string, stopCh <-chan struct{}) error { } } - s, err := hk.FindServer(serverName) + var s *Server + var err error + if serverName == "alpha" { + if len(args) > 0 && len(args[0]) > 0 { + serverName = args[0] + args = args[1:] + hk.Printf("Warning: alpha command syntax is unstable!\n\n") + } else { + err = errors.New("no alpha server specified") + hk.Printf("Error: %v\n\n", err) + hk.Usage() + return err + } + s, err = hk.FindAlphaServer(serverName) + } else { + s, err = hk.FindServer(serverName) + } if err != nil { hk.Printf("Error: %v\n\n", err) hk.Usage() diff --git a/cmd/hyperkube/hyperkube_test.go b/cmd/hyperkube/hyperkube_test.go index 5a4459b2a96..56761812010 100644 --- a/cmd/hyperkube/hyperkube_test.go +++ b/cmd/hyperkube/hyperkube_test.go @@ -151,6 +151,7 @@ func runFull(t *testing.T, args string, stopCh <-chan struct{}) *result { hk.AddServer(testServer("test1")) hk.AddServer(testServer("test2")) hk.AddServer(testServer("test3")) + hk.AddAlphaServer(testServer("testAlpha1")) hk.AddServer(testServerError("test-error")) hk.AddServer(testStopChIgnoringServer("test-stop-ch-ignoring")) hk.AddServer(testStopChRespectingServer("test-stop-ch-respecting")) @@ -236,6 +237,22 @@ func TestServerError(t *testing.T) { assert.EqualError(t, x.err, "server returning error") } +func TestAlphaRun(t *testing.T) { + x := runFull(t, "hyperkube alpha testAlpha1", wait.NeverStop) + assert.NoError(t, x.err) +} + +func TestAlphaNoArgs(t *testing.T) { + x := runFull(t, "hyperkube alpha", wait.NeverStop) + assert.EqualError(t, x.err, "no alpha server specified") +} + +func TestAlphaBadServer(t *testing.T) { + x := runFull(t, "hyperkube alpha bad-server", wait.NeverStop) + assert.EqualError(t, x.err, "Server not found: bad-server") + assert.Contains(t, x.output, "Usage") +} + func TestStopChIgnoringServer(t *testing.T) { stopCh := make(chan struct{}) returnedCh := make(chan struct{}) diff --git a/cmd/hyperkube/main.go b/cmd/hyperkube/main.go index de5b58fca12..123f040a87b 100644 --- a/cmd/hyperkube/main.go +++ b/cmd/hyperkube/main.go @@ -46,5 +46,8 @@ func main() { hk.AddServer(NewKubeProxy()) hk.AddServer(NewKubeAggregator()) + // Alpha servers + hk.AddAlphaServer(NewCloudControllerManager()) + hk.RunToExit(os.Args) }