libnetwork/config: remove vestiges of global scope

Without (*Controller).ReloadConfiguration, the only way to configure
datastore scopes would be by passing config.Options to libnetwork.New.
The only options defined which relate to datastore scopes are limited to
configuring the local-scope datastore. Furthermore, the default
datastore config only defines configuration for the local-scope
datastore. The local-scope datastore is therefore the only datastore
scope possible in libnetwork. Start removing code which is only
needed to support multiple datastore scopes.

Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
Cory Snider 2023-01-13 18:38:46 -05:00
parent 52d9883812
commit 142b522946
9 changed files with 53 additions and 108 deletions

View file

@ -29,7 +29,7 @@ func randomLocalStore() (datastore.DataStore, error) {
if err := tmp.Close(); err != nil { if err := tmp.Close(); err != nil {
return nil, fmt.Errorf("Error closing temp file: %v", err) return nil, fmt.Errorf("Error closing temp file: %v", err)
} }
return datastore.NewDataStore(datastore.LocalScope, &datastore.ScopeCfg{ return datastore.NewDataStore(datastore.ScopeCfg{
Client: datastore.ScopeClientCfg{ Client: datastore.ScopeClientCfg{
Provider: "boltdb", Provider: "boltdb",
Address: filepath.Join(defaultPrefix, filepath.Base(tmp.Name())), Address: filepath.Join(defaultPrefix, filepath.Base(tmp.Name())),

View file

@ -29,7 +29,7 @@ type Config struct {
ClusterProvider cluster.Provider ClusterProvider cluster.Provider
NetworkControlPlaneMTU int NetworkControlPlaneMTU int
DefaultAddressPool []*ipamutils.NetworkToSplit DefaultAddressPool []*ipamutils.NetworkToSplit
Scopes map[string]*datastore.ScopeCfg Scope datastore.ScopeCfg
ActiveSandboxes map[string]interface{} ActiveSandboxes map[string]interface{}
PluginGetter plugingetter.PluginGetter PluginGetter plugingetter.PluginGetter
} }
@ -38,7 +38,6 @@ type Config struct {
func New(opts ...Option) *Config { func New(opts ...Option) *Config {
cfg := &Config{ cfg := &Config{
DriverCfg: make(map[string]interface{}), DriverCfg: make(map[string]interface{}),
Scopes: make(map[string]*datastore.ScopeCfg),
} }
for _, opt := range opts { for _, opt := range opts {
@ -48,10 +47,8 @@ func New(opts ...Option) *Config {
} }
// load default scope configs which don't have explicit user specified configs. // load default scope configs which don't have explicit user specified configs.
for k, v := range datastore.DefaultScopes(cfg.DataDir) { if cfg.Scope == (datastore.ScopeCfg{}) {
if _, ok := cfg.Scopes[k]; !ok { cfg.Scope = datastore.DefaultScope(cfg.DataDir)
cfg.Scopes[k] = v
}
} }
return cfg return cfg
} }
@ -147,10 +144,7 @@ func IsValidName(name string) bool {
func OptionLocalKVProvider(provider string) Option { func OptionLocalKVProvider(provider string) Option {
return func(c *Config) { return func(c *Config) {
logrus.Debugf("Option OptionLocalKVProvider: %s", provider) logrus.Debugf("Option OptionLocalKVProvider: %s", provider)
if _, ok := c.Scopes[datastore.LocalScope]; !ok { c.Scope.Client.Provider = strings.TrimSpace(provider)
c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
}
c.Scopes[datastore.LocalScope].Client.Provider = strings.TrimSpace(provider)
} }
} }
@ -158,10 +152,7 @@ func OptionLocalKVProvider(provider string) Option {
func OptionLocalKVProviderURL(url string) Option { func OptionLocalKVProviderURL(url string) Option {
return func(c *Config) { return func(c *Config) {
logrus.Debugf("Option OptionLocalKVProviderURL: %s", url) logrus.Debugf("Option OptionLocalKVProviderURL: %s", url)
if _, ok := c.Scopes[datastore.LocalScope]; !ok { c.Scope.Client.Address = strings.TrimSpace(url)
c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
}
c.Scopes[datastore.LocalScope].Client.Address = strings.TrimSpace(url)
} }
} }
@ -169,10 +160,7 @@ func OptionLocalKVProviderURL(url string) Option {
func OptionLocalKVProviderConfig(config *store.Config) Option { func OptionLocalKVProviderConfig(config *store.Config) Option {
return func(c *Config) { return func(c *Config) {
logrus.Debugf("Option OptionLocalKVProviderConfig: %v", config) logrus.Debugf("Option OptionLocalKVProviderConfig: %v", config)
if _, ok := c.Scopes[datastore.LocalScope]; !ok { c.Scope.Client.Config = config
c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{}
}
c.Scopes[datastore.LocalScope].Client.Config = config
} }
} }

View file

@ -353,15 +353,14 @@ func (c *Controller) makeDriverConfig(ntype string) map[string]interface{} {
} }
} }
for k, v := range c.cfg.Scopes { if c.cfg.Scope.IsValid() {
if !v.IsValid() { // FIXME: every driver instance constructs a new DataStore
continue // instance against the same database. Yikes!
} cfg[netlabel.LocalKVClient] = discoverapi.DatastoreConfigData{
cfg[netlabel.MakeKVClient(k)] = discoverapi.DatastoreConfigData{ Scope: datastore.LocalScope,
Scope: k, Provider: c.cfg.Scope.Client.Provider,
Provider: v.Client.Provider, Address: c.cfg.Scope.Client.Address,
Address: v.Client.Address, Config: c.cfg.Scope.Client.Config,
Config: v.Client.Config,
} }
} }

View file

@ -129,37 +129,28 @@ const (
EndpointKeyPrefix = "endpoint" EndpointKeyPrefix = "endpoint"
) )
var ( var defaultRootChain = []string{"docker", "network", "v1.0"}
defaultScopes = makeDefaultScopes() var rootChain = defaultRootChain
)
func makeDefaultScopes() map[string]*ScopeCfg { // DefaultScope returns a default scope config for clients to use.
def := make(map[string]*ScopeCfg) func DefaultScope(dataDir string) ScopeCfg {
def[LocalScope] = &ScopeCfg{ var dbpath string
if dataDir == "" {
dbpath = defaultPrefix + "/local-kv.db"
} else {
dbpath = dataDir + "/network/files/local-kv.db"
}
return ScopeCfg{
Client: ScopeClientCfg{ Client: ScopeClientCfg{
Provider: string(store.BOLTDB), Provider: string(store.BOLTDB),
Address: defaultPrefix + "/local-kv.db", Address: dbpath,
Config: &store.Config{ Config: &store.Config{
Bucket: "libnetwork", Bucket: "libnetwork",
ConnectionTimeout: time.Minute, ConnectionTimeout: time.Minute,
}, },
}, },
} }
return def
}
var defaultRootChain = []string{"docker", "network", "v1.0"}
var rootChain = defaultRootChain
// DefaultScopes returns a map of default scopes and its config for clients to use.
func DefaultScopes(dataDir string) map[string]*ScopeCfg {
s := makeDefaultScopes()
if dataDir != "" {
s[LocalScope].Client.Address = dataDir + "/network/files/local-kv.db"
}
return s
} }
// IsValid checks if the scope config has valid configuration. // IsValid checks if the scope config has valid configuration.
@ -192,16 +183,7 @@ func ParseKey(key string) ([]string, error) {
} }
// newClient used to connect to KV Store // newClient used to connect to KV Store
func newClient(scope string, kv string, addr string, config *store.Config, cached bool) (DataStore, error) { func newClient(kv string, addr string, config *store.Config) (DataStore, error) {
if cached && scope != LocalScope {
return nil, fmt.Errorf("caching supported only for scope %s", LocalScope)
}
sequential := false
if scope == LocalScope {
sequential = true
}
if config == nil { if config == nil {
config = &store.Config{} config = &store.Config{}
} }
@ -227,31 +209,19 @@ func newClient(scope string, kv string, addr string, config *store.Config, cache
return nil, err return nil, err
} }
ds := &datastore{scope: scope, store: s, active: true, watchCh: make(chan struct{}), sequential: sequential} ds := &datastore{scope: LocalScope, store: s, active: true, watchCh: make(chan struct{}), sequential: true}
if cached {
ds.cache = newCache(ds) ds.cache = newCache(ds)
}
return ds, nil return ds, nil
} }
// NewDataStore creates a new instance of LibKV data store // NewDataStore creates a new instance of LibKV data store
func NewDataStore(scope string, cfg *ScopeCfg) (DataStore, error) { func NewDataStore(cfg ScopeCfg) (DataStore, error) {
if cfg == nil || cfg.Client.Provider == "" || cfg.Client.Address == "" { if cfg.Client.Provider == "" || cfg.Client.Address == "" {
c, ok := defaultScopes[scope] cfg = DefaultScope("")
if !ok || c.Client.Provider == "" || c.Client.Address == "" {
return nil, fmt.Errorf("unexpected scope %s without configuration passed", scope)
} }
cfg = c return newClient(cfg.Client.Provider, cfg.Client.Address, cfg.Client.Config)
}
var cached bool
if scope == LocalScope {
cached = true
}
return newClient(scope, cfg.Client.Provider, cfg.Client.Address, cfg.Client.Config, cached)
} }
// NewDataStoreFromConfig creates a new instance of LibKV data store starting from the datastore config data // NewDataStoreFromConfig creates a new instance of LibKV data store starting from the datastore config data
@ -266,7 +236,7 @@ func NewDataStoreFromConfig(dsc discoverapi.DatastoreConfigData) (DataStore, err
return nil, fmt.Errorf("cannot parse store configuration: %v", dsc.Config) return nil, fmt.Errorf("cannot parse store configuration: %v", dsc.Config)
} }
scopeCfg := &ScopeCfg{ scopeCfg := ScopeCfg{
Client: ScopeClientCfg{ Client: ScopeClientCfg{
Address: dsc.Address, Address: dsc.Address,
Provider: dsc.Provider, Provider: dsc.Provider,
@ -274,7 +244,7 @@ func NewDataStoreFromConfig(dsc discoverapi.DatastoreConfigData) (DataStore, err
}, },
} }
ds, err := NewDataStore(dsc.Scope, scopeCfg) ds, err := NewDataStore(scopeCfg)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to construct datastore client from datastore configuration %v: %v", dsc, err) return nil, fmt.Errorf("failed to construct datastore client from datastore configuration %v: %v", dsc, err)
} }

View file

@ -36,10 +36,13 @@ func TestParseKey(t *testing.T) {
} }
func TestInvalidDataStore(t *testing.T) { func TestInvalidDataStore(t *testing.T) {
config := &ScopeCfg{} config := ScopeCfg{
config.Client.Provider = "invalid" Client: ScopeClientCfg{
config.Client.Address = "localhost:8500" Provider: "invalid",
_, err := NewDataStore(GlobalScope, config) Address: "localhost:8500",
},
}
_, err := NewDataStore(config)
if err == nil { if err == nil {
t.Fatal("Invalid Datastore connection configuration must result in a failure") t.Fatal("Invalid Datastore connection configuration must result in a failure")
} }

View file

@ -45,7 +45,7 @@ func randomLocalStore(needStore bool) (datastore.DataStore, error) {
if err := tmp.Close(); err != nil { if err := tmp.Close(); err != nil {
return nil, fmt.Errorf("Error closing temp file: %v", err) return nil, fmt.Errorf("Error closing temp file: %v", err)
} }
return datastore.NewDataStore(datastore.LocalScope, &datastore.ScopeCfg{ return datastore.NewDataStore(datastore.ScopeCfg{
Client: datastore.ScopeClientCfg{ Client: datastore.ScopeClientCfg{
Provider: "boltdb", Provider: "boltdb",
Address: filepath.Join(defaultPrefix, filepath.Base(tmp.Name())), Address: filepath.Join(defaultPrefix, filepath.Base(tmp.Name())),

View file

@ -37,7 +37,7 @@ func TestMain(m *testing.M) {
} }
// Cleanup local datastore file // Cleanup local datastore file
_ = os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) _ = os.Remove(datastore.DefaultScope("").Client.Address)
os.Exit(m.Run()) os.Exit(m.Run())
} }

View file

@ -13,35 +13,20 @@ func registerKVStores() {
boltdb.Register() boltdb.Register()
} }
func (c *Controller) initScopedStore(scope string, scfg *datastore.ScopeCfg) error {
store, err := datastore.NewDataStore(scope, scfg)
if err != nil {
return err
}
c.mu.Lock()
c.stores = append(c.stores, store)
c.mu.Unlock()
return nil
}
func (c *Controller) initStores() error { func (c *Controller) initStores() error {
registerKVStores() registerKVStores()
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock()
if c.cfg == nil { if c.cfg == nil {
c.mu.Unlock()
return nil return nil
} }
scopeConfigs := c.cfg.Scopes store, err := datastore.NewDataStore(c.cfg.Scope)
c.stores = nil if err != nil {
c.mu.Unlock()
for scope, scfg := range scopeConfigs {
if err := c.initScopedStore(scope, scfg); err != nil {
return err return err
} }
} c.stores = []datastore.DataStore{store}
c.startWatch() c.startWatch()
return nil return nil

View file

@ -9,7 +9,7 @@ import (
) )
func TestBoltdbBackend(t *testing.T) { func TestBoltdbBackend(t *testing.T) {
defer os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) defer os.Remove(datastore.DefaultScope("").Client.Address)
testLocalBackend(t, "", "", nil) testLocalBackend(t, "", "", nil)
defer os.Remove("/tmp/boltdb.db") defer os.Remove("/tmp/boltdb.db")
config := &store.Config{Bucket: "testBackend"} config := &store.Config{Bucket: "testBackend"}