Browse code

Fix configuration reloading

There are five options 'debug' 'labels' 'cluster-store' 'cluster-store-opts'
and 'cluster-advertise' that can be reconfigured, configure any of these
options should not affect other options which may have configured in flags.
But this is not true, for example, I start a daemon with -D to enable the
debugging, and after a while, I want reconfigure the 'label', so I add a file
'/etc/docker/daemon.json' with content '"labels":["test"]' and send SIGHUP to daemon
to reconfigure the daemon, it work, but the debugging of the daemon is also diabled.
I don't think this is a expeted behaviour.
This patch also have some minor refactor of reconfiguration of cluster-advertiser.
Enable user to reconfigure cluster-advertiser without cluster-store in config file
since cluster-store could also be already set in flag, and we only want to reconfigure
the cluster-advertiser.

Signed-off-by: Lei Jitang <leijitang@huawei.com>

Lei Jitang authored on 2016/02/24 17:13:44
Showing 4 changed files
... ...
@@ -1602,24 +1602,37 @@ func (daemon *Daemon) initDiscovery(config *Config) error {
1602 1602
 func (daemon *Daemon) Reload(config *Config) error {
1603 1603
 	daemon.configStore.reloadLock.Lock()
1604 1604
 	defer daemon.configStore.reloadLock.Unlock()
1605
-	daemon.configStore.Labels = config.Labels
1605
+	if config.IsValueSet("label") {
1606
+		daemon.configStore.Labels = config.Labels
1607
+	}
1608
+	if config.IsValueSet("debug") {
1609
+		daemon.configStore.Debug = config.Debug
1610
+	}
1606 1611
 	return daemon.reloadClusterDiscovery(config)
1607 1612
 }
1608 1613
 
1609 1614
 func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
1610
-	newAdvertise, err := parseClusterAdvertiseSettings(config.ClusterStore, config.ClusterAdvertise)
1611
-	if err != nil && err != errDiscoveryDisabled {
1612
-		return err
1615
+	var err error
1616
+	newAdvertise := daemon.configStore.ClusterAdvertise
1617
+	newClusterStore := daemon.configStore.ClusterStore
1618
+	if config.IsValueSet("cluster-advertise") {
1619
+		if config.IsValueSet("cluster-store") {
1620
+			newClusterStore = config.ClusterStore
1621
+		}
1622
+		newAdvertise, err = parseClusterAdvertiseSettings(newClusterStore, config.ClusterAdvertise)
1623
+		if err != nil && err != errDiscoveryDisabled {
1624
+			return err
1625
+		}
1613 1626
 	}
1614 1627
 
1615 1628
 	// check discovery modifications
1616
-	if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, config.ClusterStore, config.ClusterOpts) {
1629
+	if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, config.ClusterOpts) {
1617 1630
 		return nil
1618 1631
 	}
1619 1632
 
1620 1633
 	// enable discovery for the first time if it was not previously enabled
1621 1634
 	if daemon.discoveryWatcher == nil {
1622
-		discoveryWatcher, err := initDiscovery(config.ClusterStore, newAdvertise, config.ClusterOpts)
1635
+		discoveryWatcher, err := initDiscovery(newClusterStore, newAdvertise, config.ClusterOpts)
1623 1636
 		if err != nil {
1624 1637
 			return fmt.Errorf("discovery initialization failed (%v)", err)
1625 1638
 		}
... ...
@@ -1636,7 +1649,7 @@ func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
1636 1636
 		}
1637 1637
 	}
1638 1638
 
1639
-	daemon.configStore.ClusterStore = config.ClusterStore
1639
+	daemon.configStore.ClusterStore = newClusterStore
1640 1640
 	daemon.configStore.ClusterOpts = config.ClusterOpts
1641 1641
 	daemon.configStore.ClusterAdvertise = newAdvertise
1642 1642
 
... ...
@@ -315,9 +315,12 @@ func TestDaemonReloadLabels(t *testing.T) {
315 315
 		},
316 316
 	}
317 317
 
318
+	valuesSets := make(map[string]interface{})
319
+	valuesSets["label"] = "foo:baz"
318 320
 	newConfig := &Config{
319 321
 		CommonConfig: CommonConfig{
320
-			Labels: []string{"foo:baz"},
322
+			Labels:    []string{"foo:baz"},
323
+			valuesSet: valuesSets,
321 324
 		},
322 325
 	}
323 326
 
... ...
@@ -328,6 +331,35 @@ func TestDaemonReloadLabels(t *testing.T) {
328 328
 	}
329 329
 }
330 330
 
331
+func TestDaemonReloadNotAffectOthers(t *testing.T) {
332
+	daemon := &Daemon{}
333
+	daemon.configStore = &Config{
334
+		CommonConfig: CommonConfig{
335
+			Labels: []string{"foo:bar"},
336
+			Debug:  true,
337
+		},
338
+	}
339
+
340
+	valuesSets := make(map[string]interface{})
341
+	valuesSets["label"] = "foo:baz"
342
+	newConfig := &Config{
343
+		CommonConfig: CommonConfig{
344
+			Labels:    []string{"foo:baz"},
345
+			valuesSet: valuesSets,
346
+		},
347
+	}
348
+
349
+	daemon.Reload(newConfig)
350
+	label := daemon.configStore.Labels[0]
351
+	if label != "foo:baz" {
352
+		t.Fatalf("Expected daemon label `foo:baz`, got %s", label)
353
+	}
354
+	debug := daemon.configStore.Debug
355
+	if !debug {
356
+		t.Fatalf("Expected debug 'enabled', got 'disabled'")
357
+	}
358
+}
359
+
331 360
 func TestDaemonDiscoveryReload(t *testing.T) {
332 361
 	daemon := &Daemon{}
333 362
 	daemon.configStore = &Config{
... ...
@@ -360,10 +392,14 @@ func TestDaemonDiscoveryReload(t *testing.T) {
360 360
 		t.Fatal(e)
361 361
 	}
362 362
 
363
+	valuesSets := make(map[string]interface{})
364
+	valuesSets["cluster-store"] = "memory://127.0.0.1:2222"
365
+	valuesSets["cluster-advertise"] = "127.0.0.1:5555"
363 366
 	newConfig := &Config{
364 367
 		CommonConfig: CommonConfig{
365 368
 			ClusterStore:     "memory://127.0.0.1:2222",
366 369
 			ClusterAdvertise: "127.0.0.1:5555",
370
+			valuesSet:        valuesSets,
367 371
 		},
368 372
 	}
369 373
 
... ...
@@ -392,10 +428,14 @@ func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) {
392 392
 	daemon := &Daemon{}
393 393
 	daemon.configStore = &Config{}
394 394
 
395
+	valuesSet := make(map[string]interface{})
396
+	valuesSet["cluster-store"] = "memory://127.0.0.1:2222"
397
+	valuesSet["cluster-advertise"] = "127.0.0.1:5555"
395 398
 	newConfig := &Config{
396 399
 		CommonConfig: CommonConfig{
397 400
 			ClusterStore:     "memory://127.0.0.1:2222",
398 401
 			ClusterAdvertise: "127.0.0.1:5555",
402
+			valuesSet:        valuesSet,
399 403
 		},
400 404
 	}
401 405
 
... ...
@@ -421,3 +461,42 @@ func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) {
421 421
 		t.Fatal(e)
422 422
 	}
423 423
 }
424
+
425
+func TestDaemonDiscoveryReloadOnlyClusterAdvertise(t *testing.T) {
426
+	daemon := &Daemon{}
427
+	daemon.configStore = &Config{
428
+		CommonConfig: CommonConfig{
429
+			ClusterStore: "memory://127.0.0.1",
430
+		},
431
+	}
432
+	valuesSets := make(map[string]interface{})
433
+	valuesSets["cluster-advertise"] = "127.0.0.1:5555"
434
+	newConfig := &Config{
435
+		CommonConfig: CommonConfig{
436
+			ClusterAdvertise: "127.0.0.1:5555",
437
+			valuesSet:        valuesSets,
438
+		},
439
+	}
440
+	expected := discovery.Entries{
441
+		&discovery.Entry{Host: "127.0.0.1", Port: "5555"},
442
+	}
443
+
444
+	if err := daemon.Reload(newConfig); err != nil {
445
+		t.Fatal(err)
446
+	}
447
+	stopCh := make(chan struct{})
448
+	defer close(stopCh)
449
+	ch, errCh := daemon.discoveryWatcher.Watch(stopCh)
450
+
451
+	select {
452
+	case <-time.After(1 * time.Second):
453
+		t.Fatal("failed to get discovery advertisements in time")
454
+	case e := <-ch:
455
+		if !reflect.DeepEqual(e, expected) {
456
+			t.Fatalf("expected %v, got %v\n", expected, e)
457
+		}
458
+	case e := <-errCh:
459
+		t.Fatal(e)
460
+	}
461
+
462
+}
... ...
@@ -289,15 +289,17 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
289 289
 			logrus.Errorf("Error reconfiguring the daemon: %v", err)
290 290
 			return
291 291
 		}
292
+		if config.IsValueSet("debug") {
293
+			debugEnabled := utils.IsDebugEnabled()
294
+			switch {
295
+			case debugEnabled && !config.Debug: // disable debug
296
+				utils.DisableDebug()
297
+				api.DisableProfiler()
298
+			case config.Debug && !debugEnabled: // enable debug
299
+				utils.EnableDebug()
300
+				api.EnableProfiler()
301
+			}
292 302
 
293
-		debugEnabled := utils.IsDebugEnabled()
294
-		switch {
295
-		case debugEnabled && !config.Debug: // disable debug
296
-			utils.DisableDebug()
297
-			api.DisableProfiler()
298
-		case config.Debug && !debugEnabled: // enable debug
299
-			utils.EnableDebug()
300
-			api.EnableProfiler()
301 303
 		}
302 304
 	}
303 305
 
... ...
@@ -896,6 +896,8 @@ The list of currently supported options that can be reconfigured is this:
896 896
 
897 897
 Updating and reloading the cluster configurations such as `--cluster-store`,
898 898
 `--cluster-advertise` and `--cluster-store-opts` will take effect only if
899
-these configurations were not previously configured. Configuration reload will
900
-log a warning message if it detects a change in previously configured cluster
901
-configurations.
899
+these configurations were not previously configured. If `--cluster-store`
900
+has been provided in flags and `cluster-advertise` not, `cluster-advertise`
901
+can be added in the configuration file without accompanied by `--cluster-store`
902
+Configuration reload will log a warning message if it detects a change in
903
+previously configured cluster configurations.