Merge pull request #289 from mavenugo/defcfg

Moved the TOML based Configuration to dnet
This commit is contained in:
Jana Radhakrishnan 2015-06-12 12:58:06 -07:00
commit 0eb856bfa5
12 changed files with 142 additions and 58 deletions

View file

@ -18,7 +18,7 @@ There are many networking solutions available to suit a broad range of use-cases
```go
// Create a new controller instance
controller := libnetwork.New("/etc/default/libnetwork.toml")
controller := libnetwork.New()
// Select and configure the network driver
networkType := "bridge"

View file

@ -79,7 +79,7 @@ func i2cL(i interface{}) []*containerResource {
}
func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkController, libnetwork.Network) {
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -174,7 +174,7 @@ func TestJson(t *testing.T) {
func TestCreateDeleteNetwork(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -252,7 +252,7 @@ func TestCreateDeleteNetwork(t *testing.T) {
func TestGetNetworksAndEndpoints(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -525,7 +525,7 @@ func TestGetNetworksAndEndpoints(t *testing.T) {
func TestProcGetServices(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -1001,7 +1001,7 @@ func TestAttachDetachBackend(t *testing.T) {
}
func TestDetectGetNetworksInvalidQueryComposition(t *testing.T) {
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -1108,7 +1108,7 @@ func TestFindNetworkUtil(t *testing.T) {
func TestCreateDeleteEndpoints(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -1234,7 +1234,7 @@ func TestCreateDeleteEndpoints(t *testing.T) {
func TestJoinLeave(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -1674,7 +1674,7 @@ func TestwriteJSON(t *testing.T) {
func TestHttpHandlerUninit(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -1740,7 +1740,7 @@ func TestHttpHandlerBadBody(t *testing.T) {
rsp := newWriter()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
@ -1772,7 +1772,7 @@ func TestEndToEnd(t *testing.T) {
rsp := newWriter()
c, err := libnetwork.New("")
c, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}

View file

@ -15,8 +15,8 @@ var (
serviceCommands = []command{
{"publish", "Publish a service"},
{"unpublish", "Remove a service"},
{"attach", "Attach a provider (container) to the service"},
{"detach", "Detach the provider from the service"},
{"attach", "Attach a backend (container) to the service"},
{"detach", "Detach the backend from the service"},
{"ls", "Lists all services"},
{"info", "Display information about a service"},
}
@ -189,7 +189,7 @@ func (cli *NetworkCli) CmdServiceLs(chain string, args ...string) error {
wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
// unless quiet (-q) is specified, print field titles
if !*quiet {
fmt.Fprintln(wr, "SERVICE ID\tNAME\tNETWORK\tPROVIDER")
fmt.Fprintln(wr, "SERVICE ID\tNAME\tNETWORK\tCONTAINER")
}
for _, sr := range serviceResources {
@ -228,7 +228,7 @@ func getBackendID(cli *NetworkCli, servID string) (string, error) {
}
} else {
// Only print a message, don't make the caller cli fail for this
fmt.Fprintf(cli.out, "Failed to retrieve provider list for service %s (%v)", servID, err)
fmt.Fprintf(cli.out, "Failed to retrieve backend list for service %s (%v)", servID, err)
}
}

View file

@ -19,16 +19,19 @@ import (
"github.com/docker/libnetwork"
"github.com/docker/libnetwork/api"
"github.com/docker/libnetwork/client"
"github.com/docker/libnetwork/config"
"github.com/gorilla/mux"
)
var (
const (
// DefaultHTTPHost is used if only port is provided to -H flag e.g. docker -d -H tcp://:8080
DefaultHTTPHost = "127.0.0.1"
// DefaultHTTPPort is the default http port used by dnet
DefaultHTTPPort = 2385
// DefaultUnixSocket exported
DefaultUnixSocket = "/var/run/dnet.sock"
cfgFileEnv = "LIBNETWORK_CFG"
defaultCfgFile = "/etc/default/libnetwork.toml"
)
func main() {
@ -45,6 +48,36 @@ func main() {
}
}
func parseConfig(cfgFile string) (*config.Config, error) {
if strings.Trim(cfgFile, " ") == "" {
cfgFile = os.Getenv(cfgFileEnv)
if strings.Trim(cfgFile, " ") == "" {
cfgFile = defaultCfgFile
}
}
return config.ParseConfig(cfgFile)
}
func processConfig(cfg *config.Config) []config.Option {
options := []config.Option{}
if cfg == nil {
return options
}
if strings.TrimSpace(cfg.Daemon.DefaultNetwork) != "" {
options = append(options, config.OptionDefaultNetwork(cfg.Daemon.DefaultNetwork))
}
if strings.TrimSpace(cfg.Daemon.DefaultDriver) != "" {
options = append(options, config.OptionDefaultDriver(cfg.Daemon.DefaultDriver))
}
if strings.TrimSpace(cfg.Datastore.Client.Provider) != "" {
options = append(options, config.OptionKVProvider(cfg.Datastore.Client.Provider))
}
if strings.TrimSpace(cfg.Datastore.Client.Address) != "" {
options = append(options, config.OptionKVProviderURL(cfg.Datastore.Client.Address))
}
return options
}
func dnetCommand(stdout, stderr io.Writer) error {
flag.Parse()
@ -111,7 +144,12 @@ type dnetConnection struct {
}
func (d *dnetConnection) dnetDaemon() error {
controller, err := libnetwork.New("")
cfg, err := parseConfig(*flCfgFile)
var cOptions []config.Option
if err == nil {
cOptions = processConfig(cfg)
}
controller, err := libnetwork.New(cOptions...)
if err != nil {
fmt.Println("Error starting dnetDaemon :", err)
return err

View file

@ -19,6 +19,7 @@ var (
flHost = flag.String([]string{"H", "-host"}, "", "Daemon socket to connect to")
flLogLevel = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level")
flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
flCfgFile = flag.String([]string{"c", "-cfg-file"}, "/etc/default/libnetwork.toml", "Configuration file")
flHelp = flag.Bool([]string{"h", "-help"}, false, "Print usage")
dnetCommands = []command{

View file

@ -11,7 +11,7 @@ import (
func main() {
// Create a new controller instance
controller, err := libnetwork.New("/etc/default/libnetwork.toml")
controller, err := libnetwork.New()
if err != nil {
return
}

View file

@ -3,7 +3,6 @@ package main
import (
"fmt"
"net"
"os"
"time"
log "github.com/Sirupsen/logrus"
@ -14,8 +13,7 @@ import (
func main() {
log.SetLevel(log.DebugLevel)
os.Setenv("LIBNETWORK_CFG", "libnetwork.toml")
controller, err := libnetwork.New("libnetwork.toml")
controller, err := libnetwork.New()
if err != nil {
log.Fatal(err)
}

View file

@ -1,6 +1,10 @@
package config
import "github.com/BurntSushi/toml"
import (
"strings"
"github.com/BurntSushi/toml"
)
// Config encapsulates configurations of various Libnetwork components
type Config struct {
@ -11,7 +15,9 @@ type Config struct {
// DaemonCfg represents libnetwork core configuration
type DaemonCfg struct {
Debug bool
Debug bool
DefaultNetwork string
DefaultDriver string
}
// ClusterCfg represents cluster configuration
@ -41,3 +47,44 @@ func ParseConfig(tomlCfgFile string) (*Config, error) {
}
return &cfg, nil
}
// Option is a option setter function type used to pass varios configurations
// to the controller
type Option func(c *Config)
// OptionDefaultNetwork function returns an option setter for a default network
func OptionDefaultNetwork(dn string) Option {
return func(c *Config) {
c.Daemon.DefaultNetwork = strings.TrimSpace(dn)
}
}
// OptionDefaultDriver function returns an option setter for default driver
func OptionDefaultDriver(dd string) Option {
return func(c *Config) {
c.Daemon.DefaultDriver = strings.TrimSpace(dd)
}
}
// OptionKVProvider function returns an option setter for kvstore provider
func OptionKVProvider(provider string) Option {
return func(c *Config) {
c.Datastore.Client.Provider = strings.TrimSpace(provider)
}
}
// OptionKVProviderURL function returns an option setter for kvstore url
func OptionKVProviderURL(url string) Option {
return func(c *Config) {
c.Datastore.Client.Address = strings.TrimSpace(url)
}
}
// ProcessOptions processes options and stores it in config
func (c *Config) ProcessOptions(options ...Option) {
for _, opt := range options {
if opt != nil {
opt(c)
}
}
}

View file

@ -3,7 +3,7 @@ Package libnetwork provides the basic functionality and extension points to
create network namespaces and allocate interfaces for containers to use.
// Create a new controller instance
controller, _err := libnetwork.New("/etc/default/libnetwork.toml")
controller, _err := libnetwork.New(nil)
// Select and configure the network driver
networkType := "bridge"
@ -47,8 +47,6 @@ package libnetwork
import (
"fmt"
"net"
"os"
"strings"
"sync"
log "github.com/Sirupsen/logrus"
@ -68,6 +66,9 @@ type NetworkController interface {
// ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
ConfigureNetworkDriver(networkType string, options map[string]interface{}) error
// Config method returns the bootup configuration for the controller
Config() config.Config
// Create a new network. The options parameter carries network specific options.
// Labels support will be added in the near future.
NewNetwork(networkType, name string, options ...NetworkOption) (Network, error)
@ -112,8 +113,14 @@ type controller struct {
}
// New creates a new instance of network controller.
func New(configFile string) (NetworkController, error) {
func New(cfgOptions ...config.Option) (NetworkController, error) {
var cfg *config.Config
if len(cfgOptions) > 0 {
cfg = &config.Config{}
cfg.ProcessOptions(cfgOptions...)
}
c := &controller{
cfg: cfg,
networks: networkTable{},
sandboxes: sandboxTable{},
drivers: driverTable{}}
@ -121,47 +128,27 @@ func New(configFile string) (NetworkController, error) {
return nil, err
}
if err := c.initConfig(configFile); err == nil {
if cfg != nil {
if err := c.initDataStore(); err != nil {
// Failing to initalize datastore is a bad situation to be in.
// But it cannot fail creating the Controller
log.Warnf("Failed to Initialize Datastore due to %v. Operating in non-clustered mode", err)
log.Debugf("Failed to Initialize Datastore due to %v. Operating in non-clustered mode", err)
}
if err := c.initDiscovery(); err != nil {
// Failing to initalize discovery is a bad situation to be in.
// But it cannot fail creating the Controller
log.Warnf("Failed to Initialize Discovery : %v", err)
log.Debugf("Failed to Initialize Discovery : %v", err)
}
} else {
// Missing Configuration file is not a failure scenario
// But without that, datastore cannot be initialized.
log.Debugf("Unable to Parse LibNetwork Config file : %v", err)
}
return c, nil
}
const (
cfgFileEnv = "LIBNETWORK_CFG"
defaultCfgFile = "/etc/default/libnetwork.toml"
)
func (c *controller) initConfig(configFile string) error {
cfgFile := configFile
if strings.Trim(cfgFile, " ") == "" {
cfgFile = os.Getenv(cfgFileEnv)
if strings.Trim(cfgFile, " ") == "" {
cfgFile = defaultCfgFile
}
func (c *controller) validateHostDiscoveryConfig() bool {
if c.cfg == nil || c.cfg.Cluster.Discovery == "" || c.cfg.Cluster.Address == "" {
return false
}
cfg, err := config.ParseConfig(cfgFile)
if err != nil {
return ErrInvalidConfigFile(cfgFile)
}
c.Lock()
c.cfg = cfg
c.Unlock()
return nil
return true
}
func (c *controller) initDiscovery() error {
@ -179,6 +166,12 @@ func (c *controller) hostJoinCallback(hosts []net.IP) {
func (c *controller) hostLeaveCallback(hosts []net.IP) {
}
func (c *controller) Config() config.Config {
c.Lock()
defer c.Unlock()
return *c.cfg
}
func (c *controller) ConfigureNetworkDriver(networkType string, options map[string]interface{}) error {
c.Lock()
dd, ok := c.drivers[networkType]

View file

@ -9,7 +9,7 @@ import (
func TestDriverRegistration(t *testing.T) {
bridgeNetType := "bridge"
c, err := New("")
c, err := New()
if err != nil {
t.Fatal(err)
}

View file

@ -63,7 +63,7 @@ func TestMain(m *testing.M) {
func createController() error {
var err error
controller, err = libnetwork.New("")
controller, err = libnetwork.New()
if err != nil {
return err
}
@ -1665,7 +1665,7 @@ func TestInvalidRemoteDriver(t *testing.T) {
t.Fatal(err)
}
controller, err := libnetwork.New("")
controller, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}

View file

@ -9,11 +9,18 @@ import (
"github.com/docker/libnetwork/types"
)
func (c *controller) validateDatastoreConfig() bool {
if c.cfg == nil || c.cfg.Datastore.Client.Provider == "" || c.cfg.Datastore.Client.Address == "" {
return false
}
return true
}
func (c *controller) initDataStore() error {
c.Lock()
cfg := c.cfg
c.Unlock()
if cfg == nil {
if !c.validateDatastoreConfig() {
return fmt.Errorf("datastore initialization requires a valid configuration")
}