Browse code

Allow network configuration via daemon config file.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2016/01/26 06:30:33
Showing 9 changed files
... ...
@@ -45,7 +45,6 @@ type CommonTLSOptions struct {
45 45
 type CommonConfig struct {
46 46
 	AuthorizationPlugins []string            `json:"authorization-plugins,omitempty"` // AuthorizationPlugins holds list of authorization plugins
47 47
 	AutoRestart          bool                `json:"-"`
48
-	Bridge               bridgeConfig        `json:"-"` // Bridge holds bridge network specific configuration.
49 48
 	Context              map[string][]string `json:"-"`
50 49
 	DisableBridge        bool                `json:"-"`
51 50
 	DNS                  []string            `json:"dns,omitempty"`
... ...
@@ -85,6 +84,7 @@ type CommonConfig struct {
85 85
 	// deserialization without the full struct.
86 86
 	CommonTLSOptions
87 87
 	LogConfig
88
+	bridgeConfig // bridgeConfig holds bridge network specific configuration.
88 89
 
89 90
 	reloadLock sync.Mutex
90 91
 	valuesSet  map[string]interface{}
... ...
@@ -37,19 +37,19 @@ type Config struct {
37 37
 // bridgeConfig stores all the bridge driver specific
38 38
 // configuration.
39 39
 type bridgeConfig struct {
40
-	EnableIPv6                  bool
41
-	EnableIPTables              bool
42
-	EnableIPForward             bool
43
-	EnableIPMasq                bool
44
-	EnableUserlandProxy         bool
45
-	DefaultIP                   net.IP
46
-	Iface                       string
47
-	IP                          string
48
-	FixedCIDR                   string
49
-	FixedCIDRv6                 string
50
-	DefaultGatewayIPv4          net.IP
51
-	DefaultGatewayIPv6          net.IP
52
-	InterContainerCommunication bool
40
+	EnableIPv6                  bool   `json:"ipv6,omitempty"`
41
+	EnableIPTables              bool   `json:"iptables,omitempty"`
42
+	EnableIPForward             bool   `json:"ip-forward,omitempty"`
43
+	EnableIPMasq                bool   `json:"ip-mask,omitempty"`
44
+	EnableUserlandProxy         bool   `json:"userland-proxy,omitempty"`
45
+	DefaultIP                   net.IP `json:"ip,omitempty"`
46
+	Iface                       string `json:"bridge,omitempty"`
47
+	IP                          string `json:"bip,omitempty"`
48
+	FixedCIDR                   string `json:"fixed-cidr,omitempty"`
49
+	FixedCIDRv6                 string `json:"fixed-cidr-v6,omitempty"`
50
+	DefaultGatewayIPv4          net.IP `json:"default-gateway,omitempty"`
51
+	DefaultGatewayIPv6          net.IP `json:"default-gateway-v6,omitempty"`
52
+	InterContainerCommunication bool   `json:"icc,omitempty"`
53 53
 }
54 54
 
55 55
 // InstallFlags adds command-line options to the top-level flag parser for
... ...
@@ -65,19 +65,19 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin
65 65
 	cmd.StringVar(&config.SocketGroup, []string{"G", "-group"}, "docker", usageFn("Group for the unix socket"))
66 66
 	config.Ulimits = make(map[string]*units.Ulimit)
67 67
 	cmd.Var(runconfigopts.NewUlimitOpt(&config.Ulimits), []string{"-default-ulimit"}, usageFn("Set default ulimits for containers"))
68
-	cmd.BoolVar(&config.Bridge.EnableIPTables, []string{"#iptables", "-iptables"}, true, usageFn("Enable addition of iptables rules"))
69
-	cmd.BoolVar(&config.Bridge.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, usageFn("Enable net.ipv4.ip_forward"))
70
-	cmd.BoolVar(&config.Bridge.EnableIPMasq, []string{"-ip-masq"}, true, usageFn("Enable IP masquerading"))
71
-	cmd.BoolVar(&config.Bridge.EnableIPv6, []string{"-ipv6"}, false, usageFn("Enable IPv6 networking"))
72
-	cmd.StringVar(&config.Bridge.IP, []string{"#bip", "-bip"}, "", usageFn("Specify network bridge IP"))
73
-	cmd.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", usageFn("Attach containers to a network bridge"))
74
-	cmd.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", usageFn("IPv4 subnet for fixed IPs"))
75
-	cmd.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", usageFn("IPv6 subnet for fixed IPs"))
76
-	cmd.Var(opts.NewIPOpt(&config.Bridge.DefaultGatewayIPv4, ""), []string{"-default-gateway"}, usageFn("Container default gateway IPv4 address"))
77
-	cmd.Var(opts.NewIPOpt(&config.Bridge.DefaultGatewayIPv6, ""), []string{"-default-gateway-v6"}, usageFn("Container default gateway IPv6 address"))
78
-	cmd.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, usageFn("Enable inter-container communication"))
79
-	cmd.Var(opts.NewIPOpt(&config.Bridge.DefaultIP, "0.0.0.0"), []string{"#ip", "-ip"}, usageFn("Default IP when binding container ports"))
80
-	cmd.BoolVar(&config.Bridge.EnableUserlandProxy, []string{"-userland-proxy"}, true, usageFn("Use userland proxy for loopback traffic"))
68
+	cmd.BoolVar(&config.bridgeConfig.EnableIPTables, []string{"#iptables", "-iptables"}, true, usageFn("Enable addition of iptables rules"))
69
+	cmd.BoolVar(&config.bridgeConfig.EnableIPForward, []string{"#ip-forward", "-ip-forward"}, true, usageFn("Enable net.ipv4.ip_forward"))
70
+	cmd.BoolVar(&config.bridgeConfig.EnableIPMasq, []string{"-ip-masq"}, true, usageFn("Enable IP masquerading"))
71
+	cmd.BoolVar(&config.bridgeConfig.EnableIPv6, []string{"-ipv6"}, false, usageFn("Enable IPv6 networking"))
72
+	cmd.StringVar(&config.bridgeConfig.IP, []string{"#bip", "-bip"}, "", usageFn("Specify network bridge IP"))
73
+	cmd.StringVar(&config.bridgeConfig.Iface, []string{"b", "-bridge"}, "", usageFn("Attach containers to a network bridge"))
74
+	cmd.StringVar(&config.bridgeConfig.FixedCIDR, []string{"-fixed-cidr"}, "", usageFn("IPv4 subnet for fixed IPs"))
75
+	cmd.StringVar(&config.bridgeConfig.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", usageFn("IPv6 subnet for fixed IPs"))
76
+	cmd.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv4, ""), []string{"-default-gateway"}, usageFn("Container default gateway IPv4 address"))
77
+	cmd.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv6, ""), []string{"-default-gateway-v6"}, usageFn("Container default gateway IPv6 address"))
78
+	cmd.BoolVar(&config.bridgeConfig.InterContainerCommunication, []string{"#icc", "-icc"}, true, usageFn("Enable inter-container communication"))
79
+	cmd.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultIP, "0.0.0.0"), []string{"#ip", "-ip"}, usageFn("Default IP when binding container ports"))
80
+	cmd.BoolVar(&config.bridgeConfig.EnableUserlandProxy, []string{"-userland-proxy"}, true, usageFn("Use userland proxy for loopback traffic"))
81 81
 	cmd.BoolVar(&config.EnableCors, []string{"#api-enable-cors", "#-api-enable-cors"}, false, usageFn("Enable CORS headers in the remote API, this is deprecated by --api-cors-header"))
82 82
 	cmd.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", usageFn("Set CORS headers in the remote API"))
83 83
 	cmd.StringVar(&config.CgroupParent, []string{"-cgroup-parent"}, "", usageFn("Set parent cgroup for all containers"))
... ...
@@ -15,7 +15,7 @@ var (
15 15
 // bridgeConfig stores all the bridge driver specific
16 16
 // configuration.
17 17
 type bridgeConfig struct {
18
-	VirtualSwitchName string
18
+	VirtualSwitchName string `json:"bridge,omitempty"`
19 19
 }
20 20
 
21 21
 // Config defines the configuration of a docker daemon.
... ...
@@ -37,5 +37,5 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin
37 37
 	config.InstallCommonFlags(cmd, usageFn)
38 38
 
39 39
 	// Then platform-specific install flags.
40
-	cmd.StringVar(&config.Bridge.VirtualSwitchName, []string{"b", "-bridge"}, "", "Attach containers to a virtual switch")
40
+	cmd.StringVar(&config.bridgeConfig.VirtualSwitchName, []string{"b", "-bridge"}, "", "Attach containers to a virtual switch")
41 41
 }
... ...
@@ -513,7 +513,7 @@ func (daemon *Daemon) updateEndpointNetworkSettings(container *container.Contain
513 513
 	}
514 514
 
515 515
 	if container.HostConfig.NetworkMode == containertypes.NetworkMode("bridge") {
516
-		container.NetworkSettings.Bridge = daemon.configStore.Bridge.Iface
516
+		container.NetworkSettings.Bridge = daemon.configStore.bridgeConfig.Iface
517 517
 	}
518 518
 
519 519
 	return nil
... ...
@@ -54,7 +54,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
54 54
 		if !c.Config.NetworkDisabled {
55 55
 			en.Interface = &execdriver.NetworkInterface{
56 56
 				MacAddress:   c.Config.MacAddress,
57
-				Bridge:       daemon.configStore.Bridge.VirtualSwitchName,
57
+				Bridge:       daemon.configStore.bridgeConfig.VirtualSwitchName,
58 58
 				PortBindings: c.HostConfig.PortBindings,
59 59
 
60 60
 				// TODO Windows. Include IPAddress. There already is a
... ...
@@ -413,14 +413,14 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
413 413
 // checkConfigOptions checks for mutually incompatible config options
414 414
 func checkConfigOptions(config *Config) error {
415 415
 	// Check for mutually incompatible config options
416
-	if config.Bridge.Iface != "" && config.Bridge.IP != "" {
416
+	if config.bridgeConfig.Iface != "" && config.bridgeConfig.IP != "" {
417 417
 		return fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")
418 418
 	}
419
-	if !config.Bridge.EnableIPTables && !config.Bridge.InterContainerCommunication {
419
+	if !config.bridgeConfig.EnableIPTables && !config.bridgeConfig.InterContainerCommunication {
420 420
 		return fmt.Errorf("You specified --iptables=false with --icc=false. ICC=false uses iptables to function. Please set --icc or --iptables to true.")
421 421
 	}
422
-	if !config.Bridge.EnableIPTables && config.Bridge.EnableIPMasq {
423
-		config.Bridge.EnableIPMasq = false
422
+	if !config.bridgeConfig.EnableIPTables && config.bridgeConfig.EnableIPMasq {
423
+		config.bridgeConfig.EnableIPMasq = false
424 424
 	}
425 425
 	return nil
426 426
 }
... ...
@@ -452,7 +452,7 @@ func configureKernelSecuritySupport(config *Config, driverName string) error {
452 452
 }
453 453
 
454 454
 func isBridgeNetworkDisabled(config *Config) bool {
455
-	return config.Bridge.Iface == disableNetworkBridge
455
+	return config.bridgeConfig.Iface == disableNetworkBridge
456 456
 }
457 457
 
458 458
 func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error) {
... ...
@@ -526,9 +526,9 @@ func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkC
526 526
 
527 527
 func driverOptions(config *Config) []nwconfig.Option {
528 528
 	bridgeConfig := options.Generic{
529
-		"EnableIPForwarding":  config.Bridge.EnableIPForward,
530
-		"EnableIPTables":      config.Bridge.EnableIPTables,
531
-		"EnableUserlandProxy": config.Bridge.EnableUserlandProxy}
529
+		"EnableIPForwarding":  config.bridgeConfig.EnableIPForward,
530
+		"EnableIPTables":      config.bridgeConfig.EnableIPTables,
531
+		"EnableUserlandProxy": config.bridgeConfig.EnableUserlandProxy}
532 532
 	bridgeOption := options.Generic{netlabel.GenericData: bridgeConfig}
533 533
 
534 534
 	dOptions := []nwconfig.Option{}
... ...
@@ -544,20 +544,20 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
544 544
 	}
545 545
 
546 546
 	bridgeName := bridge.DefaultBridgeName
547
-	if config.Bridge.Iface != "" {
548
-		bridgeName = config.Bridge.Iface
547
+	if config.bridgeConfig.Iface != "" {
548
+		bridgeName = config.bridgeConfig.Iface
549 549
 	}
550 550
 	netOption := map[string]string{
551 551
 		bridge.BridgeName:         bridgeName,
552 552
 		bridge.DefaultBridge:      strconv.FormatBool(true),
553 553
 		netlabel.DriverMTU:        strconv.Itoa(config.Mtu),
554
-		bridge.EnableIPMasquerade: strconv.FormatBool(config.Bridge.EnableIPMasq),
555
-		bridge.EnableICC:          strconv.FormatBool(config.Bridge.InterContainerCommunication),
554
+		bridge.EnableIPMasquerade: strconv.FormatBool(config.bridgeConfig.EnableIPMasq),
555
+		bridge.EnableICC:          strconv.FormatBool(config.bridgeConfig.InterContainerCommunication),
556 556
 	}
557 557
 
558 558
 	// --ip processing
559
-	if config.Bridge.DefaultIP != nil {
560
-		netOption[bridge.DefaultBindingIP] = config.Bridge.DefaultIP.String()
559
+	if config.bridgeConfig.DefaultIP != nil {
560
+		netOption[bridge.DefaultBindingIP] = config.bridgeConfig.DefaultIP.String()
561 561
 	}
562 562
 
563 563
 	var (
... ...
@@ -576,9 +576,9 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
576 576
 		}
577 577
 	}
578 578
 
579
-	if config.Bridge.IP != "" {
580
-		ipamV4Conf.PreferredPool = config.Bridge.IP
581
-		ip, _, err := net.ParseCIDR(config.Bridge.IP)
579
+	if config.bridgeConfig.IP != "" {
580
+		ipamV4Conf.PreferredPool = config.bridgeConfig.IP
581
+		ip, _, err := net.ParseCIDR(config.bridgeConfig.IP)
582 582
 		if err != nil {
583 583
 			return err
584 584
 		}
... ...
@@ -587,8 +587,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
587 587
 		logrus.Infof("Default bridge (%s) is assigned with an IP address %s. Daemon option --bip can be used to set a preferred IP address", bridgeName, ipamV4Conf.PreferredPool)
588 588
 	}
589 589
 
590
-	if config.Bridge.FixedCIDR != "" {
591
-		_, fCIDR, err := net.ParseCIDR(config.Bridge.FixedCIDR)
590
+	if config.bridgeConfig.FixedCIDR != "" {
591
+		_, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR)
592 592
 		if err != nil {
593 593
 			return err
594 594
 		}
... ...
@@ -596,13 +596,13 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
596 596
 		ipamV4Conf.SubPool = fCIDR.String()
597 597
 	}
598 598
 
599
-	if config.Bridge.DefaultGatewayIPv4 != nil {
600
-		ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4.String()
599
+	if config.bridgeConfig.DefaultGatewayIPv4 != nil {
600
+		ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.bridgeConfig.DefaultGatewayIPv4.String()
601 601
 	}
602 602
 
603 603
 	var deferIPv6Alloc bool
604
-	if config.Bridge.FixedCIDRv6 != "" {
605
-		_, fCIDRv6, err := net.ParseCIDR(config.Bridge.FixedCIDRv6)
604
+	if config.bridgeConfig.FixedCIDRv6 != "" {
605
+		_, fCIDRv6, err := net.ParseCIDR(config.bridgeConfig.FixedCIDRv6)
606 606
 		if err != nil {
607 607
 			return err
608 608
 		}
... ...
@@ -632,11 +632,11 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
632 632
 		}
633 633
 	}
634 634
 
635
-	if config.Bridge.DefaultGatewayIPv6 != nil {
635
+	if config.bridgeConfig.DefaultGatewayIPv6 != nil {
636 636
 		if ipamV6Conf == nil {
637 637
 			ipamV6Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)}
638 638
 		}
639
-		ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6.String()
639
+		ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.bridgeConfig.DefaultGatewayIPv6.String()
640 640
 	}
641 641
 
642 642
 	v4Conf := []*libnetwork.IpamConf{ipamV4Conf}
... ...
@@ -648,7 +648,7 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
648 648
 	_, err = controller.NewNetwork("bridge", "bridge",
649 649
 		libnetwork.NetworkOptionGeneric(options.Generic{
650 650
 			netlabel.GenericData: netOption,
651
-			netlabel.EnableIPv6:  config.Bridge.EnableIPv6,
651
+			netlabel.EnableIPv6:  config.bridgeConfig.EnableIPv6,
652 652
 		}),
653 653
 		libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil),
654 654
 		libnetwork.NetworkOptionDeferIPv6Alloc(deferIPv6Alloc))
... ...
@@ -121,8 +121,8 @@ func isBridgeNetworkDisabled(config *Config) bool {
121 121
 
122 122
 func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) {
123 123
 	// Set the name of the virtual switch if not specified by -b on daemon start
124
-	if config.Bridge.VirtualSwitchName == "" {
125
-		config.Bridge.VirtualSwitchName = defaultVirtualSwitch
124
+	if config.bridgeConfig.VirtualSwitchName == "" {
125
+		config.bridgeConfig.VirtualSwitchName = defaultVirtualSwitch
126 126
 	}
127 127
 	return nil, nil
128 128
 }
129 129
new file mode 100644
... ...
@@ -0,0 +1,43 @@
0
+// +build daemon,!windows
1
+
2
+package main
3
+
4
+import (
5
+	"io/ioutil"
6
+	"testing"
7
+
8
+	"github.com/docker/docker/cli"
9
+	"github.com/docker/docker/daemon"
10
+	"github.com/docker/docker/pkg/mflag"
11
+)
12
+
13
+func TestLoadDaemonConfigWithNetwork(t *testing.T) {
14
+	c := &daemon.Config{}
15
+	common := &cli.CommonFlags{}
16
+	flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
17
+	flags.String([]string{"-bip"}, "", "")
18
+	flags.String([]string{"-ip"}, "", "")
19
+
20
+	f, err := ioutil.TempFile("", "docker-config-")
21
+	if err != nil {
22
+		t.Fatal(err)
23
+	}
24
+
25
+	configFile := f.Name()
26
+	f.Write([]byte(`{"bip": "127.0.0.2", "ip": "127.0.0.1"}`))
27
+	f.Close()
28
+
29
+	loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
30
+	if err != nil {
31
+		t.Fatal(err)
32
+	}
33
+	if loadedConfig == nil {
34
+		t.Fatalf("expected configuration %v, got nil", c)
35
+	}
36
+	if loadedConfig.IP != "127.0.0.2" {
37
+		t.Fatalf("expected IP 127.0.0.2, got %v", loadedConfig.IP)
38
+	}
39
+	if loadedConfig.DefaultIP.String() != "127.0.0.1" {
40
+		t.Fatalf("expected DefaultIP 127.0.0.1, got %s", loadedConfig.DefaultIP)
41
+	}
42
+}
... ...
@@ -859,7 +859,20 @@ This is a full example of the allowed configuration options in the file:
859 859
 	"userns-remap": "",
860 860
 	"group": "",
861 861
 	"cgroup-parent": "",
862
-	"default-ulimits": {}
862
+	"default-ulimits": {},
863
+       "ipv6": false,
864
+       "iptables": false,
865
+       "ip-forward": false,
866
+       "ip-mask": false,
867
+       "userland-proxy": false,
868
+       "ip": "0.0.0.0",
869
+       "bridge": "",
870
+       "bip": "",
871
+       "fixed-cidr": "",
872
+       "fixed-cidr-v6": "",
873
+       "default-gateway": "",
874
+       "default-gateway-v6": "",
875
+       "icc": false
863 876
 }
864 877
 ```
865 878