Browse code

Add option to enable networkDB debug

Add a new configuration option to allow the enabling
of the networkDB debug. The option is only parsed using the
reload event. This will protect the daemon on start or restart
if the option is left behind in the config file

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>

Flavio Crisciani authored on 2017/12/02 04:24:14
Showing 4 changed files
... ...
@@ -59,6 +59,8 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
59 59
 	flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", config.DefaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull")
60 60
 	flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", config.DefaultMaxConcurrentUploads, "Set the max concurrent uploads for each push")
61 61
 	flags.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", defaultShutdownTimeout, "Set the default shutdown timeout")
62
+	flags.IntVar(&conf.NetworkDiagnosticPort, "network-diagnostic-port", 0, "TCP port number of the network diagnostic server")
63
+	flags.MarkHidden("network-diagnostic-port")
62 64
 
63 65
 	flags.StringVar(&conf.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address")
64 66
 	flags.BoolVar(&conf.Experimental, "experimental", false, "Enable experimental features")
... ...
@@ -85,26 +85,27 @@ type CommonTLSOptions struct {
85 85
 // It includes json tags to deserialize configuration from a file
86 86
 // using the same names that the flags in the command line use.
87 87
 type CommonConfig struct {
88
-	AuthzMiddleware      *authorization.Middleware `json:"-"`
89
-	AuthorizationPlugins []string                  `json:"authorization-plugins,omitempty"` // AuthorizationPlugins holds list of authorization plugins
90
-	AutoRestart          bool                      `json:"-"`
91
-	Context              map[string][]string       `json:"-"`
92
-	DisableBridge        bool                      `json:"-"`
93
-	DNS                  []string                  `json:"dns,omitempty"`
94
-	DNSOptions           []string                  `json:"dns-opts,omitempty"`
95
-	DNSSearch            []string                  `json:"dns-search,omitempty"`
96
-	ExecOptions          []string                  `json:"exec-opts,omitempty"`
97
-	GraphDriver          string                    `json:"storage-driver,omitempty"`
98
-	GraphOptions         []string                  `json:"storage-opts,omitempty"`
99
-	Labels               []string                  `json:"labels,omitempty"`
100
-	Mtu                  int                       `json:"mtu,omitempty"`
101
-	Pidfile              string                    `json:"pidfile,omitempty"`
102
-	RawLogs              bool                      `json:"raw-logs,omitempty"`
103
-	RootDeprecated       string                    `json:"graph,omitempty"`
104
-	Root                 string                    `json:"data-root,omitempty"`
105
-	ExecRoot             string                    `json:"exec-root,omitempty"`
106
-	SocketGroup          string                    `json:"group,omitempty"`
107
-	CorsHeaders          string                    `json:"api-cors-header,omitempty"`
88
+	AuthzMiddleware       *authorization.Middleware `json:"-"`
89
+	AuthorizationPlugins  []string                  `json:"authorization-plugins,omitempty"` // AuthorizationPlugins holds list of authorization plugins
90
+	AutoRestart           bool                      `json:"-"`
91
+	Context               map[string][]string       `json:"-"`
92
+	DisableBridge         bool                      `json:"-"`
93
+	DNS                   []string                  `json:"dns,omitempty"`
94
+	DNSOptions            []string                  `json:"dns-opts,omitempty"`
95
+	DNSSearch             []string                  `json:"dns-search,omitempty"`
96
+	ExecOptions           []string                  `json:"exec-opts,omitempty"`
97
+	GraphDriver           string                    `json:"storage-driver,omitempty"`
98
+	GraphOptions          []string                  `json:"storage-opts,omitempty"`
99
+	Labels                []string                  `json:"labels,omitempty"`
100
+	Mtu                   int                       `json:"mtu,omitempty"`
101
+	NetworkDiagnosticPort int                       `json:"network-diagnostic-port,omitempty"`
102
+	Pidfile               string                    `json:"pidfile,omitempty"`
103
+	RawLogs               bool                      `json:"raw-logs,omitempty"`
104
+	RootDeprecated        string                    `json:"graph,omitempty"`
105
+	Root                  string                    `json:"data-root,omitempty"`
106
+	ExecRoot              string                    `json:"exec-root,omitempty"`
107
+	SocketGroup           string                    `json:"group,omitempty"`
108
+	CorsHeaders           string                    `json:"api-cors-header,omitempty"`
108 109
 
109 110
 	// TrustKeyPath is used to generate the daemon ID and for signing schema 1 manifests
110 111
 	// when pushing to a registry which does not support schema 2. This field is marked as
... ...
@@ -61,6 +61,9 @@ func (daemon *Daemon) Reload(conf *config.Config) (err error) {
61 61
 	if err := daemon.reloadLiveRestore(conf, attributes); err != nil {
62 62
 		return err
63 63
 	}
64
+	if err := daemon.reloadNetworkDiagnosticPort(conf, attributes); err != nil {
65
+		return err
66
+	}
64 67
 	return nil
65 68
 }
66 69
 
... ...
@@ -308,3 +311,18 @@ func (daemon *Daemon) reloadLiveRestore(conf *config.Config, attributes map[stri
308 308
 	attributes["live-restore"] = fmt.Sprintf("%t", daemon.configStore.LiveRestoreEnabled)
309 309
 	return nil
310 310
 }
311
+
312
+// reloadNetworkDiagnosticPort updates the network controller starting the diagnose mode if the config is valid
313
+func (daemon *Daemon) reloadNetworkDiagnosticPort(conf *config.Config, attributes map[string]string) error {
314
+	if conf == nil || daemon.netController == nil {
315
+		return nil
316
+	}
317
+	// Enable the network diagnose if the flag is set with a valid port withing the range
318
+	if conf.IsValueSet("network-diagnostic-port") && conf.NetworkDiagnosticPort > 0 && conf.NetworkDiagnosticPort < 65536 {
319
+		logrus.Warnf("Calling the diagnostic start with %d", conf.NetworkDiagnosticPort)
320
+		daemon.netController.StartDiagnose(conf.NetworkDiagnosticPort)
321
+	} else {
322
+		daemon.netController.StopDiagnose()
323
+	}
324
+	return nil
325
+}
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	"github.com/docker/docker/pkg/discovery"
11 11
 	_ "github.com/docker/docker/pkg/discovery/memory"
12 12
 	"github.com/docker/docker/registry"
13
+	"github.com/docker/libnetwork"
13 14
 	"github.com/stretchr/testify/assert"
14 15
 )
15 16
 
... ...
@@ -479,3 +480,71 @@ func TestDaemonDiscoveryReloadOnlyClusterAdvertise(t *testing.T) {
479 479
 		t.Fatal(e)
480 480
 	}
481 481
 }
482
+
483
+func TestDaemonReloadNetworkDiagnosticPort(t *testing.T) {
484
+	daemon := &Daemon{}
485
+	daemon.configStore = &config.Config{}
486
+
487
+	valuesSet := make(map[string]interface{})
488
+	valuesSet["network-diagnostic-port"] = 2000
489
+	enableConfig := &config.Config{
490
+		CommonConfig: config.CommonConfig{
491
+			NetworkDiagnosticPort: 2000,
492
+			ValuesSet:             valuesSet,
493
+		},
494
+	}
495
+	disableConfig := &config.Config{
496
+		CommonConfig: config.CommonConfig{},
497
+	}
498
+
499
+	netOptions, err := daemon.networkOptions(enableConfig, nil, nil)
500
+	if err != nil {
501
+		t.Fatal(err)
502
+	}
503
+	controller, err := libnetwork.New(netOptions...)
504
+	if err != nil {
505
+		t.Fatal(err)
506
+	}
507
+	daemon.netController = controller
508
+
509
+	// Enable/Disable the server for some iterations
510
+	for i := 0; i < 10; i++ {
511
+		enableConfig.CommonConfig.NetworkDiagnosticPort++
512
+		if err := daemon.Reload(enableConfig); err != nil {
513
+			t.Fatal(err)
514
+		}
515
+		// Check that the diagnose is enabled
516
+		if !daemon.netController.IsDiagnoseEnabled() {
517
+			t.Fatalf("diagnosed should be enable")
518
+		}
519
+
520
+		// Reload
521
+		if err := daemon.Reload(disableConfig); err != nil {
522
+			t.Fatal(err)
523
+		}
524
+		// Check that the diagnose is disabled
525
+		if daemon.netController.IsDiagnoseEnabled() {
526
+			t.Fatalf("diagnosed should be disable")
527
+		}
528
+	}
529
+
530
+	enableConfig.CommonConfig.NetworkDiagnosticPort++
531
+	// 2 times the enable should not create problems
532
+	if err := daemon.Reload(enableConfig); err != nil {
533
+		t.Fatal(err)
534
+	}
535
+	// Check that the diagnose is enabled
536
+	if !daemon.netController.IsDiagnoseEnabled() {
537
+		t.Fatalf("diagnosed should be enable")
538
+	}
539
+
540
+	// Check that another reload does not cause issues
541
+	if err := daemon.Reload(enableConfig); err != nil {
542
+		t.Fatal(err)
543
+	}
544
+	// Check that the diagnose is enable
545
+	if !daemon.netController.IsDiagnoseEnabled() {
546
+		t.Fatalf("diagnosed should be enable")
547
+	}
548
+
549
+}