Selaa lähdekoodia

Call the Shutdown on the server

This is the right way to call for a clean shutdown

Return application/json as content-type when appropriate

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Flavio Crisciani 7 vuotta sitten
vanhempi
commit
1a2efea39e
2 muutettua tiedostoa jossa 29 lisäystä ja 19 poistoa
  1. 2 2
      libnetwork/controller.go
  2. 27 17
      libnetwork/diagnose/server.go

+ 2 - 2
libnetwork/controller.go

@@ -1306,19 +1306,19 @@ func (c *controller) Stop() {
 // StartDiagnose start the network diagnose mode
 // StartDiagnose start the network diagnose mode
 func (c *controller) StartDiagnose(port int) {
 func (c *controller) StartDiagnose(port int) {
 	c.Lock()
 	c.Lock()
-	defer c.Unlock()
 	if !c.DiagnoseServer.IsDebugEnable() {
 	if !c.DiagnoseServer.IsDebugEnable() {
 		c.DiagnoseServer.EnableDebug("127.0.0.1", port)
 		c.DiagnoseServer.EnableDebug("127.0.0.1", port)
 	}
 	}
+	c.Unlock()
 }
 }
 
 
 // StopDiagnose start the network diagnose mode
 // StopDiagnose start the network diagnose mode
 func (c *controller) StopDiagnose() {
 func (c *controller) StopDiagnose() {
 	c.Lock()
 	c.Lock()
-	defer c.Unlock()
 	if c.DiagnoseServer.IsDebugEnable() {
 	if c.DiagnoseServer.IsDebugEnable() {
 		c.DiagnoseServer.DisableDebug()
 		c.DiagnoseServer.DisableDebug()
 	}
 	}
+	c.Unlock()
 }
 }
 
 
 // IsDiagnoseEnabled returns true if the diagnose is enabled
 // IsDiagnoseEnabled returns true if the diagnose is enabled

+ 27 - 17
libnetwork/diagnose/server.go

@@ -1,12 +1,12 @@
 package diagnose
 package diagnose
 
 
 import (
 import (
+	"context"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
-	"log"
-	"net"
 	"net/http"
 	"net/http"
 	"sync"
 	"sync"
+	"sync/atomic"
 
 
 	stackdump "github.com/docker/docker/pkg/signal"
 	stackdump "github.com/docker/docker/pkg/signal"
 	"github.com/docker/libnetwork/common"
 	"github.com/docker/libnetwork/common"
@@ -36,7 +36,8 @@ var diagPaths2Func = map[string]HTTPHandlerFunc{
 // Server when the debug is enabled exposes a
 // Server when the debug is enabled exposes a
 // This data structure is protected by the Agent mutex so does not require and additional mutex here
 // This data structure is protected by the Agent mutex so does not require and additional mutex here
 type Server struct {
 type Server struct {
-	sk                net.Listener
+	enable            int32
+	srv               *http.Server
 	port              int
 	port              int
 	mux               *http.ServeMux
 	mux               *http.ServeMux
 	registeredHanders map[string]bool
 	registeredHanders map[string]bool
@@ -71,6 +72,10 @@ func (n *Server) RegisterHandler(ctx interface{}, hdlrs map[string]HTTPHandlerFu
 	}
 	}
 }
 }
 
 
+func (n *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	n.mux.ServeHTTP(w, r)
+}
+
 // EnableDebug opens a TCP socket to debug the passed network DB
 // EnableDebug opens a TCP socket to debug the passed network DB
 func (n *Server) EnableDebug(ip string, port int) {
 func (n *Server) EnableDebug(ip string, port int) {
 	n.Lock()
 	n.Lock()
@@ -78,37 +83,41 @@ func (n *Server) EnableDebug(ip string, port int) {
 
 
 	n.port = port
 	n.port = port
 
 
-	if n.sk != nil {
+	if n.enable == 1 {
 		logrus.Info("The server is already up and running")
 		logrus.Info("The server is already up and running")
 		return
 		return
 	}
 	}
 
 
-	logrus.Infof("Starting the server listening on %d for commands", port)
-	// Create the socket
-	var err error
-	n.sk, err = net.Listen("tcp", fmt.Sprintf("%s:%d", ip, port))
-	if err != nil {
-		log.Fatal(err)
-	}
+	logrus.Infof("Starting the diagnose server listening on %d for commands", port)
+	srv := &http.Server{Addr: fmt.Sprintf("127.0.0.1:%d", port), Handler: n}
+	n.srv = srv
+	n.enable = 1
+	go func(n *Server) {
+		// Ingore ErrServerClosed that is returned on the Shutdown call
+		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+			logrus.Errorf("ListenAndServe error: %s", err)
+			atomic.SwapInt32(&n.enable, 0)
+		}
+	}(n)
 
 
-	go func() {
-		http.Serve(n.sk, n.mux)
-	}()
 }
 }
 
 
 // DisableDebug stop the dubug and closes the tcp socket
 // DisableDebug stop the dubug and closes the tcp socket
 func (n *Server) DisableDebug() {
 func (n *Server) DisableDebug() {
 	n.Lock()
 	n.Lock()
 	defer n.Unlock()
 	defer n.Unlock()
-	n.sk.Close()
-	n.sk = nil
+
+	n.srv.Shutdown(context.Background())
+	n.srv = nil
+	n.enable = 0
+	logrus.Info("Disabling the diagnose server")
 }
 }
 
 
 // IsDebugEnable returns true when the debug is enabled
 // IsDebugEnable returns true when the debug is enabled
 func (n *Server) IsDebugEnable() bool {
 func (n *Server) IsDebugEnable() bool {
 	n.Lock()
 	n.Lock()
 	defer n.Unlock()
 	defer n.Unlock()
-	return n.sk != nil
+	return n.enable == 1
 }
 }
 
 
 func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
 func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
@@ -197,6 +206,7 @@ func ParseHTTPFormOptions(r *http.Request) (bool, *JSONOutput) {
 func HTTPReply(w http.ResponseWriter, r *HTTPResult, j *JSONOutput) (int, error) {
 func HTTPReply(w http.ResponseWriter, r *HTTPResult, j *JSONOutput) (int, error) {
 	var response []byte
 	var response []byte
 	if j.enable {
 	if j.enable {
+		w.Header().Set("Content-Type", "application/json")
 		var err error
 		var err error
 		if j.prettyPrint {
 		if j.prettyPrint {
 			response, err = json.MarshalIndent(r, "", "  ")
 			response, err = json.MarshalIndent(r, "", "  ")