Browse code

Moved the TOML based Configuration to dnet

The configuration format for docker runtime is based on daemon flags and
hence adjusting the libnetwork configuration to accomodate it by moving
the TOML based configuration to the dnet tool.

Also changed the controller configuration via options

Signed-off-by: Madhu Venugopal <madhu@docker.com>

Madhu Venugopal authored on 2015/06/11 22:52:46
Showing 12 changed files
... ...
@@ -18,7 +18,7 @@ There are many networking solutions available to suit a broad range of use-cases
18 18
 
19 19
 ```go
20 20
         // Create a new controller instance
21
-        controller := libnetwork.New("/etc/default/libnetwork.toml")
21
+        controller := libnetwork.New()
22 22
 
23 23
         // Select and configure the network driver
24 24
         networkType := "bridge"
... ...
@@ -79,7 +79,7 @@ func i2cL(i interface{}) []*containerResource {
79 79
 }
80 80
 
81 81
 func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkController, libnetwork.Network) {
82
-	c, err := libnetwork.New("")
82
+	c, err := libnetwork.New()
83 83
 	if err != nil {
84 84
 		t.Fatal(err)
85 85
 	}
... ...
@@ -174,7 +174,7 @@ func TestJson(t *testing.T) {
174 174
 func TestCreateDeleteNetwork(t *testing.T) {
175 175
 	defer netutils.SetupTestNetNS(t)()
176 176
 
177
-	c, err := libnetwork.New("")
177
+	c, err := libnetwork.New()
178 178
 	if err != nil {
179 179
 		t.Fatal(err)
180 180
 	}
... ...
@@ -252,7 +252,7 @@ func TestCreateDeleteNetwork(t *testing.T) {
252 252
 func TestGetNetworksAndEndpoints(t *testing.T) {
253 253
 	defer netutils.SetupTestNetNS(t)()
254 254
 
255
-	c, err := libnetwork.New("")
255
+	c, err := libnetwork.New()
256 256
 	if err != nil {
257 257
 		t.Fatal(err)
258 258
 	}
... ...
@@ -525,7 +525,7 @@ func TestGetNetworksAndEndpoints(t *testing.T) {
525 525
 func TestProcGetServices(t *testing.T) {
526 526
 	defer netutils.SetupTestNetNS(t)()
527 527
 
528
-	c, err := libnetwork.New("")
528
+	c, err := libnetwork.New()
529 529
 	if err != nil {
530 530
 		t.Fatal(err)
531 531
 	}
... ...
@@ -1001,7 +1001,7 @@ func TestAttachDetachBackend(t *testing.T) {
1001 1001
 }
1002 1002
 
1003 1003
 func TestDetectGetNetworksInvalidQueryComposition(t *testing.T) {
1004
-	c, err := libnetwork.New("")
1004
+	c, err := libnetwork.New()
1005 1005
 	if err != nil {
1006 1006
 		t.Fatal(err)
1007 1007
 	}
... ...
@@ -1108,7 +1108,7 @@ func TestFindNetworkUtil(t *testing.T) {
1108 1108
 func TestCreateDeleteEndpoints(t *testing.T) {
1109 1109
 	defer netutils.SetupTestNetNS(t)()
1110 1110
 
1111
-	c, err := libnetwork.New("")
1111
+	c, err := libnetwork.New()
1112 1112
 	if err != nil {
1113 1113
 		t.Fatal(err)
1114 1114
 	}
... ...
@@ -1234,7 +1234,7 @@ func TestCreateDeleteEndpoints(t *testing.T) {
1234 1234
 func TestJoinLeave(t *testing.T) {
1235 1235
 	defer netutils.SetupTestNetNS(t)()
1236 1236
 
1237
-	c, err := libnetwork.New("")
1237
+	c, err := libnetwork.New()
1238 1238
 	if err != nil {
1239 1239
 		t.Fatal(err)
1240 1240
 	}
... ...
@@ -1674,7 +1674,7 @@ func TestwriteJSON(t *testing.T) {
1674 1674
 func TestHttpHandlerUninit(t *testing.T) {
1675 1675
 	defer netutils.SetupTestNetNS(t)()
1676 1676
 
1677
-	c, err := libnetwork.New("")
1677
+	c, err := libnetwork.New()
1678 1678
 	if err != nil {
1679 1679
 		t.Fatal(err)
1680 1680
 	}
... ...
@@ -1740,7 +1740,7 @@ func TestHttpHandlerBadBody(t *testing.T) {
1740 1740
 
1741 1741
 	rsp := newWriter()
1742 1742
 
1743
-	c, err := libnetwork.New("")
1743
+	c, err := libnetwork.New()
1744 1744
 	if err != nil {
1745 1745
 		t.Fatal(err)
1746 1746
 	}
... ...
@@ -1772,7 +1772,7 @@ func TestEndToEnd(t *testing.T) {
1772 1772
 
1773 1773
 	rsp := newWriter()
1774 1774
 
1775
-	c, err := libnetwork.New("")
1775
+	c, err := libnetwork.New()
1776 1776
 	if err != nil {
1777 1777
 		t.Fatal(err)
1778 1778
 	}
... ...
@@ -15,8 +15,8 @@ var (
15 15
 	serviceCommands = []command{
16 16
 		{"publish", "Publish a service"},
17 17
 		{"unpublish", "Remove a service"},
18
-		{"attach", "Attach a provider (container) to the service"},
19
-		{"detach", "Detach the provider from the service"},
18
+		{"attach", "Attach a backend (container) to the service"},
19
+		{"detach", "Detach the backend from the service"},
20 20
 		{"ls", "Lists all services"},
21 21
 		{"info", "Display information about a service"},
22 22
 	}
... ...
@@ -189,7 +189,7 @@ func (cli *NetworkCli) CmdServiceLs(chain string, args ...string) error {
189 189
 	wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
190 190
 	// unless quiet (-q) is specified, print field titles
191 191
 	if !*quiet {
192
-		fmt.Fprintln(wr, "SERVICE ID\tNAME\tNETWORK\tPROVIDER")
192
+		fmt.Fprintln(wr, "SERVICE ID\tNAME\tNETWORK\tCONTAINER")
193 193
 	}
194 194
 
195 195
 	for _, sr := range serviceResources {
... ...
@@ -228,7 +228,7 @@ func getBackendID(cli *NetworkCli, servID string) (string, error) {
228 228
 			}
229 229
 		} else {
230 230
 			// Only print a message, don't make the caller cli fail for this
231
-			fmt.Fprintf(cli.out, "Failed to retrieve provider list for service %s (%v)", servID, err)
231
+			fmt.Fprintf(cli.out, "Failed to retrieve backend list for service %s (%v)", servID, err)
232 232
 		}
233 233
 	}
234 234
 
... ...
@@ -19,16 +19,19 @@ import (
19 19
 	"github.com/docker/libnetwork"
20 20
 	"github.com/docker/libnetwork/api"
21 21
 	"github.com/docker/libnetwork/client"
22
+	"github.com/docker/libnetwork/config"
22 23
 	"github.com/gorilla/mux"
23 24
 )
24 25
 
25
-var (
26
+const (
26 27
 	// DefaultHTTPHost is used if only port is provided to -H flag e.g. docker -d -H tcp://:8080
27 28
 	DefaultHTTPHost = "127.0.0.1"
28 29
 	// DefaultHTTPPort is the default http port used by dnet
29 30
 	DefaultHTTPPort = 2385
30 31
 	// DefaultUnixSocket exported
31 32
 	DefaultUnixSocket = "/var/run/dnet.sock"
33
+	cfgFileEnv        = "LIBNETWORK_CFG"
34
+	defaultCfgFile    = "/etc/default/libnetwork.toml"
32 35
 )
33 36
 
34 37
 func main() {
... ...
@@ -45,6 +48,36 @@ func main() {
45 45
 	}
46 46
 }
47 47
 
48
+func parseConfig(cfgFile string) (*config.Config, error) {
49
+	if strings.Trim(cfgFile, " ") == "" {
50
+		cfgFile = os.Getenv(cfgFileEnv)
51
+		if strings.Trim(cfgFile, " ") == "" {
52
+			cfgFile = defaultCfgFile
53
+		}
54
+	}
55
+	return config.ParseConfig(cfgFile)
56
+}
57
+
58
+func processConfig(cfg *config.Config) []config.Option {
59
+	options := []config.Option{}
60
+	if cfg == nil {
61
+		return options
62
+	}
63
+	if strings.TrimSpace(cfg.Daemon.DefaultNetwork) != "" {
64
+		options = append(options, config.OptionDefaultNetwork(cfg.Daemon.DefaultNetwork))
65
+	}
66
+	if strings.TrimSpace(cfg.Daemon.DefaultDriver) != "" {
67
+		options = append(options, config.OptionDefaultDriver(cfg.Daemon.DefaultDriver))
68
+	}
69
+	if strings.TrimSpace(cfg.Datastore.Client.Provider) != "" {
70
+		options = append(options, config.OptionKVProvider(cfg.Datastore.Client.Provider))
71
+	}
72
+	if strings.TrimSpace(cfg.Datastore.Client.Address) != "" {
73
+		options = append(options, config.OptionKVProviderURL(cfg.Datastore.Client.Address))
74
+	}
75
+	return options
76
+}
77
+
48 78
 func dnetCommand(stdout, stderr io.Writer) error {
49 79
 	flag.Parse()
50 80
 
... ...
@@ -111,7 +144,12 @@ type dnetConnection struct {
111 111
 }
112 112
 
113 113
 func (d *dnetConnection) dnetDaemon() error {
114
-	controller, err := libnetwork.New("")
114
+	cfg, err := parseConfig(*flCfgFile)
115
+	var cOptions []config.Option
116
+	if err == nil {
117
+		cOptions = processConfig(cfg)
118
+	}
119
+	controller, err := libnetwork.New(cOptions...)
115 120
 	if err != nil {
116 121
 		fmt.Println("Error starting dnetDaemon :", err)
117 122
 		return err
... ...
@@ -19,6 +19,7 @@ var (
19 19
 	flHost     = flag.String([]string{"H", "-host"}, "", "Daemon socket to connect to")
20 20
 	flLogLevel = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level")
21 21
 	flDebug    = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
22
+	flCfgFile  = flag.String([]string{"c", "-cfg-file"}, "/etc/default/libnetwork.toml", "Configuration file")
22 23
 	flHelp     = flag.Bool([]string{"h", "-help"}, false, "Print usage")
23 24
 
24 25
 	dnetCommands = []command{
... ...
@@ -11,7 +11,7 @@ import (
11 11
 
12 12
 func main() {
13 13
 	// Create a new controller instance
14
-	controller, err := libnetwork.New("/etc/default/libnetwork.toml")
14
+	controller, err := libnetwork.New()
15 15
 	if err != nil {
16 16
 		return
17 17
 	}
... ...
@@ -3,7 +3,6 @@ package main
3 3
 import (
4 4
 	"fmt"
5 5
 	"net"
6
-	"os"
7 6
 	"time"
8 7
 
9 8
 	log "github.com/Sirupsen/logrus"
... ...
@@ -14,8 +13,7 @@ import (
14 14
 
15 15
 func main() {
16 16
 	log.SetLevel(log.DebugLevel)
17
-	os.Setenv("LIBNETWORK_CFG", "libnetwork.toml")
18
-	controller, err := libnetwork.New("libnetwork.toml")
17
+	controller, err := libnetwork.New()
19 18
 	if err != nil {
20 19
 		log.Fatal(err)
21 20
 	}
... ...
@@ -1,6 +1,10 @@
1 1
 package config
2 2
 
3
-import "github.com/BurntSushi/toml"
3
+import (
4
+	"strings"
5
+
6
+	"github.com/BurntSushi/toml"
7
+)
4 8
 
5 9
 // Config encapsulates configurations of various Libnetwork components
6 10
 type Config struct {
... ...
@@ -11,7 +15,9 @@ type Config struct {
11 11
 
12 12
 // DaemonCfg represents libnetwork core configuration
13 13
 type DaemonCfg struct {
14
-	Debug bool
14
+	Debug          bool
15
+	DefaultNetwork string
16
+	DefaultDriver  string
15 17
 }
16 18
 
17 19
 // ClusterCfg represents cluster configuration
... ...
@@ -41,3 +47,44 @@ func ParseConfig(tomlCfgFile string) (*Config, error) {
41 41
 	}
42 42
 	return &cfg, nil
43 43
 }
44
+
45
+// Option is a option setter function type used to pass varios configurations
46
+// to the controller
47
+type Option func(c *Config)
48
+
49
+// OptionDefaultNetwork function returns an option setter for a default network
50
+func OptionDefaultNetwork(dn string) Option {
51
+	return func(c *Config) {
52
+		c.Daemon.DefaultNetwork = strings.TrimSpace(dn)
53
+	}
54
+}
55
+
56
+// OptionDefaultDriver function returns an option setter for default driver
57
+func OptionDefaultDriver(dd string) Option {
58
+	return func(c *Config) {
59
+		c.Daemon.DefaultDriver = strings.TrimSpace(dd)
60
+	}
61
+}
62
+
63
+// OptionKVProvider function returns an option setter for kvstore provider
64
+func OptionKVProvider(provider string) Option {
65
+	return func(c *Config) {
66
+		c.Datastore.Client.Provider = strings.TrimSpace(provider)
67
+	}
68
+}
69
+
70
+// OptionKVProviderURL function returns an option setter for kvstore url
71
+func OptionKVProviderURL(url string) Option {
72
+	return func(c *Config) {
73
+		c.Datastore.Client.Address = strings.TrimSpace(url)
74
+	}
75
+}
76
+
77
+// ProcessOptions processes options and stores it in config
78
+func (c *Config) ProcessOptions(options ...Option) {
79
+	for _, opt := range options {
80
+		if opt != nil {
81
+			opt(c)
82
+		}
83
+	}
84
+}
... ...
@@ -3,7 +3,7 @@ Package libnetwork provides the basic functionality and extension points to
3 3
 create network namespaces and allocate interfaces for containers to use.
4 4
 
5 5
         // Create a new controller instance
6
-        controller, _err := libnetwork.New("/etc/default/libnetwork.toml")
6
+        controller, _err := libnetwork.New(nil)
7 7
 
8 8
         // Select and configure the network driver
9 9
         networkType := "bridge"
... ...
@@ -47,8 +47,6 @@ package libnetwork
47 47
 import (
48 48
 	"fmt"
49 49
 	"net"
50
-	"os"
51
-	"strings"
52 50
 	"sync"
53 51
 
54 52
 	log "github.com/Sirupsen/logrus"
... ...
@@ -68,6 +66,9 @@ type NetworkController interface {
68 68
 	// ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
69 69
 	ConfigureNetworkDriver(networkType string, options map[string]interface{}) error
70 70
 
71
+	// Config method returns the bootup configuration for the controller
72
+	Config() config.Config
73
+
71 74
 	// Create a new network. The options parameter carries network specific options.
72 75
 	// Labels support will be added in the near future.
73 76
 	NewNetwork(networkType, name string, options ...NetworkOption) (Network, error)
... ...
@@ -112,8 +113,14 @@ type controller struct {
112 112
 }
113 113
 
114 114
 // New creates a new instance of network controller.
115
-func New(configFile string) (NetworkController, error) {
115
+func New(cfgOptions ...config.Option) (NetworkController, error) {
116
+	var cfg *config.Config
117
+	if len(cfgOptions) > 0 {
118
+		cfg = &config.Config{}
119
+		cfg.ProcessOptions(cfgOptions...)
120
+	}
116 121
 	c := &controller{
122
+		cfg:       cfg,
117 123
 		networks:  networkTable{},
118 124
 		sandboxes: sandboxTable{},
119 125
 		drivers:   driverTable{}}
... ...
@@ -121,47 +128,27 @@ func New(configFile string) (NetworkController, error) {
121 121
 		return nil, err
122 122
 	}
123 123
 
124
-	if err := c.initConfig(configFile); err == nil {
124
+	if cfg != nil {
125 125
 		if err := c.initDataStore(); err != nil {
126 126
 			// Failing to initalize datastore is a bad situation to be in.
127 127
 			// But it cannot fail creating the Controller
128
-			log.Warnf("Failed to Initialize Datastore due to %v. Operating in non-clustered mode", err)
128
+			log.Debugf("Failed to Initialize Datastore due to %v. Operating in non-clustered mode", err)
129 129
 		}
130 130
 		if err := c.initDiscovery(); err != nil {
131 131
 			// Failing to initalize discovery is a bad situation to be in.
132 132
 			// But it cannot fail creating the Controller
133
-			log.Warnf("Failed to Initialize Discovery : %v", err)
133
+			log.Debugf("Failed to Initialize Discovery : %v", err)
134 134
 		}
135
-	} else {
136
-		// Missing Configuration file is not a failure scenario
137
-		// But without that, datastore cannot be initialized.
138
-		log.Debugf("Unable to Parse LibNetwork Config file : %v", err)
139 135
 	}
140 136
 
141 137
 	return c, nil
142 138
 }
143 139
 
144
-const (
145
-	cfgFileEnv     = "LIBNETWORK_CFG"
146
-	defaultCfgFile = "/etc/default/libnetwork.toml"
147
-)
148
-
149
-func (c *controller) initConfig(configFile string) error {
150
-	cfgFile := configFile
151
-	if strings.Trim(cfgFile, " ") == "" {
152
-		cfgFile = os.Getenv(cfgFileEnv)
153
-		if strings.Trim(cfgFile, " ") == "" {
154
-			cfgFile = defaultCfgFile
155
-		}
156
-	}
157
-	cfg, err := config.ParseConfig(cfgFile)
158
-	if err != nil {
159
-		return ErrInvalidConfigFile(cfgFile)
140
+func (c *controller) validateHostDiscoveryConfig() bool {
141
+	if c.cfg == nil || c.cfg.Cluster.Discovery == "" || c.cfg.Cluster.Address == "" {
142
+		return false
160 143
 	}
161
-	c.Lock()
162
-	c.cfg = cfg
163
-	c.Unlock()
164
-	return nil
144
+	return true
165 145
 }
166 146
 
167 147
 func (c *controller) initDiscovery() error {
... ...
@@ -179,6 +166,12 @@ func (c *controller) hostJoinCallback(hosts []net.IP) {
179 179
 func (c *controller) hostLeaveCallback(hosts []net.IP) {
180 180
 }
181 181
 
182
+func (c *controller) Config() config.Config {
183
+	c.Lock()
184
+	defer c.Unlock()
185
+	return *c.cfg
186
+}
187
+
182 188
 func (c *controller) ConfigureNetworkDriver(networkType string, options map[string]interface{}) error {
183 189
 	c.Lock()
184 190
 	dd, ok := c.drivers[networkType]
... ...
@@ -9,7 +9,7 @@ import (
9 9
 
10 10
 func TestDriverRegistration(t *testing.T) {
11 11
 	bridgeNetType := "bridge"
12
-	c, err := New("")
12
+	c, err := New()
13 13
 	if err != nil {
14 14
 		t.Fatal(err)
15 15
 	}
... ...
@@ -63,7 +63,7 @@ func TestMain(m *testing.M) {
63 63
 func createController() error {
64 64
 	var err error
65 65
 
66
-	controller, err = libnetwork.New("")
66
+	controller, err = libnetwork.New()
67 67
 	if err != nil {
68 68
 		return err
69 69
 	}
... ...
@@ -1665,7 +1665,7 @@ func TestInvalidRemoteDriver(t *testing.T) {
1665 1665
 		t.Fatal(err)
1666 1666
 	}
1667 1667
 
1668
-	controller, err := libnetwork.New("")
1668
+	controller, err := libnetwork.New()
1669 1669
 	if err != nil {
1670 1670
 		t.Fatal(err)
1671 1671
 	}
... ...
@@ -9,11 +9,18 @@ import (
9 9
 	"github.com/docker/libnetwork/types"
10 10
 )
11 11
 
12
+func (c *controller) validateDatastoreConfig() bool {
13
+	if c.cfg == nil || c.cfg.Datastore.Client.Provider == "" || c.cfg.Datastore.Client.Address == "" {
14
+		return false
15
+	}
16
+	return true
17
+}
18
+
12 19
 func (c *controller) initDataStore() error {
13 20
 	c.Lock()
14 21
 	cfg := c.cfg
15 22
 	c.Unlock()
16
-	if cfg == nil {
23
+	if !c.validateDatastoreConfig() {
17 24
 		return fmt.Errorf("datastore initialization requires a valid configuration")
18 25
 	}
19 26