fix potential panic on http server close (#496)
This commit is contained in:
39
http.go
39
http.go
@@ -44,11 +44,19 @@ func loadTLSConfig(certPath, keyPath string) (*tls.Config, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupHTTPServer(ctx context.Context, cfg *apiServerConfig) (io.Closer, io.Closer, error) {
|
func setupHTTPServer(ctx context.Context, cfg *apiServerConfig) (cancel func(), retErr error) {
|
||||||
var (
|
var closers []io.Closer
|
||||||
podS *http.Server
|
cancel = func() {
|
||||||
metricsS *http.Server
|
for _, c := range closers {
|
||||||
)
|
c.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if retErr != nil {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if cfg.CertPath == "" || cfg.KeyPath == "" {
|
if cfg.CertPath == "" || cfg.KeyPath == "" {
|
||||||
log.G(ctx).
|
log.G(ctx).
|
||||||
WithField("certPath", cfg.CertPath).
|
WithField("certPath", cfg.CertPath).
|
||||||
@@ -57,21 +65,22 @@ func setupHTTPServer(ctx context.Context, cfg *apiServerConfig) (io.Closer, io.C
|
|||||||
} else {
|
} else {
|
||||||
tlsCfg, err := loadTLSConfig(cfg.CertPath, cfg.KeyPath)
|
tlsCfg, err := loadTLSConfig(cfg.CertPath, cfg.KeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
l, err := tls.Listen("tcp", cfg.Addr, tlsCfg)
|
l, err := tls.Listen("tcp", cfg.Addr, tlsCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "error setting up listener for pod http server")
|
return nil, errors.Wrap(err, "error setting up listener for pod http server")
|
||||||
}
|
}
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
vkubelet.AttachPodRoutes(p, mux)
|
vkubelet.AttachPodRoutes(p, mux)
|
||||||
|
|
||||||
podS = &http.Server{
|
s := &http.Server{
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
TLSConfig: tlsCfg,
|
TLSConfig: tlsCfg,
|
||||||
}
|
}
|
||||||
go serveHTTP(ctx, podS, l, "pods")
|
go serveHTTP(ctx, s, l, "pods")
|
||||||
|
closers = append(closers, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.MetricsAddr == "" {
|
if cfg.MetricsAddr == "" {
|
||||||
@@ -79,21 +88,19 @@ func setupHTTPServer(ctx context.Context, cfg *apiServerConfig) (io.Closer, io.C
|
|||||||
} else {
|
} else {
|
||||||
l, err := net.Listen("tcp", cfg.MetricsAddr)
|
l, err := net.Listen("tcp", cfg.MetricsAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if l != nil {
|
return nil, errors.Wrap(err, "could not setup listener for pod metrics http server")
|
||||||
podS.Close()
|
|
||||||
}
|
|
||||||
return nil, nil, errors.Wrap(err, "could not setup listenr for pod metrics http server")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
vkubelet.AttachMetricsRoutes(p, mux)
|
vkubelet.AttachMetricsRoutes(p, mux)
|
||||||
metricsS = &http.Server{
|
s := &http.Server{
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
}
|
}
|
||||||
go serveHTTP(ctx, metricsS, l, "pod metrics")
|
go serveHTTP(ctx, s, l, "pod metrics")
|
||||||
|
closers = append(closers, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return podS, metricsS, nil
|
return cancel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveHTTP(ctx context.Context, s *http.Server, l net.Listener, name string) {
|
func serveHTTP(ctx context.Context, s *http.Server, l net.Listener, name string) {
|
||||||
|
|||||||
6
root.go
6
root.go
@@ -108,13 +108,11 @@ This allows users to schedule kubernetes workloads on nodes that aren't running
|
|||||||
rootContextCancel()
|
rootContextCancel()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
c1, c2, err := setupHTTPServer(rootContext, apiConfig)
|
cancelHTTP, err := setupHTTPServer(rootContext, apiConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(rootContext).Fatal(err)
|
log.G(rootContext).Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer cancelHTTP()
|
||||||
defer c1.Close()
|
|
||||||
defer c2.Close()
|
|
||||||
|
|
||||||
if err := vk.Run(rootContext); err != nil && errors.Cause(err) != context.Canceled {
|
if err := vk.Run(rootContext); err != nil && errors.Cause(err) != context.Canceled {
|
||||||
log.G(rootContext).Fatal(err)
|
log.G(rootContext).Fatal(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user