Browse code

Support configuration networks

- They are configuration-only networks which
can be used to supply the configuration
when creating regular networks.
- They do not get allocated and do net get plumbed.
Drivers do not get to know about them.
- They can be removed, once no other network is
using them.
- When user creates a network specifying a
configuration network for the config, no
other network specific configuration field
is are accepted. User can only specify
network operator fields (attachable, internal,...)

Signed-off-by: Alessandro Boch <aboch@docker.com>

Alessandro Boch authored on 2017/04/08 03:18:51
Showing 5 changed files
... ...
@@ -299,6 +299,11 @@ func (n *networkRouter) buildNetworkResource(nw libnetwork.Network) *types.Netwo
299 299
 	r.Containers = make(map[string]types.EndpointResource)
300 300
 	buildIpamResources(r, info)
301 301
 	r.Labels = info.Labels()
302
+	r.ConfigOnly = info.ConfigOnly()
303
+
304
+	if cn := info.ConfigFrom(); cn != "" {
305
+		r.ConfigFrom = network.ConfigReference{Network: cn}
306
+	}
302 307
 
303 308
 	peers := info.Peers()
304 309
 	if len(peers) != 0 {
... ...
@@ -100,3 +100,8 @@ func (es *EndpointSettings) Copy() *EndpointSettings {
100 100
 type NetworkingConfig struct {
101 101
 	EndpointsConfig map[string]*EndpointSettings // Endpoint configs for each connecting network
102 102
 }
103
+
104
+// ConfigReference specifies the source which provides a network's configuration
105
+type ConfigReference struct {
106
+	Network string
107
+}
... ...
@@ -403,6 +403,8 @@ type NetworkResource struct {
403 403
 	Internal   bool                           // Internal represents if the network is used internal only
404 404
 	Attachable bool                           // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
405 405
 	Ingress    bool                           // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
406
+	ConfigFrom network.ConfigReference        // ConfigFrom specifies the source which will provide the configuration for this network.
407
+	ConfigOnly bool                           // ConfigOnly networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
406 408
 	Containers map[string]EndpointResource    // Containers contains endpoints belonging to the network
407 409
 	Options    map[string]string              // Options holds the network specific options to use for when creating the network
408 410
 	Labels     map[string]string              // Labels holds metadata specific to the network being created
... ...
@@ -435,6 +437,8 @@ type NetworkCreate struct {
435 435
 	Internal       bool
436 436
 	Attachable     bool
437 437
 	Ingress        bool
438
+	ConfigOnly     bool
439
+	ConfigFrom     *network.ConfigReference
438 440
 	Options        map[string]string
439 441
 	Labels         map[string]string
440 442
 }
... ...
@@ -320,6 +320,10 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
320 320
 		libnetwork.NetworkOptionIngress(create.Ingress),
321 321
 	}
322 322
 
323
+	if create.ConfigOnly {
324
+		nwOptions = append(nwOptions, libnetwork.NetworkOptionConfigOnly())
325
+	}
326
+
323 327
 	if create.IPAM != nil {
324 328
 		ipam := create.IPAM
325 329
 		v4Conf, v6Conf, err := getIpamConfig(ipam.Config)
... ...
@@ -337,6 +341,10 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string
337 337
 		nwOptions = append(nwOptions, libnetwork.NetworkOptionPersist(false))
338 338
 	}
339 339
 
340
+	if create.ConfigFrom != nil {
341
+		nwOptions = append(nwOptions, libnetwork.NetworkOptionConfigFrom(create.ConfigFrom.Network))
342
+	}
343
+
340 344
 	n, err := c.NewNetwork(driver, create.Name, id, nwOptions...)
341 345
 	if err != nil {
342 346
 		if _, ok := err.(libnetwork.ErrDataStoreNotInitialized); ok {
... ...
@@ -501,10 +509,16 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
501 501
 	if err := nw.Delete(); err != nil {
502 502
 		return err
503 503
 	}
504
-	daemon.pluginRefCount(nw.Type(), driverapi.NetworkPluginEndpointType, plugingetter.Release)
505
-	ipamType, _, _, _ := nw.Info().IpamConfig()
506
-	daemon.pluginRefCount(ipamType, ipamapi.PluginEndpointType, plugingetter.Release)
507
-	daemon.LogNetworkEvent(nw, "destroy")
504
+
505
+	// If this is not a configuration only network, we need to
506
+	// update the corresponding remote drivers' reference counts
507
+	if !nw.Info().ConfigOnly() {
508
+		daemon.pluginRefCount(nw.Type(), driverapi.NetworkPluginEndpointType, plugingetter.Release)
509
+		ipamType, _, _, _ := nw.Info().IpamConfig()
510
+		daemon.pluginRefCount(ipamType, ipamapi.PluginEndpointType, plugingetter.Release)
511
+		daemon.LogNetworkEvent(nw, "destroy")
512
+	}
513
+
508 514
 	return nil
509 515
 }
510 516
 
... ...
@@ -315,6 +315,9 @@ func (daemon *Daemon) localNetworksPrune(ctx context.Context, pruneFilters filte
315 315
 			return true
316 316
 		default:
317 317
 		}
318
+		if nw.Info().ConfigOnly() {
319
+			return false
320
+		}
318 321
 		if !until.IsZero() && nw.Info().Created().After(until) {
319 322
 			return false
320 323
 		}