@@ -106,6 +106,9 @@ type NetworkController interface {
106106
107107 // Stop network controller
108108 Stop ()
109+
110+ // ReloadCondfiguration updates the controller configuration
111+ ReloadConfiguration (cfgOptions ... config.Option ) error
109112}
110113
111114// NetworkWalker is a client provided function which will be used to walk the Networks.
@@ -129,7 +132,6 @@ type ipamData struct {
129132}
130133
131134type driverTable map [string ]* driverData
132-
133135type ipamTable map [string ]* ipamData
134136type sandboxTable map [string ]* sandbox
135137
@@ -153,22 +155,9 @@ type controller struct {
153155
154156// New creates a new instance of network controller.
155157func New (cfgOptions ... config.Option ) (NetworkController , error ) {
156- var cfg * config.Config
157- cfg = & config.Config {
158- Daemon : config.DaemonCfg {
159- DriverCfg : make (map [string ]interface {}),
160- },
161- Scopes : make (map [string ]* datastore.ScopeCfg ),
162- }
163-
164- if len (cfgOptions ) > 0 {
165- cfg .ProcessOptions (cfgOptions ... )
166- }
167- cfg .LoadDefaultScopes (cfg .Daemon .DataDir )
168-
169158 c := & controller {
170159 id : stringid .GenerateRandomID (),
171- cfg : cfg ,
160+ cfg : config . ParseConfigOptions ( cfgOptions ... ) ,
172161 sandboxes : sandboxTable {},
173162 drivers : driverTable {},
174163 ipamDrivers : ipamTable {},
@@ -179,8 +168,8 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
179168 return nil , err
180169 }
181170
182- if cfg != nil && cfg .Cluster .Watcher != nil {
183- if err := c .initDiscovery (cfg .Cluster .Watcher ); err != nil {
171+ if c . cfg != nil && c . cfg .Cluster .Watcher != nil {
172+ if err := c .initDiscovery (c . cfg .Cluster .Watcher ); err != nil {
184173 // Failing to initalize discovery is a bad situation to be in.
185174 // But it cannot fail creating the Controller
186175 log .Errorf ("Failed to Initialize Discovery : %v" , err )
@@ -206,6 +195,83 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
206195 return c , nil
207196}
208197
198+ var procReloadConfig = make (chan (bool ), 1 )
199+
200+ func (c * controller ) ReloadConfiguration (cfgOptions ... config.Option ) error {
201+ procReloadConfig <- true
202+ defer func () { <- procReloadConfig }()
203+
204+ // For now we accept the configuration reload only as a mean to provide a global store config after boot.
205+ // Refuse the configuration if it alters an existing datastore client configuration.
206+ update := false
207+ cfg := config .ParseConfigOptions (cfgOptions ... )
208+ for s := range c .cfg .Scopes {
209+ if _ , ok := cfg .Scopes [s ]; ! ok {
210+ return types .ForbiddenErrorf ("cannot accept new configuration because it removes an existing datastore client" )
211+ }
212+ }
213+ for s , nSCfg := range cfg .Scopes {
214+ if eSCfg , ok := c .cfg .Scopes [s ]; ok {
215+ if eSCfg .Client .Provider != nSCfg .Client .Provider ||
216+ eSCfg .Client .Address != nSCfg .Client .Address {
217+ return types .ForbiddenErrorf ("cannot accept new configuration because it modifies an existing datastore client" )
218+ }
219+ } else {
220+ update = true
221+ }
222+ }
223+ if ! update {
224+ return nil
225+ }
226+
227+ c .Lock ()
228+ c .cfg = cfg
229+ c .Unlock ()
230+
231+ if err := c .initStores (); err != nil {
232+ return err
233+ }
234+
235+ if c .discovery == nil && c .cfg .Cluster .Watcher != nil {
236+ if err := c .initDiscovery (c .cfg .Cluster .Watcher ); err != nil {
237+ log .Errorf ("Failed to Initialize Discovery after configuration update: %v" , err )
238+ }
239+ }
240+
241+ var dsConfig * discoverapi.DatastoreConfigData
242+ for scope , sCfg := range cfg .Scopes {
243+ if scope == datastore .LocalScope || ! sCfg .IsValid () {
244+ continue
245+ }
246+ dsConfig = & discoverapi.DatastoreConfigData {
247+ Scope : scope ,
248+ Provider : sCfg .Client .Provider ,
249+ Address : sCfg .Client .Address ,
250+ Config : sCfg .Client .Config ,
251+ }
252+ break
253+ }
254+ if dsConfig == nil {
255+ return nil
256+ }
257+
258+ for nm , id := range c .getIpamDrivers () {
259+ err := id .driver .DiscoverNew (discoverapi .DatastoreConfig , * dsConfig )
260+ if err != nil {
261+ log .Errorf ("Failed to set datastore in driver %s: %v" , nm , err )
262+ }
263+ }
264+
265+ for nm , id := range c .getNetDrivers () {
266+ err := id .driver .DiscoverNew (discoverapi .DatastoreConfig , * dsConfig )
267+ if err != nil {
268+ log .Errorf ("Failed to set datastore in driver %s: %v" , nm , err )
269+ }
270+ }
271+
272+ return nil
273+ }
274+
209275func (c * controller ) ID () string {
210276 return c .id
211277}
@@ -726,6 +792,26 @@ func (c *controller) getIpamDriver(name string) (ipamapi.Ipam, error) {
726792 return id .driver , nil
727793}
728794
795+ func (c * controller ) getIpamDrivers () ipamTable {
796+ c .Lock ()
797+ defer c .Unlock ()
798+ table := ipamTable {}
799+ for i , d := range c .ipamDrivers {
800+ table [i ] = d
801+ }
802+ return table
803+ }
804+
805+ func (c * controller ) getNetDrivers () driverTable {
806+ c .Lock ()
807+ defer c .Unlock ()
808+ table := driverTable {}
809+ for i , d := range c .drivers {
810+ table [i ] = d
811+ }
812+ return table
813+ }
814+
729815func (c * controller ) Stop () {
730816 c .closeStores ()
731817 c .stopExternalKeyListener ()
0 commit comments