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>
This commit is contained in:
Flavio Crisciani 2017-12-05 09:19:17 -08:00
parent 68fb31aa4b
commit 1a2efea39e
2 changed files with 29 additions and 19 deletions

View file

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

View file

@ -1,12 +1,12 @@
package diagnose
import (
"context"
"encoding/json"
"fmt"
"log"
"net"
"net/http"
"sync"
"sync/atomic"
stackdump "github.com/docker/docker/pkg/signal"
"github.com/docker/libnetwork/common"
@ -36,7 +36,8 @@ var diagPaths2Func = map[string]HTTPHandlerFunc{
// 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
type Server struct {
sk net.Listener
enable int32
srv *http.Server
port int
mux *http.ServeMux
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
func (n *Server) EnableDebug(ip string, port int) {
n.Lock()
@ -78,37 +83,41 @@ func (n *Server) EnableDebug(ip string, port int) {
n.port = port
if n.sk != nil {
if n.enable == 1 {
logrus.Info("The server is already up and running")
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
func (n *Server) DisableDebug() {
n.Lock()
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
func (n *Server) IsDebugEnable() bool {
n.Lock()
defer n.Unlock()
return n.sk != nil
return n.enable == 1
}
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) {
var response []byte
if j.enable {
w.Header().Set("Content-Type", "application/json")
var err error
if j.prettyPrint {
response, err = json.MarshalIndent(r, "", " ")