Skip to content

Commit

Permalink
Allow to pass global datastore config
Browse files Browse the repository at this point in the history
- After boot via ReloadConfiguration() method

Signed-off-by: Alessandro Boch <aboch@docker.com>
  • Loading branch information
aboch committed Feb 17, 2016
1 parent be2b696 commit cfb9180
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 16 deletions.
16 changes: 16 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ func ParseConfig(tomlCfgFile string) (*Config, error) {
return cfg, nil
}

// ParseConfigOptions parses the configuration options and returns
// a reference to the corresponding Config structure
func ParseConfigOptions(cfgOptions ...Option) *Config {
cfg := &Config{
Daemon: DaemonCfg{
DriverCfg: make(map[string]interface{}),
},
Scopes: make(map[string]*datastore.ScopeCfg),
}

cfg.ProcessOptions(cfgOptions...)
cfg.LoadDefaultScopes(cfg.Daemon.DataDir)

return cfg
}

// Option is an option setter function type used to pass various configurations
// to the controller
type Option func(c *Config)
Expand Down
102 changes: 86 additions & 16 deletions controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ type NetworkController interface {

// Stop network controller
Stop()

// ReloadCondfiguration updates the controller configuration
ReloadConfiguration(cfgOptions ...config.Option) error
}

// NetworkWalker is a client provided function which will be used to walk the Networks.
Expand Down Expand Up @@ -153,22 +156,9 @@ type controller struct {

// New creates a new instance of network controller.
func New(cfgOptions ...config.Option) (NetworkController, error) {
var cfg *config.Config
cfg = &config.Config{
Daemon: config.DaemonCfg{
DriverCfg: make(map[string]interface{}),
},
Scopes: make(map[string]*datastore.ScopeCfg),
}

if len(cfgOptions) > 0 {
cfg.ProcessOptions(cfgOptions...)
}
cfg.LoadDefaultScopes(cfg.Daemon.DataDir)

c := &controller{
id: stringid.GenerateRandomID(),
cfg: cfg,
cfg: config.ParseConfigOptions(cfgOptions...),
sandboxes: sandboxTable{},
drivers: driverTable{},
ipamDrivers: ipamTable{},
Expand All @@ -179,8 +169,8 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
return nil, err
}

if cfg != nil && cfg.Cluster.Watcher != nil {
if err := c.initDiscovery(cfg.Cluster.Watcher); err != nil {
if c.cfg != nil && c.cfg.Cluster.Watcher != nil {
if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil {
// Failing to initalize discovery is a bad situation to be in.
// But it cannot fail creating the Controller
log.Errorf("Failed to Initialize Discovery : %v", err)
Expand All @@ -206,6 +196,66 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
return c, nil
}

func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
// For now we accept the configuration reload only as a mean
// to provide a global store configuration after boot
c.Lock()
for _, ds := range c.stores {
if ds.Scope() == datastore.GlobalScope {
c.Unlock()
return types.ForbiddenErrorf(
"cannot accept new configuration because network controller has a global scope datastore configured already")
}
}
// Now accept the new config
c.cfg = config.ParseConfigOptions(cfgOptions...)
c.Unlock()

if err := c.initStores(); err != nil {
return err
}

if c.discovery == nil && c.cfg.Cluster.Watcher != nil {
if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil {
log.Errorf("Failed to Initialize Discovery after configuration update: %v", err)
}
}

var dsConfig *discoverapi.DatastoreConfigData
for scope, cfg := range c.cfg.Scopes {
if scope == datastore.LocalScope || !cfg.IsValid() {
continue
}
dsConfig = &discoverapi.DatastoreConfigData{
Scope: scope,
Provider: cfg.Client.Provider,
Address: cfg.Client.Address,
Config: cfg.Client.Config,
}
break
}

if dsConfig == nil {
return nil
}

for nm, id := range c.getIpamDrivers() {
err := id.driver.DiscoverNew(discoverapi.DatastoreConfig, *dsConfig)
if err != nil {
log.Errorf("Failed to set datastore in driver %s: %v", nm, err)
}
}

for nm, id := range c.getNetDrivers() {
err := id.driver.DiscoverNew(discoverapi.DatastoreConfig, *dsConfig)
if err != nil {
log.Errorf("Failed to set datastore in driver %s: %v", nm, err)
}
}

return nil
}

func (c *controller) ID() string {
return c.id
}
Expand Down Expand Up @@ -726,6 +776,26 @@ func (c *controller) getIpamDriver(name string) (ipamapi.Ipam, error) {
return id.driver, nil
}

func (c *controller) getIpamDrivers() ipamTable {
c.Lock()
defer c.Unlock()
table := ipamTable{}
for i, d := range c.ipamDrivers {
table[i] = d
}
return table
}

func (c *controller) getNetDrivers() driverTable {
c.Lock()
defer c.Unlock()
table := driverTable{}
for i, d := range c.drivers {
table[i] = d
}
return table
}

func (c *controller) Stop() {
c.closeStores()
c.stopExternalKeyListener()
Expand Down
4 changes: 4 additions & 0 deletions store.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func (c *controller) initStores() error {
return nil
}
scopeConfigs := c.cfg.Scopes
c.stores = nil
c.Unlock()

for scope, scfg := range scopeConfigs {
Expand Down Expand Up @@ -417,6 +418,9 @@ func (c *controller) watchLoop() {
}

func (c *controller) startWatch() {
if c.watchCh != nil {
return
}
c.watchCh = make(chan *endpoint)
c.unWatchCh = make(chan *endpoint)
c.nmap = make(map[string]*netWatch)
Expand Down

0 comments on commit cfb9180

Please sign in to comment.