diff --git a/pkg/server/genericapiserver.go b/pkg/server/genericapiserver.go index 4babef1bf..3a9cec73b 100644 --- a/pkg/server/genericapiserver.go +++ b/pkg/server/genericapiserver.go @@ -189,16 +189,16 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer { // Run spawns the http servers (secure and insecure). It only returns if stopCh is closed // or one of the ports cannot be listened on initially. -func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) { +func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { if s.SecureServingInfo != nil && s.Handler != nil { if err := s.serveSecurely(stopCh); err != nil { - glog.Fatal(err) + return err } } if s.InsecureServingInfo != nil && s.InsecureHandler != nil { if err := s.serveInsecurely(stopCh); err != nil { - glog.Fatal(err) + return err } } @@ -210,6 +210,7 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) { } <-stopCh + return nil } // EffectiveSecurePort returns the secure port we bound to. diff --git a/pkg/server/options/serving_test.go b/pkg/server/options/serving_test.go index a828c56e6..ea615b785 100644 --- a/pkg/server/options/serving_test.go +++ b/pkg/server/options/serving_test.go @@ -448,114 +448,121 @@ NextTest: } stopCh := make(chan struct{}) + func() { + defer close(stopCh) - // launch server - config := setUp(t) + // launch server + config := setUp(t) - v := fakeVersion() - config.Version = &v + v := fakeVersion() + config.Version = &v - config.EnableIndex = true - secureOptions := &SecureServingOptions{ - ServingOptions: ServingOptions{ - BindAddress: net.ParseIP("127.0.0.1"), - BindPort: 6443, - }, - ServerCert: GeneratableKeyCert{ - CertKey: CertKey{ - CertFile: serverCertBundleFile, - KeyFile: serverKeyFile, + config.EnableIndex = true + secureOptions := &SecureServingOptions{ + ServingOptions: ServingOptions{ + BindAddress: net.ParseIP("127.0.0.1"), + BindPort: 6443, }, - }, - SNICertKeys: namedCertKeys, - } - config.LoopbackClientConfig = &restclient.Config{} - if err := secureOptions.ApplyTo(&config); err != nil { - t.Errorf("%q - failed applying the SecureServingOptions: %v", title, err) - continue NextTest - } - config.InsecureServingInfo = nil - - s, err := config.Complete().New() - if err != nil { - t.Errorf("%q - failed creating the server: %v", title, err) - continue NextTest - } - - // patch in a 0-port to enable auto port allocation - s.SecureServingInfo.BindAddress = "127.0.0.1:0" - - // add poststart hook to know when the server is up. - startedCh := make(chan struct{}) - s.AddPostStartHook("test-notifier", func(context PostStartHookContext) error { - close(startedCh) - return nil - }) - preparedServer := s.PrepareRun() - go preparedServer.Run(stopCh) - - // load ca certificates into a pool - roots := x509.NewCertPool() - for _, caCert := range caCerts { - roots.AddCert(caCert) - } - - <-startedCh - - effectiveSecurePort := fmt.Sprintf("%d", preparedServer.EffectiveSecurePort()) - // try to dial - addr := fmt.Sprintf("localhost:%s", effectiveSecurePort) - t.Logf("Dialing %s as %q", addr, test.ServerName) - conn, err := tls.Dial("tcp", addr, &tls.Config{ - RootCAs: roots, - ServerName: test.ServerName, // used for SNI in the client HELLO packet - }) - if err != nil { - t.Errorf("%q - failed to connect: %v", title, err) - continue NextTest - } - - // check returned server certificate - sig := x509CertSignature(conn.ConnectionState().PeerCertificates[0]) - gotCertIndex, found := signatures[sig] - if !found { - t.Errorf("%q - unknown signature returned from server: %s", title, sig) - } - if gotCertIndex != test.ExpectedCertIndex { - t.Errorf("%q - expected cert index %d, got cert index %d", title, test.ExpectedCertIndex, gotCertIndex) - } - - conn.Close() - - // check that the loopback client can connect - host := "127.0.0.1" - if len(test.LoopbackClientBindAddressOverride) != 0 { - host = test.LoopbackClientBindAddressOverride - } - s.LoopbackClientConfig.Host = net.JoinHostPort(host, effectiveSecurePort) - if test.ExpectLoopbackClientError { - if err == nil { - t.Errorf("%q - expected error creating loopback client config", title) + ServerCert: GeneratableKeyCert{ + CertKey: CertKey{ + CertFile: serverCertBundleFile, + KeyFile: serverKeyFile, + }, + }, + SNICertKeys: namedCertKeys, } - continue NextTest - } - if err != nil { - t.Errorf("%q - failed creating loopback client config: %v", title, err) - continue NextTest - } - client, err := discovery.NewDiscoveryClientForConfig(s.LoopbackClientConfig) - if err != nil { - t.Errorf("%q - failed to create loopback client: %v", title, err) - continue NextTest - } - got, err := client.ServerVersion() - if err != nil { - t.Errorf("%q - failed to connect with loopback client: %v", title, err) - continue NextTest - } - if expected := &v; !reflect.DeepEqual(got, expected) { - t.Errorf("%q - loopback client didn't get correct version info: expected=%v got=%v", title, expected, got) - } + config.LoopbackClientConfig = &restclient.Config{} + if err := secureOptions.ApplyTo(&config); err != nil { + t.Errorf("%q - failed applying the SecureServingOptions: %v", title, err) + return + } + config.InsecureServingInfo = nil + + s, err := config.Complete().New() + if err != nil { + t.Errorf("%q - failed creating the server: %v", title, err) + return + } + + // patch in a 0-port to enable auto port allocation + s.SecureServingInfo.BindAddress = "127.0.0.1:0" + + // add poststart hook to know when the server is up. + startedCh := make(chan struct{}) + s.AddPostStartHook("test-notifier", func(context PostStartHookContext) error { + close(startedCh) + return nil + }) + preparedServer := s.PrepareRun() + go func() { + if err := preparedServer.Run(stopCh); err != nil { + t.Fatal(err) + } + }() + + // load ca certificates into a pool + roots := x509.NewCertPool() + for _, caCert := range caCerts { + roots.AddCert(caCert) + } + + <-startedCh + + effectiveSecurePort := fmt.Sprintf("%d", preparedServer.EffectiveSecurePort()) + // try to dial + addr := fmt.Sprintf("localhost:%s", effectiveSecurePort) + t.Logf("Dialing %s as %q", addr, test.ServerName) + conn, err := tls.Dial("tcp", addr, &tls.Config{ + RootCAs: roots, + ServerName: test.ServerName, // used for SNI in the client HELLO packet + }) + if err != nil { + t.Errorf("%q - failed to connect: %v", title, err) + return + } + + // check returned server certificate + sig := x509CertSignature(conn.ConnectionState().PeerCertificates[0]) + gotCertIndex, found := signatures[sig] + if !found { + t.Errorf("%q - unknown signature returned from server: %s", title, sig) + } + if gotCertIndex != test.ExpectedCertIndex { + t.Errorf("%q - expected cert index %d, got cert index %d", title, test.ExpectedCertIndex, gotCertIndex) + } + + conn.Close() + + // check that the loopback client can connect + host := "127.0.0.1" + if len(test.LoopbackClientBindAddressOverride) != 0 { + host = test.LoopbackClientBindAddressOverride + } + s.LoopbackClientConfig.Host = net.JoinHostPort(host, effectiveSecurePort) + if test.ExpectLoopbackClientError { + if err == nil { + t.Errorf("%q - expected error creating loopback client config", title) + } + return + } + if err != nil { + t.Errorf("%q - failed creating loopback client config: %v", title, err) + return + } + client, err := discovery.NewDiscoveryClientForConfig(s.LoopbackClientConfig) + if err != nil { + t.Errorf("%q - failed to create loopback client: %v", title, err) + return + } + got, err := client.ServerVersion() + if err != nil { + t.Errorf("%q - failed to connect with loopback client: %v", title, err) + return + } + if expected := &v; !reflect.DeepEqual(got, expected) { + t.Errorf("%q - loopback client didn't get correct version info: expected=%v got=%v", title, expected, got) + } + }() } }