Browse code

Global Default Address Pool feature support

This feature allows user to specify list of subnets for global
default address pool. User can configure subnet list using
'swarm init' command. Daemon passes the information to swarmkit.
We validate the information in swarmkit, then store it in cluster
object. when IPAM init is called, we pass subnet list to IPAM driver.

Signed-off-by: selansen <elango.siva@docker.com>

selansen authored on 2018/07/31 00:25:02
Showing 29 changed files
... ...
@@ -8765,14 +8765,28 @@ paths:
8765 8765
                   nodes in order to reach the containers running on this node. Using this parameter it is possible to
8766 8766
                   separate the container data traffic from the management traffic of the cluster.
8767 8767
                 type: "string"
8768
+              DefaultAddrPool:
8769
+                description: |
8770
+                  Default Address Pool specifies default subnet pools for global scope networks.
8771
+                type: "array"
8772
+                items:
8773
+                  type: "string"
8774
+                  example: ["10.10.0.0/16", "20.20.0.0/16"]
8768 8775
               ForceNewCluster:
8769 8776
                 description: "Force creation of a new swarm."
8770 8777
                 type: "boolean"
8778
+              SubnetSize:
8779
+                description: |
8780
+                  SubnetSize specifies the subnet size of the networks created from the default subnet pool
8781
+                type: "integer"
8782
+                format: "uint32"
8771 8783
               Spec:
8772 8784
                 $ref: "#/definitions/SwarmSpec"
8773 8785
             example:
8774 8786
               ListenAddr: "0.0.0.0:2377"
8775 8787
               AdvertiseAddr: "192.168.1.1:2377"
8788
+              DefaultAddrPool: ["10.10.0.0/8", "20.20.0.0/8"]
8789
+              SubnetSize: 24
8776 8790
               ForceNewCluster: false
8777 8791
               Spec:
8778 8792
                 Orchestration: {}
... ...
@@ -1,6 +1,8 @@
1 1
 package swarm // import "github.com/docker/docker/api/types/swarm"
2 2
 
3
-import "time"
3
+import (
4
+	"time"
5
+)
4 6
 
5 7
 // ClusterInfo represents info about the cluster for outputting in "info"
6 8
 // it contains the same information as "Swarm", but without the JoinTokens
... ...
@@ -10,6 +12,8 @@ type ClusterInfo struct {
10 10
 	Spec                   Spec
11 11
 	TLSInfo                TLSInfo
12 12
 	RootRotationInProgress bool
13
+	DefaultAddrPool        []string
14
+	SubnetSize             uint32
13 15
 }
14 16
 
15 17
 // Swarm represents a swarm.
... ...
@@ -153,6 +157,8 @@ type InitRequest struct {
153 153
 	Spec             Spec
154 154
 	AutoLockManagers bool
155 155
 	Availability     NodeAvailability
156
+	DefaultAddrPool  []string
157
+	SubnetSize       uint32
156 158
 }
157 159
 
158 160
 // JoinRequest is the request used to join a swarm.
... ...
@@ -40,6 +40,8 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm {
40 40
 				TrustRoot: string(c.RootCA.CACert),
41 41
 			},
42 42
 			RootRotationInProgress: c.RootCA.RootRotation != nil,
43
+			DefaultAddrPool:        c.DefaultAddressPool,
44
+			SubnetSize:             c.SubnetSize,
43 45
 		},
44 46
 		JoinTokens: types.JoinTokens{
45 47
 			Worker:  c.RootCA.JoinTokens.Worker,
... ...
@@ -3,6 +3,7 @@ package cluster // import "github.com/docker/docker/daemon/cluster"
3 3
 import (
4 4
 	"context"
5 5
 	"fmt"
6
+	"net"
6 7
 	"path/filepath"
7 8
 	"runtime"
8 9
 	"strings"
... ...
@@ -52,6 +53,10 @@ type nodeStartConfig struct {
52 52
 	AdvertiseAddr string
53 53
 	// DataPathAddr is the address that has to be used for the data path
54 54
 	DataPathAddr string
55
+	// DefaultAddressPool contains list of subnets
56
+	DefaultAddressPool []string
57
+	// SubnetSize contains subnet size of DefaultAddressPool
58
+	SubnetSize uint32
55 59
 	// JoinInProgress is set to true if a join operation has started, but
56 60
 	// not completed yet.
57 61
 	JoinInProgress bool
... ...
@@ -110,6 +115,12 @@ func (n *nodeRunner) start(conf nodeStartConfig) error {
110 110
 		joinAddr = conf.RemoteAddr
111 111
 	}
112 112
 
113
+	var defaultAddrPool []*net.IPNet
114
+	for _, address := range conf.DefaultAddressPool {
115
+		if _, b, err := net.ParseCIDR(address); err == nil {
116
+			defaultAddrPool = append(defaultAddrPool, b)
117
+		}
118
+	}
113 119
 	// Hostname is not set here. Instead, it is obtained from
114 120
 	// the node description that is reported periodically
115 121
 	swarmnodeConfig := swarmnode.Config{
... ...
@@ -117,6 +128,8 @@ func (n *nodeRunner) start(conf nodeStartConfig) error {
117 117
 		ListenControlAPI:   control,
118 118
 		ListenRemoteAPI:    conf.ListenAddr,
119 119
 		AdvertiseRemoteAPI: conf.AdvertiseAddr,
120
+		DefaultAddrPool:    defaultAddrPool,
121
+		SubnetSize:         int(conf.SubnetSize),
120 122
 		JoinAddr:           joinAddr,
121 123
 		StateDir:           n.cluster.root,
122 124
 		JoinToken:          conf.joinToken,
... ...
@@ -93,13 +93,15 @@ func (c *Cluster) Init(req types.InitRequest) (string, error) {
93 93
 	}
94 94
 
95 95
 	nr, err := c.newNodeRunner(nodeStartConfig{
96
-		forceNewCluster: req.ForceNewCluster,
97
-		autolock:        req.AutoLockManagers,
98
-		LocalAddr:       localAddr,
99
-		ListenAddr:      net.JoinHostPort(listenHost, listenPort),
100
-		AdvertiseAddr:   net.JoinHostPort(advertiseHost, advertisePort),
101
-		DataPathAddr:    dataPathAddr,
102
-		availability:    req.Availability,
96
+		forceNewCluster:    req.ForceNewCluster,
97
+		autolock:           req.AutoLockManagers,
98
+		LocalAddr:          localAddr,
99
+		ListenAddr:         net.JoinHostPort(listenHost, listenPort),
100
+		AdvertiseAddr:      net.JoinHostPort(advertiseHost, advertisePort),
101
+		DataPathAddr:       dataPathAddr,
102
+		DefaultAddressPool: req.DefaultAddrPool,
103
+		SubnetSize:         req.SubnetSize,
104
+		availability:       req.Availability,
103 105
 	})
104 106
 	if err != nil {
105 107
 		return "", err
... ...
@@ -21,6 +21,9 @@ keywords: "API, Docker, rcli, REST, documentation"
21 21
   and `OperatingSystem` if the daemon was unable to obtain this information.
22 22
 * `GET /info` now returns information about the product license, if a license
23 23
   has been applied to the daemon.
24
+* `POST /swarm/init` now accepts a `DefaultAddrPool` property to set global scope default address pool
25
+* `POST /swarm/init` now accepts a `SubnetSize` property to set global scope networks by giving the
26
+  length of the subnet masks for every such network
24 27
 
25 28
 ## V1.38 API changes
26 29
 
... ...
@@ -313,3 +313,50 @@ func noServices(client client.ServiceAPIClient) func(log poll.LogT) poll.Result
313 313
 		}
314 314
 	}
315 315
 }
316
+
317
+func TestServiceWithDefaultAddressPoolInit(t *testing.T) {
318
+	defer setupTest(t)()
319
+	var ops = []func(*daemon.Daemon){}
320
+	ipAddr := []string{"20.20.0.0/16"}
321
+	ops = append(ops, daemon.WithSwarmDefaultAddrPool(ipAddr))
322
+	ops = append(ops, daemon.WithSwarmDefaultAddrPoolSubnetSize(24))
323
+	d := swarm.NewSwarm(t, testEnv, ops...)
324
+
325
+	cli := d.NewClientT(t)
326
+	defer cli.Close()
327
+
328
+	// Create a overlay network
329
+	name := "saanvisthira" + t.Name()
330
+	network.CreateNoError(t, context.Background(), cli, name,
331
+		network.WithDriver("overlay"))
332
+
333
+	var instances uint64 = 1
334
+	serviceName := "TestService" + t.Name()
335
+	serviceID := swarm.CreateService(t, d,
336
+		swarm.ServiceWithReplicas(instances),
337
+		swarm.ServiceWithName(serviceName),
338
+		swarm.ServiceWithNetwork(name),
339
+	)
340
+
341
+	poll.WaitOn(t, serviceRunningCount(cli, serviceID, instances), swarm.ServicePoll)
342
+
343
+	_, _, err := cli.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
344
+	assert.NilError(t, err)
345
+
346
+	out, err := cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
347
+	assert.NilError(t, err)
348
+	assert.Equal(t, out.IPAM.Config[0].Subnet, "20.20.0.0/24")
349
+
350
+	err = cli.ServiceRemove(context.Background(), serviceID)
351
+	assert.NilError(t, err)
352
+	d.SwarmLeave(true)
353
+	d.Stop(t)
354
+
355
+	// Clean up , set it back to original one to make sure other tests don't fail
356
+	ipAddr = []string{"10.10.0.0/8"}
357
+	ops = append(ops, daemon.WithSwarmDefaultAddrPool(ipAddr))
358
+	ops = append(ops, daemon.WithSwarmDefaultAddrPoolSubnetSize(24))
359
+	d = swarm.NewSwarm(t, testEnv, ops...)
360
+	d.SwarmLeave(true)
361
+	defer d.Stop(t)
362
+}
... ...
@@ -73,7 +73,8 @@ type Daemon struct {
73 73
 	// swarm related field
74 74
 	swarmListenAddr string
75 75
 	SwarmPort       int // FIXME(vdemeester) should probably not be exported
76
-
76
+	DefaultAddrPool []string
77
+	SubnetSize      uint32
77 78
 	// cached information
78 79
 	CachedInfo types.Info
79 80
 }
... ...
@@ -34,6 +34,20 @@ func WithSwarmListenAddr(listenAddr string) func(*Daemon) {
34 34
 	}
35 35
 }
36 36
 
37
+// WithSwarmDefaultAddrPool sets the swarm default address pool to use for swarm mode
38
+func WithSwarmDefaultAddrPool(defaultAddrPool []string) func(*Daemon) {
39
+	return func(d *Daemon) {
40
+		d.DefaultAddrPool = defaultAddrPool
41
+	}
42
+}
43
+
44
+// WithSwarmDefaultAddrPoolSubnetSize sets the subnet length mask of swarm default address pool to use for swarm mode
45
+func WithSwarmDefaultAddrPoolSubnetSize(subnetSize uint32) func(*Daemon) {
46
+	return func(d *Daemon) {
47
+		d.SubnetSize = subnetSize
48
+	}
49
+}
50
+
37 51
 // WithEnvironment sets options from internal/test/environment.Execution struct
38 52
 func WithEnvironment(e environment.Execution) func(*Daemon) {
39 53
 	return func(d *Daemon) {
... ...
@@ -69,6 +69,10 @@ func (d *Daemon) SwarmInit(t assert.TestingT, req swarm.InitRequest) {
69 69
 	if req.ListenAddr == "" {
70 70
 		req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort)
71 71
 	}
72
+	if req.DefaultAddrPool == nil {
73
+		req.DefaultAddrPool = d.DefaultAddrPool
74
+		req.SubnetSize = d.SubnetSize
75
+	}
72 76
 	cli := d.NewClientT(t)
73 77
 	defer cli.Close()
74 78
 	_, err := cli.SwarmInit(context.Background(), req)
... ...
@@ -37,7 +37,7 @@ github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b
37 37
 #get libnetwork packages
38 38
 
39 39
 # When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly
40
-github.com/docker/libnetwork f30a35b091cc2a431ef9856c75c343f75bb5f2e2
40
+github.com/docker/libnetwork a79d3687931697244b8e03485bf7b2042f8ec6b6
41 41
 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
42 42
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
43 43
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -125,7 +125,7 @@ github.com/containerd/ttrpc 94dde388801693c54f88a6596f713b51a8b30b2d
125 125
 github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
126 126
 
127 127
 # cluster
128
-github.com/docker/swarmkit 8852e8840e30d69db0b39a4a3d6447362e17c64f
128
+github.com/docker/swarmkit cfa742c8abe6f8e922f6e4e920153c408e7d9c3b
129 129
 github.com/gogo/protobuf v1.0.0
130 130
 github.com/cloudflare/cfssl 1.3.2
131 131
 github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
... ...
@@ -45,9 +45,10 @@ func NewAllocator(lcDs, glDs datastore.DataStore) (*Allocator, error) {
45 45
 	a := &Allocator{}
46 46
 
47 47
 	// Load predefined subnet pools
48
+
48 49
 	a.predefined = map[string][]*net.IPNet{
49
-		localAddressSpace:  ipamutils.PredefinedBroadNetworks,
50
-		globalAddressSpace: ipamutils.PredefinedGranularNetworks,
50
+		localAddressSpace:  ipamutils.GetLocalScopeDefaultNetworks(),
51
+		globalAddressSpace: ipamutils.GetGlobalScopeDefaultNetworks(),
51 52
 	}
52 53
 
53 54
 	// Initialize asIndices map
... ...
@@ -35,7 +35,7 @@ func Init(ic ipamapi.Callback, l, g interface{}) error {
35 35
 		}
36 36
 	}
37 37
 
38
-	ipamutils.InitNetworks(GetDefaultIPAddressPool())
38
+	ipamutils.ConfigLocalScopeDefaultNetworks(GetDefaultIPAddressPool())
39 39
 
40 40
 	a, err := ipam.NewAllocator(localDs, globalDs)
41 41
 	if err != nil {
... ...
@@ -37,7 +37,7 @@ func InitDockerDefault(ic ipamapi.Callback, l, g interface{}) error {
37 37
 		}
38 38
 	}
39 39
 
40
-	ipamutils.InitNetworks(nil)
40
+	ipamutils.ConfigLocalScopeDefaultNetworks(nil)
41 41
 
42 42
 	a, err := ipam.NewAllocator(localDs, globalDs)
43 43
 	if err != nil {
... ...
@@ -5,23 +5,20 @@ import (
5 5
 	"fmt"
6 6
 	"net"
7 7
 	"sync"
8
-
9
-	"github.com/sirupsen/logrus"
10 8
 )
11 9
 
12 10
 var (
13
-	// PredefinedBroadNetworks contains a list of 31 IPv4 private networks with host size 16 and 12
14
-	// (172.17-31.x.x/16, 192.168.x.x/20) which do not overlap with the networks in `PredefinedGranularNetworks`
15
-	PredefinedBroadNetworks []*net.IPNet
16
-	// PredefinedGranularNetworks contains a list of 64K IPv4 private networks with host size 8
17
-	// (10.x.x.x/24) which do not overlap with the networks in `PredefinedBroadNetworks`
18
-	PredefinedGranularNetworks []*net.IPNet
19
-	initNetworksOnce           sync.Once
20
-
21
-	defaultBroadNetwork = []*NetworkToSplit{{"172.17.0.0/16", 16}, {"172.18.0.0/16", 16}, {"172.19.0.0/16", 16},
11
+	// PredefinedLocalScopeDefaultNetworks contains a list of 31 IPv4 private networks with host size 16 and 12
12
+	// (172.17-31.x.x/16, 192.168.x.x/20) which do not overlap with the networks in `PredefinedGlobalScopeDefaultNetworks`
13
+	PredefinedLocalScopeDefaultNetworks []*net.IPNet
14
+	// PredefinedGlobalScopeDefaultNetworks contains a list of 64K IPv4 private networks with host size 8
15
+	// (10.x.x.x/24) which do not overlap with the networks in `PredefinedLocalScopeDefaultNetworks`
16
+	PredefinedGlobalScopeDefaultNetworks []*net.IPNet
17
+	mutex                                sync.Mutex
18
+	localScopeDefaultNetworks            = []*NetworkToSplit{{"172.17.0.0/16", 16}, {"172.18.0.0/16", 16}, {"172.19.0.0/16", 16},
22 19
 		{"172.20.0.0/14", 16}, {"172.24.0.0/14", 16}, {"172.28.0.0/14", 16},
23 20
 		{"192.168.0.0/16", 20}}
24
-	defaultGranularNetwork = []*NetworkToSplit{{"10.0.0.0/8", 24}}
21
+	globalScopeDefaultNetworks = []*NetworkToSplit{{"10.0.0.0/8", 24}}
25 22
 )
26 23
 
27 24
 // NetworkToSplit represent a network that has to be split in chunks with mask length Size.
... ...
@@ -34,19 +31,61 @@ type NetworkToSplit struct {
34 34
 	Size int    `json:"size"`
35 35
 }
36 36
 
37
-// InitNetworks initializes the broad network pool and the granular network pool
38
-func InitNetworks(defaultAddressPool []*NetworkToSplit) {
39
-	initNetworksOnce.Do(func() {
40
-		// error ingnored should never fail
41
-		PredefinedGranularNetworks, _ = splitNetworks(defaultGranularNetwork)
42
-		if defaultAddressPool == nil {
43
-			defaultAddressPool = defaultBroadNetwork
44
-		}
45
-		var err error
46
-		if PredefinedBroadNetworks, err = splitNetworks(defaultAddressPool); err != nil {
47
-			logrus.WithError(err).Error("InitAddressPools failed to initialize the default address pool")
48
-		}
49
-	})
37
+func init() {
38
+	var err error
39
+	if PredefinedGlobalScopeDefaultNetworks, err = splitNetworks(globalScopeDefaultNetworks); err != nil {
40
+		//we are going to panic in case of error as we should never get into this state
41
+		panic("InitAddressPools failed to initialize the global scope default address pool")
42
+	}
43
+
44
+	if PredefinedLocalScopeDefaultNetworks, err = splitNetworks(localScopeDefaultNetworks); err != nil {
45
+		//we are going to panic in case of error as we should never get into this state
46
+		panic("InitAddressPools failed to initialize the local scope default address pool")
47
+	}
48
+}
49
+
50
+// configDefaultNetworks configures local as well global default pool based on input
51
+func configDefaultNetworks(defaultAddressPool []*NetworkToSplit, result *[]*net.IPNet) error {
52
+	mutex.Lock()
53
+	defer mutex.Unlock()
54
+	defaultNetworks, err := splitNetworks(defaultAddressPool)
55
+	if err != nil {
56
+		return err
57
+	}
58
+	*result = defaultNetworks
59
+	return nil
60
+}
61
+
62
+// GetGlobalScopeDefaultNetworks returns PredefinedGlobalScopeDefaultNetworks
63
+func GetGlobalScopeDefaultNetworks() []*net.IPNet {
64
+	mutex.Lock()
65
+	defer mutex.Unlock()
66
+	return PredefinedGlobalScopeDefaultNetworks
67
+}
68
+
69
+// GetLocalScopeDefaultNetworks returns PredefinedLocalScopeDefaultNetworks
70
+func GetLocalScopeDefaultNetworks() []*net.IPNet {
71
+	mutex.Lock()
72
+	defer mutex.Unlock()
73
+	return PredefinedLocalScopeDefaultNetworks
74
+}
75
+
76
+// ConfigGlobalScopeDefaultNetworks configures global default pool.
77
+// Ideally this will be called from SwarmKit as part of swarm init
78
+func ConfigGlobalScopeDefaultNetworks(defaultAddressPool []*NetworkToSplit) error {
79
+	if defaultAddressPool == nil {
80
+		defaultAddressPool = globalScopeDefaultNetworks
81
+	}
82
+	return configDefaultNetworks(defaultAddressPool, &PredefinedGlobalScopeDefaultNetworks)
83
+}
84
+
85
+// ConfigLocalScopeDefaultNetworks configures local default pool.
86
+// Ideally this will be called during libnetwork init
87
+func ConfigLocalScopeDefaultNetworks(defaultAddressPool []*NetworkToSplit) error {
88
+	if defaultAddressPool == nil {
89
+		return nil
90
+	}
91
+	return configDefaultNetworks(defaultAddressPool, &PredefinedLocalScopeDefaultNetworks)
50 92
 }
51 93
 
52 94
 // splitNetworks takes a slice of networks, split them accordingly and returns them
... ...
@@ -94,8 +94,8 @@ func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
94 94
 	}
95 95
 
96 96
 	if link == nil || len(v4Nets) == 0 {
97
-		// Choose from predefined broad networks
98
-		v4Net, err := FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
97
+		// Choose from predefined local scope  networks
98
+		v4Net, err := FindAvailableNetwork(ipamutils.PredefinedLocalScopeDefaultNetworks)
99 99
 		if err != nil {
100 100
 			return nil, nil, err
101 101
 		}
... ...
@@ -84,9 +84,13 @@ func (*ListNodesRequest) ProtoMessage()               {}
84 84
 func (*ListNodesRequest) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{2} }
85 85
 
86 86
 type ListNodesRequest_Filters struct {
87
-	Names       []string              `protobuf:"bytes,1,rep,name=names" json:"names,omitempty"`
88
-	IDPrefixes  []string              `protobuf:"bytes,2,rep,name=id_prefixes,json=idPrefixes" json:"id_prefixes,omitempty"`
89
-	Labels      map[string]string     `protobuf:"bytes,3,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
87
+	Names      []string `protobuf:"bytes,1,rep,name=names" json:"names,omitempty"`
88
+	IDPrefixes []string `protobuf:"bytes,2,rep,name=id_prefixes,json=idPrefixes" json:"id_prefixes,omitempty"`
89
+	// Labels refers to engine labels, which are labels set by the user on the
90
+	// node and reported back to the managers
91
+	Labels map[string]string `protobuf:"bytes,3,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
92
+	// NodeLabels are labels set on the node object on the managers.
93
+	NodeLabels  map[string]string     `protobuf:"bytes,7,rep,name=node_labels,json=nodeLabels" json:"node_labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
90 94
 	Memberships []NodeSpec_Membership `protobuf:"varint,4,rep,name=memberships,enum=docker.swarmkit.v1.NodeSpec_Membership" json:"memberships,omitempty"`
91 95
 	Roles       []NodeRole            `protobuf:"varint,5,rep,name=roles,enum=docker.swarmkit.v1.NodeRole" json:"roles,omitempty"`
92 96
 	// NamePrefixes matches all objects with the given prefixes
... ...
@@ -1105,6 +1109,13 @@ func (m *ListNodesRequest_Filters) CopyFrom(src interface{}) {
1105 1105
 		}
1106 1106
 	}
1107 1107
 
1108
+	if o.NodeLabels != nil {
1109
+		m.NodeLabels = make(map[string]string, len(o.NodeLabels))
1110
+		for k, v := range o.NodeLabels {
1111
+			m.NodeLabels[k] = v
1112
+		}
1113
+	}
1114
+
1108 1115
 	if o.Memberships != nil {
1109 1116
 		m.Memberships = make([]NodeSpec_Membership, len(o.Memberships))
1110 1117
 		copy(m.Memberships, o.Memberships)
... ...
@@ -3640,6 +3651,23 @@ func (m *ListNodesRequest_Filters) MarshalTo(dAtA []byte) (int, error) {
3640 3640
 			i += copy(dAtA[i:], s)
3641 3641
 		}
3642 3642
 	}
3643
+	if len(m.NodeLabels) > 0 {
3644
+		for k, _ := range m.NodeLabels {
3645
+			dAtA[i] = 0x3a
3646
+			i++
3647
+			v := m.NodeLabels[k]
3648
+			mapSize := 1 + len(k) + sovControl(uint64(len(k))) + 1 + len(v) + sovControl(uint64(len(v)))
3649
+			i = encodeVarintControl(dAtA, i, uint64(mapSize))
3650
+			dAtA[i] = 0xa
3651
+			i++
3652
+			i = encodeVarintControl(dAtA, i, uint64(len(k)))
3653
+			i += copy(dAtA[i:], k)
3654
+			dAtA[i] = 0x12
3655
+			i++
3656
+			i = encodeVarintControl(dAtA, i, uint64(len(v)))
3657
+			i += copy(dAtA[i:], v)
3658
+		}
3659
+	}
3643 3660
 	return i, nil
3644 3661
 }
3645 3662
 
... ...
@@ -6985,6 +7013,14 @@ func (m *ListNodesRequest_Filters) Size() (n int) {
6985 6985
 			n += 1 + l + sovControl(uint64(l))
6986 6986
 		}
6987 6987
 	}
6988
+	if len(m.NodeLabels) > 0 {
6989
+		for k, v := range m.NodeLabels {
6990
+			_ = k
6991
+			_ = v
6992
+			mapEntrySize := 1 + len(k) + sovControl(uint64(len(k))) + 1 + len(v) + sovControl(uint64(len(v)))
6993
+			n += mapEntrySize + 1 + sovControl(uint64(mapEntrySize))
6994
+		}
6995
+	}
6988 6996
 	return n
6989 6997
 }
6990 6998
 
... ...
@@ -7883,6 +7919,16 @@ func (this *ListNodesRequest_Filters) String() string {
7883 7883
 		mapStringForLabels += fmt.Sprintf("%v: %v,", k, this.Labels[k])
7884 7884
 	}
7885 7885
 	mapStringForLabels += "}"
7886
+	keysForNodeLabels := make([]string, 0, len(this.NodeLabels))
7887
+	for k, _ := range this.NodeLabels {
7888
+		keysForNodeLabels = append(keysForNodeLabels, k)
7889
+	}
7890
+	sortkeys.Strings(keysForNodeLabels)
7891
+	mapStringForNodeLabels := "map[string]string{"
7892
+	for _, k := range keysForNodeLabels {
7893
+		mapStringForNodeLabels += fmt.Sprintf("%v: %v,", k, this.NodeLabels[k])
7894
+	}
7895
+	mapStringForNodeLabels += "}"
7886 7896
 	s := strings.Join([]string{`&ListNodesRequest_Filters{`,
7887 7897
 		`Names:` + fmt.Sprintf("%v", this.Names) + `,`,
7888 7898
 		`IDPrefixes:` + fmt.Sprintf("%v", this.IDPrefixes) + `,`,
... ...
@@ -7890,6 +7936,7 @@ func (this *ListNodesRequest_Filters) String() string {
7890 7890
 		`Memberships:` + fmt.Sprintf("%v", this.Memberships) + `,`,
7891 7891
 		`Roles:` + fmt.Sprintf("%v", this.Roles) + `,`,
7892 7892
 		`NamePrefixes:` + fmt.Sprintf("%v", this.NamePrefixes) + `,`,
7893
+		`NodeLabels:` + mapStringForNodeLabels + `,`,
7893 7894
 		`}`,
7894 7895
 	}, "")
7895 7896
 	return s
... ...
@@ -9221,6 +9268,124 @@ func (m *ListNodesRequest_Filters) Unmarshal(dAtA []byte) error {
9221 9221
 			}
9222 9222
 			m.NamePrefixes = append(m.NamePrefixes, string(dAtA[iNdEx:postIndex]))
9223 9223
 			iNdEx = postIndex
9224
+		case 7:
9225
+			if wireType != 2 {
9226
+				return fmt.Errorf("proto: wrong wireType = %d for field NodeLabels", wireType)
9227
+			}
9228
+			var msglen int
9229
+			for shift := uint(0); ; shift += 7 {
9230
+				if shift >= 64 {
9231
+					return ErrIntOverflowControl
9232
+				}
9233
+				if iNdEx >= l {
9234
+					return io.ErrUnexpectedEOF
9235
+				}
9236
+				b := dAtA[iNdEx]
9237
+				iNdEx++
9238
+				msglen |= (int(b) & 0x7F) << shift
9239
+				if b < 0x80 {
9240
+					break
9241
+				}
9242
+			}
9243
+			if msglen < 0 {
9244
+				return ErrInvalidLengthControl
9245
+			}
9246
+			postIndex := iNdEx + msglen
9247
+			if postIndex > l {
9248
+				return io.ErrUnexpectedEOF
9249
+			}
9250
+			if m.NodeLabels == nil {
9251
+				m.NodeLabels = make(map[string]string)
9252
+			}
9253
+			var mapkey string
9254
+			var mapvalue string
9255
+			for iNdEx < postIndex {
9256
+				entryPreIndex := iNdEx
9257
+				var wire uint64
9258
+				for shift := uint(0); ; shift += 7 {
9259
+					if shift >= 64 {
9260
+						return ErrIntOverflowControl
9261
+					}
9262
+					if iNdEx >= l {
9263
+						return io.ErrUnexpectedEOF
9264
+					}
9265
+					b := dAtA[iNdEx]
9266
+					iNdEx++
9267
+					wire |= (uint64(b) & 0x7F) << shift
9268
+					if b < 0x80 {
9269
+						break
9270
+					}
9271
+				}
9272
+				fieldNum := int32(wire >> 3)
9273
+				if fieldNum == 1 {
9274
+					var stringLenmapkey uint64
9275
+					for shift := uint(0); ; shift += 7 {
9276
+						if shift >= 64 {
9277
+							return ErrIntOverflowControl
9278
+						}
9279
+						if iNdEx >= l {
9280
+							return io.ErrUnexpectedEOF
9281
+						}
9282
+						b := dAtA[iNdEx]
9283
+						iNdEx++
9284
+						stringLenmapkey |= (uint64(b) & 0x7F) << shift
9285
+						if b < 0x80 {
9286
+							break
9287
+						}
9288
+					}
9289
+					intStringLenmapkey := int(stringLenmapkey)
9290
+					if intStringLenmapkey < 0 {
9291
+						return ErrInvalidLengthControl
9292
+					}
9293
+					postStringIndexmapkey := iNdEx + intStringLenmapkey
9294
+					if postStringIndexmapkey > l {
9295
+						return io.ErrUnexpectedEOF
9296
+					}
9297
+					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
9298
+					iNdEx = postStringIndexmapkey
9299
+				} else if fieldNum == 2 {
9300
+					var stringLenmapvalue uint64
9301
+					for shift := uint(0); ; shift += 7 {
9302
+						if shift >= 64 {
9303
+							return ErrIntOverflowControl
9304
+						}
9305
+						if iNdEx >= l {
9306
+							return io.ErrUnexpectedEOF
9307
+						}
9308
+						b := dAtA[iNdEx]
9309
+						iNdEx++
9310
+						stringLenmapvalue |= (uint64(b) & 0x7F) << shift
9311
+						if b < 0x80 {
9312
+							break
9313
+						}
9314
+					}
9315
+					intStringLenmapvalue := int(stringLenmapvalue)
9316
+					if intStringLenmapvalue < 0 {
9317
+						return ErrInvalidLengthControl
9318
+					}
9319
+					postStringIndexmapvalue := iNdEx + intStringLenmapvalue
9320
+					if postStringIndexmapvalue > l {
9321
+						return io.ErrUnexpectedEOF
9322
+					}
9323
+					mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
9324
+					iNdEx = postStringIndexmapvalue
9325
+				} else {
9326
+					iNdEx = entryPreIndex
9327
+					skippy, err := skipControl(dAtA[iNdEx:])
9328
+					if err != nil {
9329
+						return err
9330
+					}
9331
+					if skippy < 0 {
9332
+						return ErrInvalidLengthControl
9333
+					}
9334
+					if (iNdEx + skippy) > postIndex {
9335
+						return io.ErrUnexpectedEOF
9336
+					}
9337
+					iNdEx += skippy
9338
+				}
9339
+			}
9340
+			m.NodeLabels[mapkey] = mapvalue
9341
+			iNdEx = postIndex
9224 9342
 		default:
9225 9343
 			iNdEx = preIndex
9226 9344
 			skippy, err := skipControl(dAtA[iNdEx:])
... ...
@@ -15950,139 +16115,141 @@ var (
15950 15950
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/control.proto", fileDescriptorControl) }
15951 15951
 
15952 15952
 var fileDescriptorControl = []byte{
15953
-	// 2137 bytes of a gzipped FileDescriptorProto
15954
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4f, 0x73, 0x1b, 0x49,
15955
-	0x15, 0xb7, 0xfe, 0xd8, 0x92, 0x9f, 0x6c, 0xd9, 0xee, 0x38, 0xa0, 0x52, 0x82, 0x9d, 0x9a, 0x90,
15956
-	0x44, 0xd9, 0x32, 0x12, 0xab, 0xb0, 0x6c, 0x58, 0x8a, 0x3f, 0x6b, 0x3b, 0x9b, 0xd5, 0x7a, 0xe3,
15957
-	0xa4, 0xc6, 0xc9, 0x16, 0x37, 0x95, 0x2c, 0xb5, 0xbd, 0x13, 0xc9, 0x1a, 0x31, 0x33, 0xf2, 0xae,
15958
-	0x8b, 0x0b, 0x50, 0xcb, 0x81, 0x0f, 0x40, 0x15, 0x57, 0xae, 0x1c, 0x38, 0x70, 0xe2, 0xc0, 0x07,
15959
-	0x48, 0x71, 0xe2, 0xc8, 0xc9, 0xb0, 0xaa, 0x82, 0xe2, 0xc4, 0x67, 0xa0, 0xba, 0xfb, 0xf5, 0xfc,
15960
-	0x53, 0xcf, 0x8c, 0x24, 0xab, 0xca, 0x39, 0x59, 0xd3, 0xf3, 0x7b, 0xfd, 0x5e, 0xf7, 0xfb, 0xf5,
15961
-	0x6f, 0xba, 0x5f, 0x1b, 0x76, 0x4e, 0x0d, 0xe7, 0xf3, 0xe1, 0x71, 0xb5, 0x6d, 0x9e, 0xd5, 0x3a,
15962
-	0x66, 0xbb, 0x4b, 0xad, 0x9a, 0xfd, 0x45, 0xcb, 0x3a, 0xeb, 0x1a, 0x4e, 0xad, 0x35, 0x30, 0x6a,
15963
-	0x6d, 0xb3, 0xef, 0x58, 0x66, 0xaf, 0x3a, 0xb0, 0x4c, 0xc7, 0x24, 0x44, 0x40, 0xaa, 0x12, 0x52,
15964
-	0x3d, 0x7f, 0xb7, 0xfc, 0x4e, 0x42, 0x0f, 0xf6, 0x80, 0xb6, 0x6d, 0x61, 0x5f, 0x4e, 0xf2, 0x66,
15965
-	0x1e, 0xbf, 0xa6, 0x6d, 0x47, 0xa2, 0x93, 0x7a, 0x76, 0x2e, 0x06, 0x54, 0x62, 0x37, 0x4f, 0xcd,
15966
-	0x53, 0x93, 0xff, 0xac, 0xb1, 0x5f, 0xd8, 0xfa, 0x7e, 0x4c, 0x0f, 0x1c, 0x71, 0x3c, 0x3c, 0xa9,
15967
-	0x0d, 0x7a, 0xc3, 0x53, 0xa3, 0x8f, 0x7f, 0x84, 0xa1, 0xf6, 0x1e, 0x14, 0x9f, 0x52, 0xe7, 0xd0,
15968
-	0xec, 0x50, 0x9d, 0xfe, 0x7c, 0x48, 0x6d, 0x87, 0xdc, 0x85, 0x5c, 0xdf, 0xec, 0xd0, 0xa6, 0xd1,
15969
-	0x29, 0xa5, 0xee, 0xa4, 0x2a, 0xcb, 0xbb, 0x30, 0xba, 0xdc, 0x5e, 0x62, 0x88, 0xc6, 0xbe, 0xbe,
15970
-	0xc4, 0x5e, 0x35, 0x3a, 0xda, 0x4f, 0x60, 0xcd, 0x35, 0xb3, 0x07, 0x66, 0xdf, 0xa6, 0x64, 0x07,
15971
-	0xb2, 0xec, 0x25, 0x37, 0x2a, 0xd4, 0x4b, 0xd5, 0xf1, 0x19, 0xac, 0x72, 0x3c, 0x47, 0x69, 0xff,
15972
-	0xc9, 0xc0, 0xfa, 0xa7, 0x86, 0xcd, 0xbb, 0xb0, 0xa5, 0xeb, 0x8f, 0x20, 0x77, 0x62, 0xf4, 0x1c,
15973
-	0x6a, 0xd9, 0xd8, 0xcb, 0x8e, 0xaa, 0x97, 0xb0, 0x59, 0xf5, 0x23, 0x61, 0xa3, 0x4b, 0xe3, 0xf2,
15974
-	0x6f, 0x33, 0x90, 0xc3, 0x46, 0xb2, 0x09, 0x8b, 0xfd, 0xd6, 0x19, 0x65, 0x3d, 0x66, 0x2a, 0xcb,
15975
-	0xba, 0x78, 0x20, 0x35, 0x28, 0x18, 0x9d, 0xe6, 0xc0, 0xa2, 0x27, 0xc6, 0x97, 0xd4, 0x2e, 0xa5,
15976
-	0xd9, 0xbb, 0xdd, 0xe2, 0xe8, 0x72, 0x1b, 0x1a, 0xfb, 0x2f, 0xb0, 0x55, 0x07, 0xa3, 0x23, 0x7f,
15977
-	0x93, 0x17, 0xb0, 0xd4, 0x6b, 0x1d, 0xd3, 0x9e, 0x5d, 0xca, 0xdc, 0xc9, 0x54, 0x0a, 0xf5, 0xc7,
15978
-	0xd3, 0x44, 0x56, 0xfd, 0x94, 0x9b, 0x3e, 0xe9, 0x3b, 0xd6, 0x85, 0x8e, 0xfd, 0x90, 0x67, 0x50,
15979
-	0x38, 0xa3, 0x67, 0xc7, 0xd4, 0xb2, 0x3f, 0x37, 0x06, 0x76, 0x29, 0x7b, 0x27, 0x53, 0x29, 0xd6,
15980
-	0x1f, 0x44, 0x4d, 0xdb, 0xd1, 0x80, 0xb6, 0xab, 0xcf, 0x5c, 0xfc, 0x6e, 0x7a, 0x7d, 0x41, 0xf7,
15981
-	0xdb, 0x93, 0xef, 0xc3, 0xa2, 0x65, 0xf6, 0xa8, 0x5d, 0x5a, 0xe4, 0x1d, 0xdd, 0x8e, 0x9c, 0x7f,
15982
-	0xb3, 0x47, 0xb9, 0xb5, 0x80, 0x93, 0xbb, 0xb0, 0xca, 0xa6, 0xc4, 0x9b, 0x8b, 0x25, 0x3e, 0x4f,
15983
-	0x2b, 0xac, 0x51, 0x8e, 0xbe, 0xfc, 0x03, 0x28, 0xf8, 0x86, 0x40, 0xd6, 0x21, 0xd3, 0xa5, 0x17,
15984
-	0x82, 0x1e, 0x3a, 0xfb, 0xc9, 0x66, 0xf9, 0xbc, 0xd5, 0x1b, 0xd2, 0x52, 0x9a, 0xb7, 0x89, 0x87,
15985
-	0x0f, 0xd2, 0x8f, 0x53, 0xda, 0x1e, 0x6c, 0xf8, 0xa6, 0x05, 0xb9, 0x52, 0x85, 0x45, 0xc6, 0x02,
15986
-	0x91, 0x94, 0x38, 0xb2, 0x08, 0x98, 0xf6, 0xc7, 0x14, 0x6c, 0xbc, 0x1a, 0x74, 0x5a, 0x0e, 0x9d,
15987
-	0x96, 0xa9, 0xe4, 0xc7, 0xb0, 0xc2, 0x41, 0xe7, 0xd4, 0xb2, 0x0d, 0xb3, 0xcf, 0x03, 0x2c, 0xd4,
15988
-	0x6f, 0xa9, 0x3c, 0x7e, 0x26, 0x20, 0x7a, 0x81, 0x19, 0xe0, 0x03, 0xf9, 0x2e, 0x64, 0xd9, 0xc2,
15989
-	0x2e, 0x65, 0xb8, 0xdd, 0xed, 0xb8, 0xfc, 0xe8, 0x1c, 0xa9, 0xed, 0x02, 0xf1, 0xc7, 0x3a, 0xd3,
15990
-	0xf2, 0x38, 0x84, 0x0d, 0x9d, 0x9e, 0x99, 0xe7, 0xd3, 0x8f, 0x77, 0x13, 0x16, 0x4f, 0x4c, 0xab,
15991
-	0x2d, 0x32, 0x91, 0xd7, 0xc5, 0x83, 0xb6, 0x09, 0xc4, 0xdf, 0x9f, 0x88, 0x09, 0x17, 0xff, 0xcb,
15992
-	0x96, 0xdd, 0xf5, 0xb9, 0x70, 0x5a, 0x76, 0x37, 0xe4, 0x82, 0x21, 0x98, 0x0b, 0xf6, 0xca, 0x5d,
15993
-	0xfc, 0xc2, 0xcc, 0x1b, 0x1d, 0x7b, 0x19, 0x37, 0x3a, 0x8e, 0xe7, 0x28, 0xed, 0xb1, 0x1c, 0xdd,
15994
-	0xd4, 0xae, 0xdd, 0x71, 0xf8, 0xbd, 0x6b, 0x7f, 0xcd, 0x0a, 0x31, 0x61, 0x8d, 0x33, 0x88, 0x89,
15995
-	0xdf, 0x6c, 0x5c, 0x4c, 0xfe, 0x79, 0x8d, 0x62, 0xa2, 0x8a, 0x4c, 0x29, 0x26, 0x35, 0x28, 0xd8,
15996
-	0xd4, 0x3a, 0x37, 0xda, 0x8c, 0x1d, 0x42, 0x4c, 0x30, 0x84, 0x23, 0xd1, 0xdc, 0xd8, 0xb7, 0x75,
15997
-	0x40, 0x48, 0xa3, 0x63, 0x93, 0xfb, 0x90, 0x47, 0x2e, 0x09, 0xc5, 0x58, 0xde, 0x2d, 0x8c, 0x2e,
15998
-	0xb7, 0x73, 0x82, 0x4c, 0xb6, 0x9e, 0x13, 0x6c, 0xb2, 0xc9, 0xc7, 0x50, 0xec, 0x50, 0xdb, 0xb0,
15999
-	0x68, 0xa7, 0x69, 0x3b, 0x2d, 0x07, 0xf5, 0xa1, 0x58, 0xff, 0x56, 0x54, 0x8a, 0x8f, 0x18, 0x8a,
16000
-	0x0b, 0xcc, 0x2a, 0x1a, 0xf2, 0x16, 0x85, 0xd0, 0xe4, 0xc6, 0x85, 0x86, 0xdc, 0x06, 0x18, 0x0e,
16001
-	0x9a, 0x8e, 0xd9, 0x64, 0xeb, 0xa7, 0x94, 0xe7, 0x14, 0xce, 0x0f, 0x07, 0x2f, 0xcd, 0xfd, 0x96,
16002
-	0x43, 0x49, 0x19, 0xf2, 0xd6, 0xb0, 0xef, 0x18, 0x2c, 0x03, 0xcb, 0xdc, 0xda, 0x7d, 0x9e, 0x83,
16003
-	0x44, 0xe1, 0x64, 0x7b, 0x12, 0xc5, 0x38, 0x17, 0x2b, 0x51, 0x9c, 0x84, 0x02, 0xa6, 0x1d, 0xc0,
16004
-	0xe6, 0x9e, 0x45, 0x5b, 0x0e, 0xc5, 0x09, 0x97, 0x34, 0x7c, 0x84, 0xfa, 0x21, 0x38, 0xb8, 0xad,
16005
-	0xea, 0x06, 0x2d, 0x7c, 0x12, 0x72, 0x08, 0x37, 0x43, 0x9d, 0x61, 0x54, 0xef, 0x41, 0x0e, 0x93,
16006
-	0x88, 0x1d, 0xde, 0x8a, 0xe9, 0x50, 0x97, 0x58, 0xed, 0x35, 0x6c, 0x3c, 0xa5, 0x4e, 0x28, 0xb2,
16007
-	0x1d, 0x00, 0x8f, 0x33, 0xb8, 0xe6, 0x56, 0x47, 0x97, 0xdb, 0xcb, 0x2e, 0x65, 0xf4, 0x65, 0x97,
16008
-	0x31, 0xe4, 0x01, 0xac, 0x19, 0x7d, 0x9b, 0x5a, 0x4e, 0xb3, 0x43, 0x4f, 0x5a, 0xc3, 0x9e, 0x63,
16009
-	0xa3, 0xc2, 0x14, 0x45, 0xf3, 0x3e, 0xb6, 0x6a, 0x07, 0x40, 0xfc, 0xbe, 0xae, 0x16, 0xf8, 0x9f,
16010
-	0xd3, 0xb0, 0x29, 0xc4, 0xf4, 0x4a, 0xc1, 0xef, 0xc3, 0x9a, 0x44, 0x4f, 0xf1, 0x1d, 0x28, 0xa2,
16011
-	0x8d, 0xfc, 0x14, 0x3c, 0x0a, 0x7c, 0x0a, 0x26, 0x4b, 0x25, 0x79, 0x06, 0x79, 0xcb, 0xec, 0xf5,
16012
-	0x8e, 0x5b, 0xed, 0x6e, 0x29, 0x7b, 0x27, 0x55, 0x29, 0xd6, 0xdf, 0x55, 0x19, 0xaa, 0x06, 0x59,
16013
-	0xd5, 0xd1, 0x50, 0x77, 0xbb, 0xd0, 0x34, 0xc8, 0xcb, 0x56, 0x92, 0x87, 0xec, 0xe1, 0xf3, 0xc3,
16014
-	0x27, 0xeb, 0x0b, 0x64, 0x05, 0xf2, 0x2f, 0xf4, 0x27, 0x9f, 0x35, 0x9e, 0xbf, 0x3a, 0x5a, 0x4f,
16015
-	0x31, 0xf6, 0x84, 0xba, 0xbb, 0x5a, 0x12, 0xf6, 0x61, 0x53, 0x88, 0xee, 0x55, 0x72, 0xa0, 0x7d,
16016
-	0x13, 0x6e, 0x86, 0x7a, 0x41, 0xf5, 0xfe, 0x2a, 0x03, 0x37, 0xd8, 0xfa, 0xc3, 0x76, 0x57, 0xc0,
16017
-	0x1b, 0x61, 0x01, 0xaf, 0x45, 0xc9, 0x64, 0xc8, 0x72, 0x5c, 0xc3, 0xff, 0x90, 0x9e, 0xbb, 0x86,
16018
-	0x1f, 0x85, 0x34, 0xfc, 0x87, 0x53, 0x06, 0xa7, 0x94, 0xf1, 0x31, 0x8d, 0xcc, 0x2a, 0x34, 0xd2,
16019
-	0xaf, 0x82, 0x8b, 0xf3, 0x53, 0xc1, 0xe7, 0xb0, 0x19, 0x0c, 0x17, 0x49, 0xf3, 0x3e, 0xe4, 0x31,
16020
-	0x89, 0x52, 0x0b, 0x63, 0x59, 0xe3, 0x82, 0x3d, 0x45, 0x3c, 0xa4, 0xce, 0x17, 0xa6, 0xd5, 0x9d,
16021
-	0x42, 0x11, 0xd1, 0x42, 0xa5, 0x88, 0x6e, 0x67, 0x1e, 0xa7, 0xfb, 0xa2, 0x29, 0x8e, 0xd3, 0xd2,
16022
-	0x4a, 0x62, 0xb5, 0x57, 0x5c, 0x11, 0x43, 0x91, 0x11, 0xc8, 0xb2, 0x99, 0xc6, 0xf9, 0xe2, 0xbf,
16023
-	0x19, 0xc9, 0xd1, 0x86, 0x91, 0x3c, 0xed, 0x91, 0x1c, 0x6d, 0x19, 0xc9, 0x11, 0xd0, 0xe8, 0xa0,
16024
-	0xf8, 0xcd, 0x29, 0xc6, 0x9f, 0xc9, 0x75, 0x37, 0xf7, 0x30, 0xdd, 0xb5, 0x18, 0x8a, 0x54, 0xfb,
16025
-	0x6f, 0x5a, 0xac, 0x45, 0x6c, 0x9f, 0x61, 0x2d, 0x86, 0x2c, 0xc7, 0xd7, 0xe2, 0x6f, 0xae, 0x71,
16026
-	0x2d, 0x46, 0x04, 0x37, 0xf3, 0x5a, 0x9c, 0xc3, 0x7a, 0xf3, 0x42, 0xf2, 0xd6, 0x1b, 0x26, 0x2a,
16027
-	0x76, 0xbd, 0xc9, 0xcc, 0xb9, 0x60, 0xed, 0x43, 0x4e, 0xe9, 0xbd, 0xde, 0xd0, 0x76, 0xa8, 0xe5,
16028
-	0xd3, 0xe8, 0xb6, 0x68, 0x09, 0x69, 0x34, 0xe2, 0x18, 0x2f, 0x10, 0xe0, 0xd2, 0xd7, 0xed, 0xc2,
16029
-	0xa3, 0x2f, 0x42, 0xe2, 0xe8, 0x2b, 0xad, 0x24, 0xd6, 0xe5, 0x12, 0xbe, 0x98, 0x81, 0x4b, 0x21,
16030
-	0xcb, 0xb7, 0x8b, 0x4b, 0x11, 0xc1, 0x5d, 0x27, 0x97, 0xbc, 0x90, 0x3c, 0x2e, 0x61, 0x36, 0x62,
16031
-	0xb9, 0x24, 0x53, 0xe7, 0x82, 0xb5, 0xdf, 0xa5, 0xa0, 0x70, 0x40, 0x2f, 0x74, 0xd3, 0x69, 0x39,
16032
-	0x6c, 0xeb, 0xf3, 0x0e, 0x6c, 0x30, 0x92, 0x51, 0xab, 0xf9, 0xda, 0x34, 0xfa, 0x4d, 0xc7, 0xec,
16033
-	0xd2, 0x3e, 0x0f, 0x2d, 0xaf, 0xaf, 0x89, 0x17, 0x9f, 0x98, 0x46, 0xff, 0x25, 0x6b, 0x26, 0x3b,
16034
-	0x40, 0xce, 0x5a, 0xfd, 0xd6, 0x69, 0x10, 0x2c, 0x36, 0x8b, 0xeb, 0xf8, 0x46, 0x89, 0x1e, 0xf6,
16035
-	0x7b, 0x66, 0xbb, 0xdb, 0x64, 0xa3, 0xce, 0x04, 0xd0, 0xaf, 0xf8, 0x8b, 0x03, 0x7a, 0xa1, 0xfd,
16036
-	0xda, 0xdd, 0x0f, 0x5e, 0x85, 0xe7, 0x6c, 0x3f, 0x28, 0xd1, 0xd3, 0xec, 0x07, 0xd1, 0x66, 0x8a,
16037
-	0xfd, 0x20, 0x7a, 0xf7, 0xed, 0x07, 0x3f, 0x64, 0xfb, 0x41, 0x31, 0xab, 0x7c, 0x3f, 0x18, 0x61,
16038
-	0xe8, 0x9b, 0xfc, 0xdd, 0xec, 0x9b, 0xcb, 0xed, 0x05, 0xdd, 0x35, 0xf3, 0xf6, 0x77, 0x73, 0x5a,
16039
-	0xa8, 0x3f, 0x82, 0x75, 0xbe, 0x63, 0x6f, 0x5b, 0xd4, 0x91, 0xf3, 0xf9, 0x10, 0x96, 0x6d, 0xde,
16040
-	0xe0, 0x4d, 0xe7, 0xca, 0xe8, 0x72, 0x3b, 0x2f, 0x50, 0x8d, 0x7d, 0xf6, 0x9d, 0xe7, 0xbf, 0x3a,
16041
-	0xda, 0x53, 0x3c, 0x5c, 0x08, 0x73, 0x0c, 0xa5, 0x0e, 0x4b, 0x02, 0x80, 0x91, 0x94, 0xd5, 0x7b,
16042
-	0x06, 0x6e, 0x83, 0x48, 0xed, 0x2f, 0x29, 0xb8, 0x21, 0x37, 0xae, 0xb3, 0xc5, 0x42, 0x76, 0xa1,
16043
-	0x88, 0xd0, 0x29, 0xf2, 0xba, 0x2a, 0x4c, 0x64, 0x5a, 0xeb, 0x81, 0xb4, 0x6e, 0x45, 0x07, 0xee,
16044
-	0xdb, 0x9e, 0x7c, 0xe2, 0x1d, 0x53, 0xae, 0x3c, 0x0d, 0xff, 0x4e, 0x03, 0x11, 0x3b, 0x31, 0xf6,
16045
-	0xe8, 0xca, 0xe6, 0xc7, 0x61, 0xd9, 0xac, 0x46, 0xef, 0x38, 0xfd, 0x86, 0xe3, 0xaa, 0xf9, 0xd5,
16046
-	0xfc, 0x55, 0x53, 0x0f, 0xa9, 0xe6, 0x07, 0xd3, 0xc5, 0x76, 0x2d, 0xa2, 0x79, 0x20, 0x8f, 0x1d,
16047
-	0x18, 0x11, 0xa6, 0xec, 0x7b, 0xec, 0x90, 0xc4, 0x9b, 0x50, 0x32, 0xe3, 0x72, 0x26, 0xa1, 0x5a,
16048
-	0x03, 0x6e, 0xc8, 0x13, 0xbb, 0x9f, 0xba, 0xf5, 0xc0, 0x5e, 0x77, 0x62, 0x2e, 0x05, 0xbb, 0xba,
16049
-	0x02, 0x97, 0x7e, 0x0a, 0x37, 0xe4, 0xa1, 0x6b, 0xc6, 0xd5, 0xfd, 0x0d, 0xef, 0xf0, 0xe7, 0x8f,
16050
-	0x06, 0x45, 0x63, 0xcf, 0xec, 0x9f, 0x18, 0xa7, 0xbe, 0x6e, 0xdb, 0xbc, 0x21, 0xd4, 0xad, 0x40,
16051
-	0xb1, 0x6e, 0xc5, 0x6b, 0x57, 0x34, 0xa4, 0xb9, 0x37, 0x42, 0x01, 0x88, 0x1b, 0x21, 0xda, 0x20,
16052
-	0xd2, 0x27, 0x1a, 0xb3, 0xc6, 0xc2, 0x44, 0x03, 0xa1, 0xd3, 0x88, 0x86, 0x30, 0x99, 0x42, 0x34,
16053
-	0x84, 0x67, 0x95, 0x68, 0xcc, 0x61, 0x1a, 0xa4, 0x68, 0x88, 0xe6, 0x19, 0x44, 0x23, 0x68, 0xf8,
16054
-	0x76, 0x89, 0x86, 0x3a, 0xb6, 0xeb, 0x14, 0x0d, 0x37, 0x22, 0x4f, 0x34, 0x44, 0x22, 0x62, 0x45,
16055
-	0x03, 0x73, 0x26, 0xa1, 0x9e, 0x68, 0x04, 0xa9, 0x3b, 0x81, 0x68, 0xa8, 0xb8, 0x14, 0xec, 0xea,
16056
-	0x0a, 0x5c, 0x72, 0x45, 0x63, 0xe6, 0xd5, 0xed, 0x8a, 0x46, 0x30, 0x9a, 0xfa, 0xaf, 0x6e, 0x41,
16057
-	0x6e, 0x4f, 0x5c, 0xb4, 0x12, 0x03, 0x72, 0x78, 0x85, 0x48, 0x34, 0x55, 0x50, 0xc1, 0x6b, 0xc9,
16058
-	0xf2, 0xdd, 0x58, 0x0c, 0x8a, 0xd2, 0xcd, 0xbf, 0xfd, 0xe9, 0x7f, 0xbf, 0x4f, 0xaf, 0xc1, 0x2a,
16059
-	0x07, 0x7d, 0x07, 0xb7, 0x8f, 0xc4, 0x84, 0x65, 0xf7, 0x0e, 0x8a, 0x7c, 0x7b, 0x92, 0x9b, 0xbb,
16060
-	0xf2, 0xbd, 0x04, 0x54, 0xbc, 0x43, 0x0b, 0xc0, 0xbb, 0x02, 0x22, 0xf7, 0xa2, 0x0b, 0x7e, 0xfe,
16061
-	0x11, 0xde, 0x4f, 0x82, 0x25, 0xfa, 0xf4, 0xae, 0x78, 0xd4, 0x3e, 0xc7, 0xae, 0x94, 0xd4, 0x3e,
16062
-	0x15, 0x37, 0x45, 0x11, 0x3e, 0x45, 0x0e, 0x5f, 0xb6, 0xec, 0x6e, 0x64, 0x0e, 0x7d, 0x57, 0x3c,
16063
-	0x91, 0x39, 0x0c, 0x5c, 0xe6, 0xc4, 0xe7, 0x90, 0x17, 0xe9, 0xa3, 0x73, 0xe8, 0xbf, 0x30, 0x89,
16064
-	0xce, 0x61, 0xa0, 0xd2, 0x9f, 0x38, 0x9f, 0x7c, 0x78, 0x31, 0xf3, 0xe9, 0x1f, 0xe1, 0xfd, 0x24,
16065
-	0x58, 0xa2, 0x4f, 0xaf, 0x76, 0xae, 0xf6, 0x39, 0x56, 0xc7, 0x57, 0xfb, 0x1c, 0x2f, 0xc1, 0x47,
16066
-	0xf9, 0xfc, 0x12, 0x56, 0xfc, 0x75, 0x3f, 0xf2, 0x60, 0xc2, 0x42, 0x66, 0xb9, 0x92, 0x0c, 0x8c,
16067
-	0xf7, 0xfc, 0x0b, 0x58, 0x0d, 0xdc, 0x72, 0x10, 0x65, 0x8f, 0xaa, 0x5b, 0x95, 0xf2, 0xc3, 0x09,
16068
-	0x90, 0x89, 0xce, 0x03, 0x45, 0x72, 0xb5, 0x73, 0x55, 0x59, 0x5e, 0xed, 0x5c, 0x59, 0x71, 0x8f,
16069
-	0x71, 0x1e, 0xa8, 0x85, 0xab, 0x9d, 0xab, 0x8a, 0xee, 0x6a, 0xe7, 0xea, 0xc2, 0x7a, 0x2c, 0xc9,
16070
-	0xb0, 0x7e, 0x14, 0x49, 0xb2, 0x60, 0xcd, 0x31, 0x92, 0x64, 0xe1, 0x02, 0x62, 0x3c, 0xc9, 0x64,
16071
-	0xb1, 0x2b, 0x9a, 0x64, 0xa1, 0x0a, 0x5d, 0x34, 0xc9, 0xc2, 0x75, 0xb3, 0x44, 0x92, 0xc9, 0x01,
16072
-	0xc7, 0x90, 0x2c, 0x34, 0xe6, 0x87, 0x13, 0x20, 0x27, 0xcc, 0x73, 0xac, 0x73, 0x55, 0x91, 0x37,
16073
-	0x2e, 0xcf, 0x13, 0x3a, 0x17, 0x79, 0xc6, 0xd3, 0x7e, 0x64, 0x9e, 0x83, 0x75, 0x94, 0xc8, 0x3c,
16074
-	0x87, 0x4a, 0x0d, 0x09, 0x79, 0x96, 0x85, 0xa8, 0xe8, 0x3c, 0x87, 0xaa, 0x67, 0xd1, 0x79, 0x0e,
16075
-	0xd7, 0xb4, 0x12, 0xd7, 0xb3, 0x1c, 0x70, 0xcc, 0x7a, 0x0e, 0x8d, 0xf9, 0xe1, 0x04, 0xc8, 0xc4,
16076
-	0x8f, 0x93, 0x5b, 0x02, 0x51, 0x7f, 0x9c, 0xc2, 0x05, 0x96, 0xf2, 0xbd, 0x04, 0x54, 0xe2, 0x3c,
16077
-	0xfb, 0xeb, 0x0d, 0xea, 0x79, 0x56, 0xd4, 0x52, 0xca, 0x95, 0x64, 0x60, 0xbc, 0xe7, 0x21, 0x14,
16078
-	0x7c, 0xa7, 0x66, 0x72, 0x7f, 0xb2, 0x83, 0x7e, 0xf9, 0x41, 0x22, 0x2e, 0x71, 0xc0, 0xfe, 0x43,
16079
-	0xb1, 0x7a, 0xc0, 0x8a, 0x13, 0x78, 0xb9, 0x92, 0x0c, 0x4c, 0xf4, 0xec, 0x3f, 0x00, 0xab, 0x3d,
16080
-	0x2b, 0x0e, 0xd9, 0xe5, 0x4a, 0x32, 0x70, 0x12, 0x56, 0x89, 0x2d, 0x74, 0x24, 0xab, 0x02, 0x7b,
16081
-	0xf4, 0x48, 0x56, 0x05, 0xf7, 0xe1, 0x89, 0xac, 0x42, 0x9f, 0x31, 0xac, 0x0a, 0xba, 0xad, 0x24,
16082
-	0x03, 0x27, 0x62, 0x15, 0x1e, 0xab, 0xa2, 0x59, 0x15, 0x3c, 0x09, 0x46, 0xb3, 0x2a, 0x74, 0x3e,
16083
-	0x4b, 0x64, 0x55, 0xdc, 0x80, 0x15, 0x47, 0xb4, 0x38, 0x56, 0x4d, 0x3c, 0xd5, 0xfe, 0x13, 0x52,
16084
-	0x1c, 0xab, 0x26, 0xf0, 0xac, 0x3a, 0x6c, 0x45, 0x78, 0xde, 0x2d, 0xbd, 0xf9, 0x7a, 0x6b, 0xe1,
16085
-	0x1f, 0x5f, 0x6f, 0x2d, 0xfc, 0x72, 0xb4, 0x95, 0x7a, 0x33, 0xda, 0x4a, 0xfd, 0x7d, 0xb4, 0x95,
16086
-	0xfa, 0xd7, 0x68, 0x2b, 0x75, 0xbc, 0xc4, 0xff, 0x25, 0xf4, 0xd1, 0xff, 0x03, 0x00, 0x00, 0xff,
16087
-	0xff, 0x47, 0x18, 0x50, 0x6c, 0x2b, 0x2b, 0x00, 0x00,
15953
+	// 2167 bytes of a gzipped FileDescriptorProto
15954
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4d, 0x73, 0x1b, 0x49,
15955
+	0x19, 0xb6, 0x3e, 0x6c, 0xc9, 0xaf, 0x6c, 0xd9, 0xee, 0x78, 0x41, 0xa5, 0x04, 0x3b, 0x35, 0x21,
15956
+	0x89, 0xb2, 0x65, 0x24, 0x56, 0x61, 0xd9, 0xb0, 0xb0, 0xc0, 0xda, 0xce, 0x66, 0xb5, 0xde, 0x38,
15957
+	0xa9, 0x71, 0xb2, 0xc5, 0x85, 0x52, 0xc9, 0x52, 0xdb, 0x3b, 0x91, 0xac, 0x11, 0x33, 0x23, 0xef,
15958
+	0xba, 0xb8, 0x00, 0x15, 0x7e, 0x02, 0x55, 0x5c, 0x39, 0x51, 0xc5, 0x81, 0x03, 0x27, 0x0e, 0xfc,
15959
+	0x80, 0x14, 0x27, 0x8e, 0x9c, 0x0c, 0xab, 0x2a, 0xaa, 0x38, 0xf1, 0x1b, 0xa8, 0xee, 0x7e, 0x7b,
15960
+	0xbe, 0xd4, 0x33, 0xa3, 0x0f, 0x57, 0x79, 0x4f, 0x96, 0x7a, 0x9e, 0xf7, 0xa3, 0xfb, 0x7d, 0xfa,
15961
+	0x51, 0xf7, 0x3b, 0x86, 0x9d, 0x53, 0xc3, 0xf9, 0x7c, 0x78, 0x5c, 0x6d, 0x9b, 0x67, 0xb5, 0x8e,
15962
+	0xd9, 0xee, 0x52, 0xab, 0x66, 0x7f, 0xd1, 0xb2, 0xce, 0xba, 0x86, 0x53, 0x6b, 0x0d, 0x8c, 0x5a,
15963
+	0xdb, 0xec, 0x3b, 0x96, 0xd9, 0xab, 0x0e, 0x2c, 0xd3, 0x31, 0x09, 0x11, 0x90, 0xaa, 0x84, 0x54,
15964
+	0xcf, 0xdf, 0x29, 0xbf, 0x9d, 0xe0, 0xc1, 0x1e, 0xd0, 0xb6, 0x2d, 0xec, 0xcb, 0x49, 0xd1, 0xcc,
15965
+	0xe3, 0x57, 0xb4, 0xed, 0x48, 0x74, 0x92, 0x67, 0xe7, 0x62, 0x40, 0x25, 0x76, 0xf3, 0xd4, 0x3c,
15966
+	0x35, 0xf9, 0xc7, 0x1a, 0xfb, 0x84, 0xa3, 0xef, 0xc5, 0x78, 0xe0, 0x88, 0xe3, 0xe1, 0x49, 0x6d,
15967
+	0xd0, 0x1b, 0x9e, 0x1a, 0x7d, 0xfc, 0x23, 0x0c, 0xb5, 0x77, 0xa1, 0xf8, 0x84, 0x3a, 0x87, 0x66,
15968
+	0x87, 0xea, 0xf4, 0x17, 0x43, 0x6a, 0x3b, 0xe4, 0x0e, 0xe4, 0xfa, 0x66, 0x87, 0x36, 0x8d, 0x4e,
15969
+	0x29, 0x75, 0x3b, 0x55, 0x59, 0xde, 0x85, 0xd1, 0xe5, 0xf6, 0x12, 0x43, 0x34, 0xf6, 0xf5, 0x25,
15970
+	0xf6, 0xa8, 0xd1, 0xd1, 0x7e, 0x02, 0x6b, 0xae, 0x99, 0x3d, 0x30, 0xfb, 0x36, 0x25, 0x3b, 0x90,
15971
+	0x65, 0x0f, 0xb9, 0x51, 0xa1, 0x5e, 0xaa, 0x8e, 0xaf, 0x60, 0x95, 0xe3, 0x39, 0x4a, 0x7b, 0xbd,
15972
+	0x08, 0xeb, 0x9f, 0x1a, 0x36, 0x77, 0x61, 0xcb, 0xd0, 0x1f, 0x41, 0xee, 0xc4, 0xe8, 0x39, 0xd4,
15973
+	0xb2, 0xd1, 0xcb, 0x8e, 0xca, 0x4b, 0xd8, 0xac, 0xfa, 0x91, 0xb0, 0xd1, 0xa5, 0x71, 0xf9, 0x8f,
15974
+	0x59, 0xc8, 0xe1, 0x20, 0xd9, 0x84, 0xc5, 0x7e, 0xeb, 0x8c, 0x32, 0x8f, 0x99, 0xca, 0xb2, 0x2e,
15975
+	0xbe, 0x90, 0x1a, 0x14, 0x8c, 0x4e, 0x73, 0x60, 0xd1, 0x13, 0xe3, 0x4b, 0x6a, 0x97, 0xd2, 0xec,
15976
+	0xd9, 0x6e, 0x71, 0x74, 0xb9, 0x0d, 0x8d, 0xfd, 0xe7, 0x38, 0xaa, 0x83, 0xd1, 0x91, 0x9f, 0xc9,
15977
+	0x73, 0x58, 0xea, 0xb5, 0x8e, 0x69, 0xcf, 0x2e, 0x65, 0x6e, 0x67, 0x2a, 0x85, 0xfa, 0xa3, 0x69,
15978
+	0x32, 0xab, 0x7e, 0xca, 0x4d, 0x1f, 0xf7, 0x1d, 0xeb, 0x42, 0x47, 0x3f, 0xe4, 0x29, 0x14, 0xce,
15979
+	0xe8, 0xd9, 0x31, 0xb5, 0xec, 0xcf, 0x8d, 0x81, 0x5d, 0xca, 0xde, 0xce, 0x54, 0x8a, 0xf5, 0xfb,
15980
+	0x51, 0xcb, 0x76, 0x34, 0xa0, 0xed, 0xea, 0x53, 0x17, 0xbf, 0x9b, 0x5e, 0x5f, 0xd0, 0xfd, 0xf6,
15981
+	0xe4, 0xfb, 0xb0, 0x68, 0x99, 0x3d, 0x6a, 0x97, 0x16, 0xb9, 0xa3, 0x5b, 0x91, 0xeb, 0x6f, 0xf6,
15982
+	0x28, 0xb7, 0x16, 0x70, 0x72, 0x07, 0x56, 0xd9, 0x92, 0x78, 0x6b, 0xb1, 0xc4, 0xd7, 0x69, 0x85,
15983
+	0x0d, 0xba, 0xb3, 0xff, 0x39, 0x14, 0x38, 0x27, 0x70, 0x09, 0x72, 0x7c, 0x09, 0x7e, 0x34, 0xd5,
15984
+	0x12, 0xb0, 0x41, 0xff, 0x32, 0x40, 0xdf, 0x1d, 0x28, 0xff, 0x00, 0x0a, 0xbe, 0x47, 0x64, 0x1d,
15985
+	0x32, 0x5d, 0x7a, 0x21, 0xd8, 0xa7, 0xb3, 0x8f, 0xac, 0x88, 0xe7, 0xad, 0xde, 0x90, 0x96, 0xd2,
15986
+	0x7c, 0x4c, 0x7c, 0x79, 0x3f, 0xfd, 0x28, 0x55, 0xfe, 0x00, 0xd6, 0x42, 0x9e, 0xa7, 0x31, 0xd7,
15987
+	0xf6, 0x60, 0xc3, 0x97, 0x31, 0x32, 0xb9, 0x0a, 0x8b, 0x2c, 0x39, 0x41, 0x99, 0x38, 0x2a, 0x0b,
15988
+	0x98, 0xf6, 0xa7, 0x14, 0x6c, 0xbc, 0x1c, 0x74, 0x5a, 0x0e, 0x9d, 0x76, 0x1f, 0x91, 0x1f, 0xc3,
15989
+	0x0a, 0x07, 0x9d, 0x53, 0xcb, 0x36, 0xcc, 0x3e, 0x4f, 0xb0, 0x50, 0xbf, 0xa9, 0x8a, 0xf8, 0x99,
15990
+	0x80, 0xe8, 0xbc, 0x12, 0xf8, 0x85, 0x7c, 0x17, 0xb2, 0x4c, 0x76, 0x4a, 0x19, 0x6e, 0x77, 0x2b,
15991
+	0x8e, 0x3d, 0x3a, 0x47, 0x6a, 0xbb, 0x40, 0xfc, 0xb9, 0xce, 0xb4, 0x79, 0x0f, 0x61, 0x43, 0xa7,
15992
+	0x67, 0xe6, 0xf9, 0xf4, 0xf3, 0xdd, 0x84, 0xc5, 0x13, 0xd3, 0x6a, 0x8b, 0x4a, 0xe4, 0x75, 0xf1,
15993
+	0x45, 0xdb, 0x04, 0xe2, 0xf7, 0x27, 0x72, 0x42, 0x69, 0x7a, 0xd1, 0xb2, 0xbb, 0xbe, 0x10, 0x4e,
15994
+	0xcb, 0xee, 0x86, 0x42, 0x30, 0x04, 0x0b, 0xc1, 0x1e, 0xb9, 0xd2, 0x24, 0xcc, 0xbc, 0xd9, 0xb1,
15995
+	0x87, 0x71, 0xb3, 0xe3, 0x78, 0x8e, 0xd2, 0x1e, 0xc9, 0xd9, 0x4d, 0x1d, 0xda, 0x9d, 0x87, 0x3f,
15996
+	0xba, 0xf6, 0xb7, 0xac, 0x90, 0x3a, 0x36, 0x38, 0x83, 0xd4, 0xf9, 0xcd, 0xc6, 0xa5, 0xee, 0x5f,
15997
+	0x99, 0xeb, 0x93, 0x3a, 0x55, 0x66, 0x4a, 0xa9, 0xab, 0x41, 0xc1, 0xa6, 0xd6, 0xb9, 0xd1, 0x66,
15998
+	0xec, 0x10, 0x52, 0x87, 0x29, 0x1c, 0x89, 0xe1, 0xc6, 0xbe, 0xad, 0x03, 0x42, 0x1a, 0x1d, 0x9b,
15999
+	0xdc, 0x83, 0x3c, 0x72, 0x49, 0xe8, 0xd9, 0xf2, 0x6e, 0x61, 0x74, 0xb9, 0x9d, 0x13, 0x64, 0xb2,
16000
+	0xf5, 0x9c, 0x60, 0x93, 0x4d, 0x3e, 0x86, 0x62, 0x87, 0xda, 0x86, 0x45, 0x3b, 0x4d, 0xdb, 0x69,
16001
+	0x39, 0xa8, 0x5e, 0xc5, 0xfa, 0xb7, 0xa2, 0x4a, 0x7c, 0xc4, 0x50, 0x5c, 0xfe, 0x56, 0xd1, 0x90,
16002
+	0x8f, 0x28, 0x64, 0x30, 0xa7, 0x90, 0xc1, 0x5b, 0x00, 0xc3, 0x41, 0xd3, 0x31, 0x9b, 0x6c, 0xff,
16003
+	0x94, 0xf2, 0x9c, 0xc2, 0xf9, 0xe1, 0xe0, 0x85, 0xb9, 0xdf, 0x72, 0x28, 0x29, 0x43, 0xde, 0x1a,
16004
+	0xf6, 0x1d, 0x83, 0x55, 0x60, 0x99, 0x5b, 0xbb, 0xdf, 0xe7, 0x50, 0x38, 0x29, 0x51, 0xb8, 0xd8,
16005
+	0x9e, 0x44, 0x31, 0xce, 0xc5, 0x4a, 0x14, 0x27, 0xa1, 0x80, 0x69, 0x07, 0xb0, 0xb9, 0x67, 0xd1,
16006
+	0x96, 0x43, 0x71, 0xc1, 0x25, 0x0d, 0x1f, 0xa2, 0x7e, 0x08, 0x0e, 0x6e, 0xab, 0xdc, 0xa0, 0x85,
16007
+	0x4f, 0x42, 0x0e, 0xe1, 0xad, 0x90, 0x33, 0xcc, 0xea, 0x5d, 0xc8, 0x61, 0x11, 0xd1, 0xe1, 0xcd,
16008
+	0x18, 0x87, 0xba, 0xc4, 0x6a, 0xaf, 0x60, 0xe3, 0x09, 0x75, 0x42, 0x99, 0xed, 0x00, 0x78, 0x9c,
16009
+	0xc1, 0x3d, 0xb7, 0x3a, 0xba, 0xdc, 0x5e, 0x76, 0x29, 0xa3, 0x2f, 0xbb, 0x8c, 0x21, 0xf7, 0x61,
16010
+	0xcd, 0xe8, 0xdb, 0xd4, 0x72, 0x9a, 0x1d, 0x7a, 0xd2, 0x1a, 0xf6, 0x1c, 0x1b, 0x15, 0xa6, 0x28,
16011
+	0x86, 0xf7, 0x71, 0x54, 0x3b, 0x00, 0xe2, 0x8f, 0x35, 0x5f, 0xe2, 0x7f, 0x49, 0xc3, 0xa6, 0x10,
16012
+	0xd3, 0xb9, 0x92, 0xdf, 0x87, 0x35, 0x89, 0x9e, 0xe2, 0x77, 0xa0, 0x88, 0x36, 0xf2, 0xa7, 0xe0,
16013
+	0x61, 0xe0, 0xa7, 0x60, 0xb2, 0x52, 0x92, 0xa7, 0x90, 0xb7, 0xcc, 0x5e, 0xef, 0xb8, 0xd5, 0xee,
16014
+	0x96, 0xb2, 0xb7, 0x53, 0x95, 0x62, 0xfd, 0x1d, 0x95, 0xa1, 0x6a, 0x92, 0x55, 0x1d, 0x0d, 0x75,
16015
+	0xd7, 0x85, 0xa6, 0x41, 0x5e, 0x8e, 0x92, 0x3c, 0x64, 0x0f, 0x9f, 0x1d, 0x3e, 0x5e, 0x5f, 0x20,
16016
+	0x2b, 0x90, 0x7f, 0xae, 0x3f, 0xfe, 0xac, 0xf1, 0xec, 0xe5, 0xd1, 0x7a, 0x8a, 0xb1, 0x27, 0xe4,
16017
+	0x6e, 0xbe, 0x22, 0xec, 0xc3, 0xa6, 0x10, 0xdd, 0x79, 0x6a, 0xa0, 0x7d, 0x13, 0xde, 0x0a, 0x79,
16018
+	0x41, 0xf5, 0x7e, 0x9d, 0x81, 0x1b, 0x6c, 0xff, 0xe1, 0xb8, 0x2b, 0xe0, 0x8d, 0xb0, 0x80, 0xd7,
16019
+	0xa2, 0x64, 0x32, 0x64, 0x39, 0xae, 0xe1, 0x7f, 0x48, 0x5f, 0xb9, 0x86, 0x1f, 0x85, 0x34, 0xfc,
16020
+	0x87, 0x53, 0x26, 0xa7, 0x94, 0xf1, 0x31, 0x8d, 0xcc, 0x2a, 0x34, 0xd2, 0xaf, 0x82, 0x8b, 0x57,
16021
+	0xa7, 0x82, 0xcf, 0x60, 0x33, 0x98, 0x2e, 0x92, 0xe6, 0x3d, 0xc8, 0x63, 0x11, 0xa5, 0x16, 0xc6,
16022
+	0xb2, 0xc6, 0x05, 0x7b, 0x8a, 0x78, 0x48, 0x9d, 0x2f, 0x4c, 0xab, 0x3b, 0x85, 0x22, 0xa2, 0x85,
16023
+	0x4a, 0x11, 0x5d, 0x67, 0x1e, 0xa7, 0xfb, 0x62, 0x28, 0x8e, 0xd3, 0xd2, 0x4a, 0x62, 0xb5, 0x97,
16024
+	0x5c, 0x11, 0x43, 0x99, 0x11, 0xc8, 0xb2, 0x95, 0xc6, 0xf5, 0xe2, 0x9f, 0x19, 0xc9, 0xd1, 0x86,
16025
+	0x91, 0x3c, 0xed, 0x91, 0x1c, 0x6d, 0x19, 0xc9, 0x11, 0xd0, 0xe8, 0xa0, 0xf8, 0x5d, 0x51, 0x8e,
16026
+	0x3f, 0x93, 0xfb, 0xee, 0xca, 0xd3, 0x74, 0xf7, 0x62, 0x28, 0x53, 0xed, 0xbf, 0x69, 0xb1, 0x17,
16027
+	0x71, 0x7c, 0x86, 0xbd, 0x18, 0xb2, 0x1c, 0xdf, 0x8b, 0xbf, 0xbd, 0xc6, 0xbd, 0x18, 0x91, 0xdc,
16028
+	0xcc, 0x7b, 0xf1, 0x0a, 0xf6, 0x9b, 0x97, 0x92, 0xb7, 0xdf, 0xb0, 0x50, 0xb1, 0xfb, 0x4d, 0x56,
16029
+	0xce, 0x05, 0x6b, 0x1f, 0x72, 0x4a, 0xef, 0xf5, 0x86, 0xb6, 0x43, 0x2d, 0x9f, 0x46, 0xb7, 0xc5,
16030
+	0x48, 0x48, 0xa3, 0x11, 0xc7, 0x78, 0x81, 0x00, 0x97, 0xbe, 0xae, 0x0b, 0x8f, 0xbe, 0x08, 0x89,
16031
+	0xa3, 0xaf, 0xb4, 0x92, 0x58, 0x97, 0x4b, 0xf8, 0x60, 0x06, 0x2e, 0x85, 0x2c, 0xbf, 0x5e, 0x5c,
16032
+	0x8a, 0x48, 0xee, 0x3a, 0xb9, 0xe4, 0xa5, 0xe4, 0x71, 0x09, 0xab, 0x11, 0xcb, 0x25, 0x59, 0x3a,
16033
+	0x17, 0xac, 0xfd, 0x2e, 0x05, 0x85, 0x03, 0x7a, 0xa1, 0x9b, 0x4e, 0xcb, 0x61, 0x47, 0x9f, 0xb7,
16034
+	0x61, 0x83, 0x91, 0x8c, 0x5a, 0xcd, 0x57, 0xa6, 0xd1, 0x6f, 0x3a, 0x66, 0x97, 0xf6, 0x79, 0x6a,
16035
+	0x79, 0x7d, 0x4d, 0x3c, 0xf8, 0xc4, 0x34, 0xfa, 0x2f, 0xd8, 0x30, 0xd9, 0x01, 0x72, 0xd6, 0xea,
16036
+	0xb7, 0x4e, 0x83, 0x60, 0x71, 0x58, 0x5c, 0xc7, 0x27, 0x4a, 0xf4, 0xb0, 0xdf, 0x33, 0xdb, 0xdd,
16037
+	0x26, 0x9b, 0x75, 0x26, 0x80, 0x7e, 0xc9, 0x1f, 0x1c, 0xd0, 0x0b, 0xed, 0x37, 0xee, 0x79, 0x70,
16038
+	0x1e, 0x9e, 0xb3, 0xf3, 0xa0, 0x44, 0x4f, 0x73, 0x1e, 0x44, 0x9b, 0x29, 0xce, 0x83, 0x18, 0xdd,
16039
+	0x77, 0x1e, 0xfc, 0x90, 0x9d, 0x07, 0xc5, 0xaa, 0xf2, 0xf3, 0x60, 0x84, 0xa1, 0x6f, 0xf1, 0x77,
16040
+	0xb3, 0x6f, 0x2e, 0xb7, 0x17, 0x74, 0xd7, 0xcc, 0x3b, 0xdf, 0x5d, 0xd1, 0x46, 0xfd, 0x00, 0xd6,
16041
+	0xf9, 0x89, 0xbd, 0x6d, 0x51, 0x47, 0xae, 0xe7, 0x03, 0x58, 0xb6, 0xf9, 0x80, 0xb7, 0x9c, 0x2b,
16042
+	0xa3, 0xcb, 0xed, 0xbc, 0x40, 0x35, 0xf6, 0xd9, 0xef, 0x3c, 0xff, 0xd4, 0xd1, 0x9e, 0xe0, 0xe5,
16043
+	0x42, 0x98, 0x63, 0x2a, 0x75, 0x58, 0x12, 0x00, 0xcc, 0xa4, 0xac, 0x3e, 0x33, 0x70, 0x1b, 0x44,
16044
+	0x6a, 0x7f, 0x4d, 0xc1, 0x0d, 0x79, 0x70, 0x9d, 0x2d, 0x17, 0xb2, 0x0b, 0x45, 0x84, 0x4e, 0x51,
16045
+	0xd7, 0x55, 0x61, 0x22, 0xcb, 0x5a, 0x0f, 0x94, 0x75, 0x2b, 0x3a, 0x71, 0xdf, 0xf1, 0xe4, 0x13,
16046
+	0xef, 0x9a, 0x32, 0xf7, 0x32, 0xfc, 0x27, 0x0d, 0x44, 0x9c, 0xc4, 0xd8, 0x57, 0x57, 0x36, 0x3f,
16047
+	0x0e, 0xcb, 0x66, 0x35, 0xfa, 0xc4, 0xe9, 0x37, 0x1c, 0x57, 0xcd, 0xd7, 0x57, 0xaf, 0x9a, 0x7a,
16048
+	0x48, 0x35, 0xdf, 0x9f, 0x2e, 0xb7, 0x6b, 0x11, 0xcd, 0x03, 0x79, 0xed, 0xc0, 0x8c, 0xb0, 0x64,
16049
+	0xdf, 0x63, 0x97, 0x24, 0x3e, 0x84, 0x92, 0x19, 0x57, 0x33, 0x09, 0xd5, 0x1a, 0x70, 0x43, 0xde,
16050
+	0xd8, 0xfd, 0xd4, 0xad, 0x07, 0xce, 0xba, 0x13, 0x73, 0x29, 0xe8, 0x6a, 0x0e, 0x2e, 0xfd, 0x14,
16051
+	0x6e, 0xc8, 0x4b, 0xd7, 0x8c, 0xbb, 0xfb, 0x1b, 0xde, 0xe5, 0xcf, 0x9f, 0x0d, 0x8a, 0xc6, 0x9e,
16052
+	0xd9, 0x3f, 0x31, 0x4e, 0x7d, 0x6e, 0xdb, 0x7c, 0x20, 0xe4, 0x56, 0xa0, 0x98, 0x5b, 0xf1, 0xd8,
16053
+	0x15, 0x0d, 0x69, 0xee, 0xcd, 0x50, 0x00, 0xe2, 0x66, 0x88, 0x36, 0x88, 0xf4, 0x89, 0xc6, 0xac,
16054
+	0xb9, 0x30, 0xd1, 0x40, 0xe8, 0x34, 0xa2, 0x21, 0x4c, 0xa6, 0x10, 0x0d, 0x11, 0x59, 0x25, 0x1a,
16055
+	0x57, 0xb0, 0x0c, 0x52, 0x34, 0xc4, 0xf0, 0x0c, 0xa2, 0x11, 0x34, 0xfc, 0x7a, 0x89, 0x86, 0x3a,
16056
+	0xb7, 0xeb, 0x14, 0x0d, 0x37, 0x23, 0x4f, 0x34, 0x44, 0x21, 0x62, 0x45, 0x03, 0x6b, 0x26, 0xa1,
16057
+	0x9e, 0x68, 0x04, 0xa9, 0x3b, 0x81, 0x68, 0xa8, 0xb8, 0x14, 0x74, 0x35, 0x07, 0x97, 0x5c, 0xd1,
16058
+	0x98, 0x79, 0x77, 0xbb, 0xa2, 0x11, 0xcc, 0xa6, 0xfe, 0xeb, 0x9b, 0x90, 0xdb, 0x13, 0xaf, 0x81,
16059
+	0x89, 0x01, 0x39, 0x7c, 0xc1, 0x49, 0x34, 0x55, 0x52, 0xc1, 0x97, 0xa6, 0xe5, 0x3b, 0xb1, 0x18,
16060
+	0x14, 0xa5, 0xb7, 0xfe, 0xfe, 0xe7, 0xff, 0xfd, 0x3e, 0xbd, 0x06, 0xab, 0x1c, 0xf4, 0x1d, 0x3c,
16061
+	0x3e, 0x12, 0x13, 0x96, 0xdd, 0x77, 0x50, 0xe4, 0xdb, 0x93, 0xbc, 0x54, 0x2b, 0xdf, 0x4d, 0x40,
16062
+	0xc5, 0x07, 0xb4, 0x00, 0xbc, 0x57, 0x40, 0xe4, 0x6e, 0x74, 0xc3, 0xcf, 0x3f, 0xc3, 0x7b, 0x49,
16063
+	0xb0, 0xc4, 0x98, 0xde, 0x2b, 0x1e, 0x75, 0xcc, 0xb1, 0x57, 0x4a, 0xea, 0x98, 0x8a, 0x37, 0x45,
16064
+	0x11, 0x31, 0x45, 0x0d, 0x5f, 0xb4, 0xec, 0x6e, 0x64, 0x0d, 0x7d, 0xaf, 0x78, 0x22, 0x6b, 0x18,
16065
+	0x78, 0x99, 0x13, 0x5f, 0x43, 0xde, 0xa4, 0x8f, 0xae, 0xa1, 0xff, 0x85, 0x49, 0x74, 0x0d, 0x03,
16066
+	0x9d, 0xfe, 0xc4, 0xf5, 0xe4, 0xd3, 0x8b, 0x59, 0x4f, 0xff, 0x0c, 0xef, 0x25, 0xc1, 0x12, 0x63,
16067
+	0x7a, 0xbd, 0x73, 0x75, 0xcc, 0xb1, 0x3e, 0xbe, 0x3a, 0xe6, 0x78, 0x0b, 0x3e, 0x2a, 0xe6, 0x97,
16068
+	0xb0, 0xe2, 0xef, 0xfb, 0x91, 0xfb, 0x13, 0x36, 0x32, 0xcb, 0x95, 0x64, 0x60, 0x7c, 0xe4, 0x5f,
16069
+	0xc2, 0x6a, 0xe0, 0x2d, 0x07, 0x51, 0x7a, 0x54, 0xbd, 0x55, 0x29, 0x3f, 0x98, 0x00, 0x99, 0x18,
16070
+	0x3c, 0xd0, 0x24, 0x57, 0x07, 0x57, 0xb5, 0xe5, 0xd5, 0xc1, 0x95, 0x1d, 0xf7, 0x98, 0xe0, 0x81,
16071
+	0x5e, 0xb8, 0x3a, 0xb8, 0xaa, 0xe9, 0xae, 0x0e, 0xae, 0x6e, 0xac, 0xc7, 0x92, 0x0c, 0xfb, 0x47,
16072
+	0x91, 0x24, 0x0b, 0xf6, 0x1c, 0x23, 0x49, 0x16, 0x6e, 0x20, 0xc6, 0x93, 0x4c, 0x36, 0xbb, 0xa2,
16073
+	0x49, 0x16, 0xea, 0xd0, 0x45, 0x93, 0x2c, 0xdc, 0x37, 0x4b, 0x24, 0x99, 0x9c, 0x70, 0x0c, 0xc9,
16074
+	0x42, 0x73, 0x7e, 0x30, 0x01, 0x72, 0xc2, 0x3a, 0xc7, 0x06, 0x57, 0x35, 0x79, 0xe3, 0xea, 0x3c,
16075
+	0x61, 0x70, 0x51, 0x67, 0xbc, 0xed, 0x47, 0xd6, 0x39, 0xd8, 0x47, 0x89, 0xac, 0x73, 0xa8, 0xd5,
16076
+	0x90, 0x50, 0x67, 0xd9, 0x88, 0x8a, 0xae, 0x73, 0xa8, 0x7b, 0x16, 0x5d, 0xe7, 0x70, 0x4f, 0x2b,
16077
+	0x71, 0x3f, 0xcb, 0x09, 0xc7, 0xec, 0xe7, 0xd0, 0x9c, 0x1f, 0x4c, 0x80, 0x4c, 0xfc, 0x71, 0x72,
16078
+	0x5b, 0x20, 0xea, 0x1f, 0xa7, 0x70, 0x83, 0xa5, 0x7c, 0x37, 0x01, 0x95, 0xb8, 0xce, 0xfe, 0x7e,
16079
+	0x83, 0x7a, 0x9d, 0x15, 0xbd, 0x94, 0x72, 0x25, 0x19, 0x18, 0x1f, 0x79, 0x08, 0x05, 0xdf, 0xad,
16080
+	0x99, 0xdc, 0x9b, 0xec, 0xa2, 0x5f, 0xbe, 0x9f, 0x88, 0x4b, 0x9c, 0xb0, 0xff, 0x52, 0xac, 0x9e,
16081
+	0xb0, 0xe2, 0x06, 0x5e, 0xae, 0x24, 0x03, 0x13, 0x23, 0xfb, 0x2f, 0xc0, 0xea, 0xc8, 0x8a, 0x4b,
16082
+	0x76, 0xb9, 0x92, 0x0c, 0x9c, 0x84, 0x55, 0xe2, 0x08, 0x1d, 0xc9, 0xaa, 0xc0, 0x19, 0x3d, 0x92,
16083
+	0x55, 0xc1, 0x73, 0x78, 0x22, 0xab, 0x30, 0x66, 0x0c, 0xab, 0x82, 0x61, 0x2b, 0xc9, 0xc0, 0x89,
16084
+	0x58, 0x85, 0xd7, 0xaa, 0x68, 0x56, 0x05, 0x6f, 0x82, 0xd1, 0xac, 0x0a, 0xdd, 0xcf, 0x12, 0x59,
16085
+	0x15, 0x37, 0x61, 0xc5, 0x15, 0x2d, 0x8e, 0x55, 0x13, 0x2f, 0xb5, 0xff, 0x86, 0x14, 0xc7, 0xaa,
16086
+	0x09, 0x22, 0xab, 0x2e, 0x5b, 0x11, 0x91, 0x77, 0x4b, 0x6f, 0xbe, 0xda, 0x5a, 0xf8, 0xe7, 0x57,
16087
+	0x5b, 0x0b, 0xbf, 0x1a, 0x6d, 0xa5, 0xde, 0x8c, 0xb6, 0x52, 0xff, 0x18, 0x6d, 0xa5, 0xfe, 0x3d,
16088
+	0xda, 0x4a, 0x1d, 0x2f, 0xf1, 0x7f, 0x58, 0x7d, 0xf8, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x96,
16089
+	0x0e, 0xd9, 0x9f, 0xc9, 0x2b, 0x00, 0x00,
16088 16090
 }
... ...
@@ -175,7 +175,11 @@ message ListNodesRequest {
175 175
 	message Filters {
176 176
 		repeated string names = 1;
177 177
 		repeated string id_prefixes = 2;
178
+		// Labels refers to engine labels, which are labels set by the user on the
179
+		// node and reported back to the managers
178 180
 		map<string, string> labels = 3;
181
+		// NodeLabels are labels set on the node object on the managers.
182
+		map<string, string> node_labels = 7;
179 183
 		repeated NodeSpec.Membership memberships = 4 [packed=false];
180 184
 		repeated NodeRole roles = 5 [packed=false];
181 185
 		// NamePrefixes matches all objects with the given prefixes
... ...
@@ -274,6 +274,13 @@ type Cluster struct {
274 274
 	// reject joining the cluster.  Nodes that report themselves to be non-FIPS
275 275
 	// should be rejected from the cluster.
276 276
 	FIPS bool `protobuf:"varint,10,opt,name=fips,proto3" json:"fips,omitempty"`
277
+	// This field specifies default subnet pools for global scope networks. If
278
+	// unspecified, Docker will use the predefined subnets as it works on older releases.
279
+	// Format Example : {"20.20.0.0/16",""20.20.0.0/16"}
280
+	DefaultAddressPool []string `protobuf:"bytes,11,rep,name=defaultAddressPool" json:"defaultAddressPool,omitempty"`
281
+	// This flag specifies the default subnet size of global scope networks by giving
282
+	// the length of the subnet masks for every such network
283
+	SubnetSize uint32 `protobuf:"varint,12,opt,name=subnetSize,proto3" json:"subnetSize,omitempty"`
277 284
 }
278 285
 
279 286
 func (m *Cluster) Reset()                    { *m = Cluster{} }
... ...
@@ -658,6 +665,11 @@ func (m *Cluster) CopyFrom(src interface{}) {
658 658
 		}
659 659
 	}
660 660
 
661
+	if o.DefaultAddressPool != nil {
662
+		m.DefaultAddressPool = make([]string, len(o.DefaultAddressPool))
663
+		copy(m.DefaultAddressPool, o.DefaultAddressPool)
664
+	}
665
+
661 666
 }
662 667
 
663 668
 func (m *Secret) Copy() *Secret {
... ...
@@ -1440,6 +1452,26 @@ func (m *Cluster) MarshalTo(dAtA []byte) (int, error) {
1440 1440
 		}
1441 1441
 		i++
1442 1442
 	}
1443
+	if len(m.DefaultAddressPool) > 0 {
1444
+		for _, s := range m.DefaultAddressPool {
1445
+			dAtA[i] = 0x5a
1446
+			i++
1447
+			l = len(s)
1448
+			for l >= 1<<7 {
1449
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
1450
+				l >>= 7
1451
+				i++
1452
+			}
1453
+			dAtA[i] = uint8(l)
1454
+			i++
1455
+			i += copy(dAtA[i:], s)
1456
+		}
1457
+	}
1458
+	if m.SubnetSize != 0 {
1459
+		dAtA[i] = 0x60
1460
+		i++
1461
+		i = encodeVarintObjects(dAtA, i, uint64(m.SubnetSize))
1462
+	}
1443 1463
 	return i, nil
1444 1464
 }
1445 1465
 
... ...
@@ -1924,6 +1956,15 @@ func (m *Cluster) Size() (n int) {
1924 1924
 	if m.FIPS {
1925 1925
 		n += 2
1926 1926
 	}
1927
+	if len(m.DefaultAddressPool) > 0 {
1928
+		for _, s := range m.DefaultAddressPool {
1929
+			l = len(s)
1930
+			n += 1 + l + sovObjects(uint64(l))
1931
+		}
1932
+	}
1933
+	if m.SubnetSize != 0 {
1934
+		n += 1 + sovObjects(uint64(m.SubnetSize))
1935
+	}
1927 1936
 	return n
1928 1937
 }
1929 1938
 
... ...
@@ -4804,6 +4845,8 @@ func (this *Cluster) String() string {
4804 4804
 		`BlacklistedCertificates:` + mapStringForBlacklistedCertificates + `,`,
4805 4805
 		`UnlockKeys:` + strings.Replace(fmt.Sprintf("%v", this.UnlockKeys), "EncryptionKey", "EncryptionKey", 1) + `,`,
4806 4806
 		`FIPS:` + fmt.Sprintf("%v", this.FIPS) + `,`,
4807
+		`DefaultAddressPool:` + fmt.Sprintf("%v", this.DefaultAddressPool) + `,`,
4808
+		`SubnetSize:` + fmt.Sprintf("%v", this.SubnetSize) + `,`,
4807 4809
 		`}`,
4808 4810
 	}, "")
4809 4811
 	return s
... ...
@@ -7241,6 +7284,54 @@ func (m *Cluster) Unmarshal(dAtA []byte) error {
7241 7241
 				}
7242 7242
 			}
7243 7243
 			m.FIPS = bool(v != 0)
7244
+		case 11:
7245
+			if wireType != 2 {
7246
+				return fmt.Errorf("proto: wrong wireType = %d for field DefaultAddressPool", wireType)
7247
+			}
7248
+			var stringLen uint64
7249
+			for shift := uint(0); ; shift += 7 {
7250
+				if shift >= 64 {
7251
+					return ErrIntOverflowObjects
7252
+				}
7253
+				if iNdEx >= l {
7254
+					return io.ErrUnexpectedEOF
7255
+				}
7256
+				b := dAtA[iNdEx]
7257
+				iNdEx++
7258
+				stringLen |= (uint64(b) & 0x7F) << shift
7259
+				if b < 0x80 {
7260
+					break
7261
+				}
7262
+			}
7263
+			intStringLen := int(stringLen)
7264
+			if intStringLen < 0 {
7265
+				return ErrInvalidLengthObjects
7266
+			}
7267
+			postIndex := iNdEx + intStringLen
7268
+			if postIndex > l {
7269
+				return io.ErrUnexpectedEOF
7270
+			}
7271
+			m.DefaultAddressPool = append(m.DefaultAddressPool, string(dAtA[iNdEx:postIndex]))
7272
+			iNdEx = postIndex
7273
+		case 12:
7274
+			if wireType != 0 {
7275
+				return fmt.Errorf("proto: wrong wireType = %d for field SubnetSize", wireType)
7276
+			}
7277
+			m.SubnetSize = 0
7278
+			for shift := uint(0); ; shift += 7 {
7279
+				if shift >= 64 {
7280
+					return ErrIntOverflowObjects
7281
+				}
7282
+				if iNdEx >= l {
7283
+					return io.ErrUnexpectedEOF
7284
+				}
7285
+				b := dAtA[iNdEx]
7286
+				iNdEx++
7287
+				m.SubnetSize |= (uint32(b) & 0x7F) << shift
7288
+				if b < 0x80 {
7289
+					break
7290
+				}
7291
+			}
7244 7292
 		default:
7245 7293
 			iNdEx = preIndex
7246 7294
 			skippy, err := skipObjects(dAtA[iNdEx:])
... ...
@@ -8037,102 +8128,104 @@ var (
8037 8037
 func init() { proto.RegisterFile("github.com/docker/swarmkit/api/objects.proto", fileDescriptorObjects) }
8038 8038
 
8039 8039
 var fileDescriptorObjects = []byte{
8040
-	// 1544 bytes of a gzipped FileDescriptorProto
8041
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4d, 0x73, 0xdb, 0x4c,
8042
-	0x1d, 0xaf, 0x6c, 0xc5, 0x2f, 0x7f, 0x27, 0x26, 0xec, 0x13, 0x82, 0x6a, 0x82, 0x1d, 0xfc, 0x0c,
8043
-	0xcc, 0x33, 0xcf, 0x74, 0x9c, 0x12, 0x0a, 0xa4, 0x81, 0xd2, 0xda, 0x49, 0x68, 0x3d, 0xa5, 0x34,
8044
-	0xb3, 0x29, 0x2d, 0x37, 0xb1, 0x91, 0x36, 0xae, 0xb0, 0xac, 0xd5, 0x68, 0xd7, 0x2e, 0xbe, 0xf5,
8045
-	0x1c, 0x3e, 0x40, 0x6e, 0x1c, 0xfa, 0x2d, 0xb8, 0x70, 0xe0, 0xd4, 0x23, 0xc3, 0x81, 0xe1, 0x94,
8046
-	0xa1, 0xfe, 0x16, 0xcc, 0x70, 0x60, 0x76, 0xb5, 0xb2, 0x95, 0x58, 0x79, 0x63, 0x3a, 0x19, 0x4e,
8047
-	0xd1, 0x6a, 0x7f, 0xbf, 0xff, 0x9b, 0xfe, 0x6f, 0x31, 0xdc, 0xeb, 0x79, 0xe2, 0xed, 0xf0, 0xb0,
8048
-	0xe5, 0xb0, 0xc1, 0x86, 0xcb, 0x9c, 0x3e, 0x8d, 0x36, 0xf8, 0x3b, 0x12, 0x0d, 0xfa, 0x9e, 0xd8,
8049
-	0x20, 0xa1, 0xb7, 0xc1, 0x0e, 0x7f, 0x4f, 0x1d, 0xc1, 0x5b, 0x61, 0xc4, 0x04, 0x43, 0x28, 0x86,
8050
-	0xb4, 0x12, 0x48, 0x6b, 0xf4, 0xc3, 0xda, 0xd7, 0x57, 0x48, 0x10, 0xe3, 0x90, 0x6a, 0xfe, 0x95,
8051
-	0x58, 0x1e, 0x52, 0x27, 0xc1, 0x36, 0x7a, 0x8c, 0xf5, 0x7c, 0xba, 0xa1, 0x4e, 0x87, 0xc3, 0xa3,
8052
-	0x0d, 0xe1, 0x0d, 0x28, 0x17, 0x64, 0x10, 0x6a, 0xc0, 0x4a, 0x8f, 0xf5, 0x98, 0x7a, 0xdc, 0x90,
8053
-	0x4f, 0xfa, 0xed, 0xdd, 0xf3, 0x34, 0x12, 0x8c, 0xf5, 0xd5, 0x4f, 0x2f, 0xd1, 0x3e, 0x85, 0x87,
8054
-	0xfe, 0xb0, 0xe7, 0x05, 0xfa, 0x4f, 0x4c, 0x6c, 0xfe, 0xd9, 0x00, 0xf3, 0x05, 0x15, 0x04, 0xfd,
8055
-	0x0c, 0x8a, 0x23, 0x1a, 0x71, 0x8f, 0x05, 0x96, 0xb1, 0x6e, 0x7c, 0x55, 0xd9, 0xfc, 0x4e, 0x6b,
8056
-	0x3e, 0x22, 0xad, 0xd7, 0x31, 0xa4, 0x63, 0x7e, 0x3c, 0x6d, 0xdc, 0xc1, 0x09, 0x03, 0x3d, 0x04,
8057
-	0x70, 0x22, 0x4a, 0x04, 0x75, 0x6d, 0x22, 0xac, 0x9c, 0xe2, 0xd7, 0x5a, 0xb1, 0xb9, 0xad, 0x44,
8058
-	0x7f, 0xeb, 0x55, 0xe2, 0x25, 0x2e, 0x6b, 0x74, 0x5b, 0x48, 0xea, 0x30, 0x74, 0x13, 0x6a, 0xfe,
8059
-	0x6a, 0xaa, 0x46, 0xb7, 0x45, 0xf3, 0xfd, 0x02, 0x98, 0xbf, 0x66, 0x2e, 0x45, 0xab, 0x90, 0xf3,
8060
-	0x5c, 0x65, 0x76, 0xb9, 0x53, 0x98, 0x9c, 0x36, 0x72, 0xdd, 0x5d, 0x9c, 0xf3, 0x5c, 0xb4, 0x09,
8061
-	0xe6, 0x80, 0x0a, 0xa2, 0x0d, 0xb2, 0xb2, 0x1c, 0x92, 0xbe, 0x6b, 0x6f, 0x14, 0x16, 0xfd, 0x04,
8062
-	0x4c, 0xf9, 0xa9, 0xb4, 0x25, 0x6b, 0x59, 0x1c, 0xa9, 0xf3, 0x20, 0xa4, 0x4e, 0xc2, 0x93, 0x78,
8063
-	0xb4, 0x07, 0x15, 0x97, 0x72, 0x27, 0xf2, 0x42, 0x21, 0x63, 0x68, 0x2a, 0xfa, 0x97, 0x17, 0xd1,
8064
-	0x77, 0x67, 0x50, 0x9c, 0xe6, 0xa1, 0x9f, 0x43, 0x81, 0x0b, 0x22, 0x86, 0xdc, 0x5a, 0x50, 0x12,
8065
-	0xea, 0x17, 0x1a, 0xa0, 0x50, 0xda, 0x04, 0xcd, 0x41, 0xcf, 0xa0, 0x3a, 0x20, 0x01, 0xe9, 0xd1,
8066
-	0xc8, 0xd6, 0x52, 0x0a, 0x4a, 0xca, 0xf7, 0x32, 0x5d, 0x8f, 0x91, 0xb1, 0x20, 0xbc, 0x34, 0x48,
8067
-	0x1f, 0x51, 0x17, 0x80, 0x08, 0x41, 0x9c, 0xb7, 0x03, 0x1a, 0x08, 0xab, 0xa8, 0xa4, 0x7c, 0x3f,
8068
-	0xd3, 0x16, 0x2a, 0xde, 0xb1, 0xa8, 0xdf, 0x9e, 0x82, 0x3b, 0x39, 0xcb, 0xc0, 0x29, 0x32, 0x7a,
8069
-	0x0a, 0x15, 0x87, 0x46, 0xc2, 0x3b, 0xf2, 0x1c, 0x22, 0xa8, 0x55, 0x52, 0xb2, 0x1a, 0x59, 0xb2,
8070
-	0x76, 0x66, 0x30, 0xed, 0x58, 0x9a, 0x89, 0xee, 0x83, 0x19, 0x31, 0x9f, 0x5a, 0xe5, 0x75, 0xe3,
8071
-	0xab, 0xea, 0xc5, 0x9f, 0x06, 0x33, 0x9f, 0x62, 0x85, 0x94, 0xaa, 0x67, 0x86, 0x70, 0x0b, 0xd6,
8072
-	0xf3, 0xd7, 0x76, 0x03, 0xa7, 0x99, 0xdb, 0xab, 0xc7, 0x27, 0x4d, 0x04, 0xcb, 0x25, 0x63, 0xd9,
8073
-	0x50, 0x79, 0x66, 0xdc, 0x37, 0x7e, 0x6b, 0xfc, 0xce, 0x68, 0xfe, 0x27, 0x0f, 0xc5, 0x03, 0x1a,
8074
-	0x8d, 0x3c, 0xe7, 0xf3, 0x66, 0xe1, 0xc3, 0x33, 0x59, 0x98, 0x19, 0x2c, 0xad, 0x76, 0x2e, 0x11,
8075
-	0xb7, 0xa0, 0x44, 0x03, 0x37, 0x64, 0x5e, 0x20, 0x74, 0x16, 0x66, 0x46, 0x6a, 0x4f, 0x63, 0xf0,
8076
-	0x14, 0x8d, 0xf6, 0x60, 0x29, 0x2e, 0x2e, 0xfb, 0x4c, 0x0a, 0xae, 0x67, 0xd1, 0x7f, 0xa3, 0x80,
8077
-	0x3a, 0x77, 0x16, 0x87, 0xa9, 0x13, 0xda, 0x85, 0xa5, 0x30, 0xa2, 0x23, 0x8f, 0x0d, 0xb9, 0xad,
8078
-	0x9c, 0x28, 0x5c, 0xcb, 0x09, 0xbc, 0x98, 0xb0, 0xe4, 0x09, 0xfd, 0x02, 0x16, 0x25, 0xd9, 0x4e,
8079
-	0x9a, 0x12, 0x5c, 0xd9, 0x94, 0x70, 0x45, 0x12, 0xf4, 0x01, 0xbd, 0x84, 0x6f, 0x9d, 0xb1, 0x62,
8080
-	0x2a, 0xa8, 0x72, 0xb5, 0xa0, 0x2f, 0xd2, 0x96, 0xe8, 0x97, 0xdb, 0xe8, 0xf8, 0xa4, 0x59, 0x85,
8081
-	0xc5, 0x74, 0x0a, 0x34, 0xff, 0x94, 0x83, 0x52, 0x12, 0x48, 0xf4, 0x40, 0x7f, 0x33, 0xe3, 0xe2,
8082
-	0xa8, 0x25, 0x58, 0xe5, 0x6f, 0xfc, 0xb9, 0x1e, 0xc0, 0x42, 0xc8, 0x22, 0xc1, 0xad, 0x9c, 0x4a,
8083
-	0xce, 0xcc, 0x7a, 0xdf, 0x67, 0x91, 0xd8, 0x61, 0xc1, 0x91, 0xd7, 0xc3, 0x31, 0x18, 0xbd, 0x81,
8084
-	0xca, 0xc8, 0x8b, 0xc4, 0x90, 0xf8, 0xb6, 0x17, 0x72, 0x2b, 0xaf, 0xb8, 0x3f, 0xb8, 0x4c, 0x65,
8085
-	0xeb, 0x75, 0x8c, 0xef, 0xee, 0x77, 0xaa, 0x93, 0xd3, 0x06, 0x4c, 0x8f, 0x1c, 0x83, 0x16, 0xd5,
8086
-	0x0d, 0x79, 0xed, 0x05, 0x94, 0xa7, 0x37, 0xe8, 0x1e, 0x40, 0x10, 0xd7, 0x85, 0x3d, 0xcd, 0xec,
8087
-	0xa5, 0xc9, 0x69, 0xa3, 0xac, 0xab, 0xa5, 0xbb, 0x8b, 0xcb, 0x1a, 0xd0, 0x75, 0x11, 0x02, 0x93,
8088
-	0xb8, 0x6e, 0xa4, 0xf2, 0xbc, 0x8c, 0xd5, 0x73, 0xf3, 0x8f, 0x45, 0x30, 0x5f, 0x11, 0xde, 0xbf,
8089
-	0xed, 0x16, 0x2d, 0x75, 0xce, 0x55, 0xc6, 0x3d, 0x00, 0x1e, 0xe7, 0x9b, 0x74, 0xc7, 0x9c, 0xb9,
8090
-	0xa3, 0xb3, 0x50, 0xba, 0xa3, 0x01, 0xb1, 0x3b, 0xdc, 0x67, 0x42, 0x15, 0x81, 0x89, 0xd5, 0x33,
8091
-	0xfa, 0x12, 0x8a, 0x01, 0x73, 0x15, 0xbd, 0xa0, 0xe8, 0x30, 0x39, 0x6d, 0x14, 0x64, 0xd3, 0xe9,
8092
-	0xee, 0xe2, 0x82, 0xbc, 0xea, 0xba, 0xaa, 0xe9, 0x04, 0x01, 0x13, 0x44, 0x36, 0x74, 0xae, 0x7b,
8093
-	0x67, 0x66, 0xf6, 0xb7, 0x67, 0xb0, 0xa4, 0xdf, 0xa5, 0x98, 0xe8, 0x35, 0x7c, 0x91, 0xd8, 0x9b,
8094
-	0x16, 0x58, 0xba, 0x89, 0x40, 0xa4, 0x25, 0xa4, 0x6e, 0x52, 0x33, 0xa6, 0x7c, 0xf1, 0x8c, 0x51,
8095
-	0x11, 0xcc, 0x9a, 0x31, 0x1d, 0x58, 0x72, 0x29, 0xf7, 0x22, 0xea, 0xaa, 0x36, 0x41, 0x55, 0x65,
8096
-	0x56, 0x37, 0xbf, 0x7b, 0x99, 0x10, 0x8a, 0x17, 0x35, 0x47, 0x9d, 0x50, 0x1b, 0x4a, 0x3a, 0x6f,
8097
-	0xb8, 0x55, 0xb9, 0x49, 0x53, 0x9e, 0xd2, 0xce, 0xb4, 0xb9, 0xc5, 0x1b, 0xb5, 0xb9, 0x87, 0x00,
8098
-	0x3e, 0xeb, 0xd9, 0x6e, 0xe4, 0x8d, 0x68, 0x64, 0x2d, 0xe9, 0x8d, 0x23, 0x83, 0xbb, 0xab, 0x10,
8099
-	0xb8, 0xec, 0xb3, 0x5e, 0xfc, 0x38, 0xd7, 0x94, 0xaa, 0x37, 0x6c, 0x4a, 0x04, 0x6a, 0x84, 0x73,
8100
-	0xaf, 0x17, 0x50, 0xd7, 0xee, 0xd1, 0x80, 0x46, 0x9e, 0x63, 0x47, 0x94, 0xb3, 0x61, 0xe4, 0x50,
8101
-	0x6e, 0x7d, 0x43, 0x45, 0x22, 0x73, 0x67, 0x78, 0x1a, 0x83, 0xb1, 0xc6, 0x62, 0x2b, 0x11, 0x73,
8102
-	0xee, 0x82, 0x6f, 0xd7, 0x8e, 0x4f, 0x9a, 0xab, 0xb0, 0x92, 0x6e, 0x53, 0x5b, 0xc6, 0x13, 0xe3,
8103
-	0x99, 0xb1, 0x6f, 0x34, 0xff, 0x9a, 0x83, 0x6f, 0xce, 0xc5, 0x14, 0xfd, 0x18, 0x8a, 0x3a, 0xaa,
8104
-	0x97, 0x6d, 0x7e, 0x9a, 0x87, 0x13, 0x2c, 0x5a, 0x83, 0xb2, 0x2c, 0x71, 0xca, 0x39, 0x8d, 0x9b,
8105
-	0x57, 0x19, 0xcf, 0x5e, 0x20, 0x0b, 0x8a, 0xc4, 0xf7, 0x88, 0xbc, 0xcb, 0xab, 0xbb, 0xe4, 0x88,
8106
-	0x86, 0xb0, 0x1a, 0x87, 0xde, 0x9e, 0x0d, 0x58, 0x9b, 0x85, 0x82, 0x5b, 0xa6, 0xf2, 0xff, 0xf1,
8107
-	0xb5, 0x32, 0x41, 0x7f, 0x9c, 0xd9, 0x8b, 0x97, 0xa1, 0xe0, 0x7b, 0x81, 0x88, 0xc6, 0x78, 0xc5,
8108
-	0xcd, 0xb8, 0xaa, 0x3d, 0x85, 0xbb, 0x17, 0x52, 0xd0, 0x32, 0xe4, 0xfb, 0x74, 0x1c, 0xb7, 0x27,
8109
-	0x2c, 0x1f, 0xd1, 0x0a, 0x2c, 0x8c, 0x88, 0x3f, 0xa4, 0xba, 0x9b, 0xc5, 0x87, 0xed, 0xdc, 0x96,
8110
-	0xd1, 0xfc, 0x90, 0x83, 0xa2, 0x36, 0xe7, 0xb6, 0x47, 0xbe, 0x56, 0x3b, 0xd7, 0xd8, 0x1e, 0xc1,
8111
-	0xa2, 0x0e, 0x69, 0x5c, 0x91, 0xe6, 0x95, 0x39, 0x5d, 0x89, 0xf1, 0x71, 0x35, 0x3e, 0x02, 0xd3,
8112
-	0x0b, 0xc9, 0x40, 0x8f, 0xfb, 0x4c, 0xcd, 0xdd, 0xfd, 0xf6, 0x8b, 0x97, 0x61, 0xdc, 0x58, 0x4a,
8113
-	0x93, 0xd3, 0x86, 0x29, 0x5f, 0x60, 0x45, 0xcb, 0x1c, 0x8c, 0x7f, 0x5f, 0x80, 0xe2, 0x8e, 0x3f,
8114
-	0xe4, 0x82, 0x46, 0xb7, 0x1d, 0x24, 0xad, 0x76, 0x2e, 0x48, 0x3b, 0x50, 0x8c, 0x18, 0x13, 0xb6,
8115
-	0x43, 0x2e, 0x8b, 0x0f, 0x66, 0x4c, 0xec, 0xb4, 0x3b, 0x55, 0x49, 0x94, 0xbd, 0x3d, 0x3e, 0xe3,
8116
-	0x82, 0xa4, 0xee, 0x10, 0xf4, 0x06, 0x56, 0x93, 0x89, 0x78, 0xc8, 0x98, 0xe0, 0x22, 0x22, 0xa1,
8117
-	0xdd, 0xa7, 0x63, 0xb9, 0x2b, 0xe5, 0x2f, 0x5a, 0xb4, 0xf7, 0x02, 0x27, 0x1a, 0xab, 0xe0, 0x3d,
8118
-	0xa7, 0x63, 0xbc, 0xa2, 0x05, 0x74, 0x12, 0xfe, 0x73, 0x3a, 0xe6, 0xe8, 0x31, 0xac, 0xd1, 0x29,
8119
-	0x4c, 0x4a, 0xb4, 0x7d, 0x32, 0x90, 0xb3, 0xde, 0x76, 0x7c, 0xe6, 0xf4, 0xd5, 0xb8, 0x31, 0xf1,
8120
-	0x5d, 0x9a, 0x16, 0xf5, 0xab, 0x18, 0xb1, 0x23, 0x01, 0x88, 0x83, 0x75, 0xe8, 0x13, 0xa7, 0xef,
8121
-	0x7b, 0x5c, 0xfe, 0x2f, 0x95, 0xda, 0x9b, 0xe5, 0xc4, 0x90, 0xb6, 0x6d, 0x5d, 0x12, 0xad, 0x56,
8122
-	0x67, 0xc6, 0x4d, 0x6d, 0xe1, 0xba, 0xa2, 0xbe, 0x7d, 0x98, 0x7d, 0x8b, 0x3a, 0x50, 0x19, 0x06,
8123
-	0x52, 0x7d, 0x1c, 0x83, 0xf2, 0x75, 0x63, 0x00, 0x31, 0x4b, 0x79, 0xbe, 0x06, 0xe6, 0x91, 0xdc,
8124
-	0x61, 0xe4, 0x18, 0x29, 0xc5, 0xc9, 0xf5, 0xcb, 0xee, 0xfe, 0x01, 0x56, 0x6f, 0x6b, 0x23, 0x58,
8125
-	0xbb, 0xcc, 0xb4, 0x8c, 0xca, 0x7d, 0x92, 0xae, 0xdc, 0xca, 0xe6, 0xd7, 0x59, 0xd6, 0x64, 0x8b,
8126
-	0x4c, 0x55, 0x79, 0x66, 0x52, 0xff, 0xc5, 0x80, 0xc2, 0x01, 0x75, 0x22, 0x2a, 0x3e, 0x6b, 0x4e,
8127
-	0x6f, 0x9d, 0xc9, 0xe9, 0x7a, 0xf6, 0x9a, 0x2c, 0xb5, 0xce, 0xa5, 0x74, 0x0d, 0x4a, 0x5e, 0x20,
8128
-	0x68, 0x14, 0x10, 0x5f, 0xe5, 0x74, 0x09, 0x4f, 0xcf, 0x99, 0x0e, 0x7c, 0x30, 0xa0, 0x10, 0xef,
8129
-	0x91, 0xb7, 0xed, 0x40, 0xac, 0xf5, 0xbc, 0x03, 0x99, 0x46, 0xfe, 0xdb, 0x80, 0x52, 0x32, 0xce,
8130
-	0x3e, 0xab, 0x99, 0xe7, 0xf6, 0xb2, 0xfc, 0xff, 0xbc, 0x97, 0x21, 0x30, 0xfb, 0x5e, 0xa0, 0x37,
8131
-	0x48, 0xac, 0x9e, 0x51, 0x0b, 0x8a, 0x21, 0x19, 0xfb, 0x8c, 0xb8, 0xba, 0x8d, 0xae, 0xcc, 0xfd,
8132
-	0x86, 0xd1, 0x0e, 0xc6, 0x38, 0x01, 0x6d, 0xaf, 0x1c, 0x9f, 0x34, 0x97, 0xa1, 0x9a, 0xf6, 0xfc,
8133
-	0xad, 0xd1, 0xfc, 0x87, 0x01, 0xe5, 0xbd, 0x3f, 0x08, 0x1a, 0xa8, 0x6d, 0xe1, 0xff, 0xd2, 0xf9,
8134
-	0xf5, 0xf9, 0xdf, 0x39, 0xca, 0x67, 0x7e, 0xc2, 0xc8, 0xfa, 0xa8, 0x1d, 0xeb, 0xe3, 0xa7, 0xfa,
8135
-	0x9d, 0x7f, 0x7e, 0xaa, 0xdf, 0x79, 0x3f, 0xa9, 0x1b, 0x1f, 0x27, 0x75, 0xe3, 0x6f, 0x93, 0xba,
8136
-	0xf1, 0xaf, 0x49, 0xdd, 0x38, 0x2c, 0xa8, 0xf8, 0xfc, 0xe8, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff,
8137
-	0x07, 0xc5, 0x5a, 0x5b, 0xae, 0x13, 0x00, 0x00,
8040
+	// 1581 bytes of a gzipped FileDescriptorProto
8041
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4b, 0x73, 0x1b, 0x4b,
8042
+	0x15, 0xce, 0x48, 0x63, 0x3d, 0x8e, 0x6c, 0x61, 0xfa, 0x1a, 0x33, 0x11, 0x46, 0x32, 0xba, 0x05,
8043
+	0x75, 0xeb, 0x56, 0x4a, 0xbe, 0x98, 0x0b, 0x38, 0x86, 0xcb, 0x8d, 0x64, 0x9b, 0x44, 0x15, 0x42,
8044
+	0x5c, 0xed, 0x90, 0xb0, 0x1b, 0x5a, 0x33, 0x6d, 0x65, 0xd0, 0x68, 0x7a, 0x6a, 0xba, 0xa5, 0x20,
8045
+	0x56, 0x59, 0x9b, 0x1f, 0xe0, 0x1d, 0x8b, 0xfc, 0x0b, 0x36, 0x2c, 0x58, 0x65, 0xc9, 0x8a, 0x62,
8046
+	0xe5, 0x22, 0xfa, 0x17, 0x54, 0xb1, 0xa0, 0xba, 0xa7, 0x47, 0x1a, 0x5b, 0xe3, 0x17, 0x95, 0x72,
8047
+	0xb1, 0x72, 0x3f, 0xbe, 0xef, 0xf4, 0x39, 0x67, 0xce, 0xcb, 0x82, 0x07, 0x7d, 0x4f, 0xbc, 0x1e,
8048
+	0xf5, 0x5a, 0x0e, 0x1b, 0x6e, 0xb9, 0xcc, 0x19, 0xd0, 0x68, 0x8b, 0xbf, 0x21, 0xd1, 0x70, 0xe0,
8049
+	0x89, 0x2d, 0x12, 0x7a, 0x5b, 0xac, 0xf7, 0x7b, 0xea, 0x08, 0xde, 0x0a, 0x23, 0x26, 0x18, 0x42,
8050
+	0x31, 0xa4, 0x95, 0x40, 0x5a, 0xe3, 0x1f, 0xd6, 0x3e, 0xbf, 0x46, 0x82, 0x98, 0x84, 0x54, 0xf3,
8051
+	0xaf, 0xc5, 0xf2, 0x90, 0x3a, 0x09, 0xb6, 0xd1, 0x67, 0xac, 0xef, 0xd3, 0x2d, 0xb5, 0xeb, 0x8d,
8052
+	0x8e, 0xb7, 0x84, 0x37, 0xa4, 0x5c, 0x90, 0x61, 0xa8, 0x01, 0x6b, 0x7d, 0xd6, 0x67, 0x6a, 0xb9,
8053
+	0x25, 0x57, 0xfa, 0xf4, 0xfe, 0x45, 0x1a, 0x09, 0x26, 0xfa, 0xea, 0xa7, 0x57, 0xbc, 0x3e, 0x83,
8054
+	0x87, 0xfe, 0xa8, 0xef, 0x05, 0xfa, 0x4f, 0x4c, 0x6c, 0xfe, 0xc5, 0x00, 0xf3, 0x19, 0x15, 0x04,
8055
+	0xfd, 0x0c, 0x8a, 0x63, 0x1a, 0x71, 0x8f, 0x05, 0x96, 0xb1, 0x69, 0x7c, 0x56, 0xd9, 0xfe, 0x4e,
8056
+	0x6b, 0xd1, 0x23, 0xad, 0x97, 0x31, 0xa4, 0x63, 0xbe, 0x3f, 0x6b, 0xdc, 0xc3, 0x09, 0x03, 0x3d,
8057
+	0x04, 0x70, 0x22, 0x4a, 0x04, 0x75, 0x6d, 0x22, 0xac, 0x9c, 0xe2, 0xd7, 0x5a, 0xb1, 0xba, 0xad,
8058
+	0xe4, 0xfd, 0xd6, 0x8b, 0xc4, 0x4a, 0x5c, 0xd6, 0xe8, 0xb6, 0x90, 0xd4, 0x51, 0xe8, 0x26, 0xd4,
8059
+	0xfc, 0xf5, 0x54, 0x8d, 0x6e, 0x8b, 0xe6, 0xdb, 0x25, 0x30, 0x7f, 0xcd, 0x5c, 0x8a, 0xd6, 0x21,
8060
+	0xe7, 0xb9, 0x4a, 0xed, 0x72, 0xa7, 0x30, 0x3d, 0x6b, 0xe4, 0xba, 0xfb, 0x38, 0xe7, 0xb9, 0x68,
8061
+	0x1b, 0xcc, 0x21, 0x15, 0x44, 0x2b, 0x64, 0x65, 0x19, 0x24, 0x6d, 0xd7, 0xd6, 0x28, 0x2c, 0xfa,
8062
+	0x09, 0x98, 0xf2, 0x53, 0x69, 0x4d, 0x36, 0xb2, 0x38, 0xf2, 0xcd, 0xa3, 0x90, 0x3a, 0x09, 0x4f,
8063
+	0xe2, 0xd1, 0x01, 0x54, 0x5c, 0xca, 0x9d, 0xc8, 0x0b, 0x85, 0xf4, 0xa1, 0xa9, 0xe8, 0x9f, 0x5e,
8064
+	0x46, 0xdf, 0x9f, 0x43, 0x71, 0x9a, 0x87, 0x7e, 0x0e, 0x05, 0x2e, 0x88, 0x18, 0x71, 0x6b, 0x49,
8065
+	0x49, 0xa8, 0x5f, 0xaa, 0x80, 0x42, 0x69, 0x15, 0x34, 0x07, 0x3d, 0x81, 0xea, 0x90, 0x04, 0xa4,
8066
+	0x4f, 0x23, 0x5b, 0x4b, 0x29, 0x28, 0x29, 0xdf, 0xcb, 0x34, 0x3d, 0x46, 0xc6, 0x82, 0xf0, 0xca,
8067
+	0x30, 0xbd, 0x45, 0x5d, 0x00, 0x22, 0x04, 0x71, 0x5e, 0x0f, 0x69, 0x20, 0xac, 0xa2, 0x92, 0xf2,
8068
+	0xfd, 0x4c, 0x5d, 0xa8, 0x78, 0xc3, 0xa2, 0x41, 0x7b, 0x06, 0xee, 0xe4, 0x2c, 0x03, 0xa7, 0xc8,
8069
+	0xe8, 0x31, 0x54, 0x1c, 0x1a, 0x09, 0xef, 0xd8, 0x73, 0x88, 0xa0, 0x56, 0x49, 0xc9, 0x6a, 0x64,
8070
+	0xc9, 0xda, 0x9b, 0xc3, 0xb4, 0x61, 0x69, 0x26, 0xfa, 0x02, 0xcc, 0x88, 0xf9, 0xd4, 0x2a, 0x6f,
8071
+	0x1a, 0x9f, 0x55, 0x2f, 0xff, 0x34, 0x98, 0xf9, 0x14, 0x2b, 0xa4, 0x7c, 0x7a, 0xae, 0x08, 0xb7,
8072
+	0x60, 0x33, 0x7f, 0x63, 0x33, 0x70, 0x9a, 0xb9, 0xbb, 0x7e, 0x72, 0xda, 0x44, 0xb0, 0x5a, 0x32,
8073
+	0x56, 0x0d, 0x15, 0x67, 0xc6, 0x17, 0xc6, 0x6f, 0x8d, 0xdf, 0x19, 0xcd, 0xff, 0xe4, 0xa1, 0x78,
8074
+	0x44, 0xa3, 0xb1, 0xe7, 0x7c, 0xdc, 0x28, 0x7c, 0x78, 0x2e, 0x0a, 0x33, 0x9d, 0xa5, 0x9f, 0x5d,
8075
+	0x08, 0xc4, 0x1d, 0x28, 0xd1, 0xc0, 0x0d, 0x99, 0x17, 0x08, 0x1d, 0x85, 0x99, 0x9e, 0x3a, 0xd0,
8076
+	0x18, 0x3c, 0x43, 0xa3, 0x03, 0x58, 0x89, 0x93, 0xcb, 0x3e, 0x17, 0x82, 0x9b, 0x59, 0xf4, 0xdf,
8077
+	0x28, 0xa0, 0x8e, 0x9d, 0xe5, 0x51, 0x6a, 0x87, 0xf6, 0x61, 0x25, 0x8c, 0xe8, 0xd8, 0x63, 0x23,
8078
+	0x6e, 0x2b, 0x23, 0x0a, 0x37, 0x32, 0x02, 0x2f, 0x27, 0x2c, 0xb9, 0x43, 0xbf, 0x80, 0x65, 0x49,
8079
+	0xb6, 0x93, 0xa2, 0x04, 0xd7, 0x16, 0x25, 0x5c, 0x91, 0x04, 0xbd, 0x41, 0xcf, 0xe1, 0x5b, 0xe7,
8080
+	0xb4, 0x98, 0x09, 0xaa, 0x5c, 0x2f, 0xe8, 0x93, 0xb4, 0x26, 0xfa, 0x70, 0x17, 0x9d, 0x9c, 0x36,
8081
+	0xab, 0xb0, 0x9c, 0x0e, 0x81, 0xe6, 0x9f, 0x73, 0x50, 0x4a, 0x1c, 0x89, 0xbe, 0xd4, 0xdf, 0xcc,
8082
+	0xb8, 0xdc, 0x6b, 0x09, 0x56, 0xd9, 0x1b, 0x7f, 0xae, 0x2f, 0x61, 0x29, 0x64, 0x91, 0xe0, 0x56,
8083
+	0x4e, 0x05, 0x67, 0x66, 0xbe, 0x1f, 0xb2, 0x48, 0xec, 0xb1, 0xe0, 0xd8, 0xeb, 0xe3, 0x18, 0x8c,
8084
+	0x5e, 0x41, 0x65, 0xec, 0x45, 0x62, 0x44, 0x7c, 0xdb, 0x0b, 0xb9, 0x95, 0x57, 0xdc, 0x1f, 0x5c,
8085
+	0xf5, 0x64, 0xeb, 0x65, 0x8c, 0xef, 0x1e, 0x76, 0xaa, 0xd3, 0xb3, 0x06, 0xcc, 0xb6, 0x1c, 0x83,
8086
+	0x16, 0xd5, 0x0d, 0x79, 0xed, 0x19, 0x94, 0x67, 0x37, 0xe8, 0x01, 0x40, 0x10, 0xe7, 0x85, 0x3d,
8087
+	0x8b, 0xec, 0x95, 0xe9, 0x59, 0xa3, 0xac, 0xb3, 0xa5, 0xbb, 0x8f, 0xcb, 0x1a, 0xd0, 0x75, 0x11,
8088
+	0x02, 0x93, 0xb8, 0x6e, 0xa4, 0xe2, 0xbc, 0x8c, 0xd5, 0xba, 0xf9, 0xa7, 0x22, 0x98, 0x2f, 0x08,
8089
+	0x1f, 0xdc, 0x75, 0x89, 0x96, 0x6f, 0x2e, 0x64, 0xc6, 0x03, 0x00, 0x1e, 0xc7, 0x9b, 0x34, 0xc7,
8090
+	0x9c, 0x9b, 0xa3, 0xa3, 0x50, 0x9a, 0xa3, 0x01, 0xb1, 0x39, 0xdc, 0x67, 0x42, 0x25, 0x81, 0x89,
8091
+	0xd5, 0x1a, 0x7d, 0x0a, 0xc5, 0x80, 0xb9, 0x8a, 0x5e, 0x50, 0x74, 0x98, 0x9e, 0x35, 0x0a, 0xb2,
8092
+	0xe8, 0x74, 0xf7, 0x71, 0x41, 0x5e, 0x75, 0x5d, 0x55, 0x74, 0x82, 0x80, 0x09, 0x22, 0x0b, 0x3a,
8093
+	0xd7, 0xb5, 0x33, 0x33, 0xfa, 0xdb, 0x73, 0x58, 0x52, 0xef, 0x52, 0x4c, 0xf4, 0x12, 0x3e, 0x49,
8094
+	0xf4, 0x4d, 0x0b, 0x2c, 0xdd, 0x46, 0x20, 0xd2, 0x12, 0x52, 0x37, 0xa9, 0x1e, 0x53, 0xbe, 0xbc,
8095
+	0xc7, 0x28, 0x0f, 0x66, 0xf5, 0x98, 0x0e, 0xac, 0xb8, 0x94, 0x7b, 0x11, 0x75, 0x55, 0x99, 0xa0,
8096
+	0x2a, 0x33, 0xab, 0xdb, 0xdf, 0xbd, 0x4a, 0x08, 0xc5, 0xcb, 0x9a, 0xa3, 0x76, 0xa8, 0x0d, 0x25,
8097
+	0x1d, 0x37, 0xdc, 0xaa, 0xdc, 0xa6, 0x28, 0xcf, 0x68, 0xe7, 0xca, 0xdc, 0xf2, 0xad, 0xca, 0xdc,
8098
+	0x43, 0x00, 0x9f, 0xf5, 0x6d, 0x37, 0xf2, 0xc6, 0x34, 0xb2, 0x56, 0xf4, 0xc4, 0x91, 0xc1, 0xdd,
8099
+	0x57, 0x08, 0x5c, 0xf6, 0x59, 0x3f, 0x5e, 0x2e, 0x14, 0xa5, 0xea, 0x2d, 0x8b, 0x12, 0x81, 0x1a,
8100
+	0xe1, 0xdc, 0xeb, 0x07, 0xd4, 0xb5, 0xfb, 0x34, 0xa0, 0x91, 0xe7, 0xd8, 0x11, 0xe5, 0x6c, 0x14,
8101
+	0x39, 0x94, 0x5b, 0xdf, 0x50, 0x9e, 0xc8, 0x9c, 0x19, 0x1e, 0xc7, 0x60, 0xac, 0xb1, 0xd8, 0x4a,
8102
+	0xc4, 0x5c, 0xb8, 0xe0, 0xbb, 0xb5, 0x93, 0xd3, 0xe6, 0x3a, 0xac, 0xa5, 0xcb, 0xd4, 0x8e, 0xf1,
8103
+	0xc8, 0x78, 0x62, 0x1c, 0x1a, 0xcd, 0xbf, 0xe5, 0xe0, 0x9b, 0x0b, 0x3e, 0x45, 0x3f, 0x86, 0xa2,
8104
+	0xf6, 0xea, 0x55, 0x93, 0x9f, 0xe6, 0xe1, 0x04, 0x8b, 0x36, 0xa0, 0x2c, 0x53, 0x9c, 0x72, 0x4e,
8105
+	0xe3, 0xe2, 0x55, 0xc6, 0xf3, 0x03, 0x64, 0x41, 0x91, 0xf8, 0x1e, 0x91, 0x77, 0x79, 0x75, 0x97,
8106
+	0x6c, 0xd1, 0x08, 0xd6, 0x63, 0xd7, 0xdb, 0xf3, 0x06, 0x6b, 0xb3, 0x50, 0x70, 0xcb, 0x54, 0xf6,
8107
+	0x7f, 0x7d, 0xa3, 0x48, 0xd0, 0x1f, 0x67, 0x7e, 0xf0, 0x3c, 0x14, 0xfc, 0x20, 0x10, 0xd1, 0x04,
8108
+	0xaf, 0xb9, 0x19, 0x57, 0xb5, 0xc7, 0x70, 0xff, 0x52, 0x0a, 0x5a, 0x85, 0xfc, 0x80, 0x4e, 0xe2,
8109
+	0xf2, 0x84, 0xe5, 0x12, 0xad, 0xc1, 0xd2, 0x98, 0xf8, 0x23, 0xaa, 0xab, 0x59, 0xbc, 0xd9, 0xcd,
8110
+	0xed, 0x18, 0xcd, 0x77, 0x39, 0x28, 0x6a, 0x75, 0xee, 0xba, 0xe5, 0xeb, 0x67, 0x17, 0x0a, 0xdb,
8111
+	0x57, 0xb0, 0xac, 0x5d, 0x1a, 0x67, 0xa4, 0x79, 0x6d, 0x4c, 0x57, 0x62, 0x7c, 0x9c, 0x8d, 0x5f,
8112
+	0x81, 0xe9, 0x85, 0x64, 0xa8, 0xdb, 0x7d, 0xe6, 0xcb, 0xdd, 0xc3, 0xf6, 0xb3, 0xe7, 0x61, 0x5c,
8113
+	0x58, 0x4a, 0xd3, 0xb3, 0x86, 0x29, 0x0f, 0xb0, 0xa2, 0x65, 0x36, 0xc6, 0x77, 0x05, 0x28, 0xee,
8114
+	0xf9, 0x23, 0x2e, 0x68, 0x74, 0xd7, 0x4e, 0xd2, 0xcf, 0x2e, 0x38, 0x69, 0x0f, 0x8a, 0x11, 0x63,
8115
+	0xc2, 0x76, 0xc8, 0x55, 0xfe, 0xc1, 0x8c, 0x89, 0xbd, 0x76, 0xa7, 0x2a, 0x89, 0xb2, 0xb6, 0xc7,
8116
+	0x7b, 0x5c, 0x90, 0xd4, 0x3d, 0x82, 0x5e, 0xc1, 0x7a, 0xd2, 0x11, 0x7b, 0x8c, 0x09, 0x2e, 0x22,
8117
+	0x12, 0xda, 0x03, 0x3a, 0x91, 0xb3, 0x52, 0xfe, 0xb2, 0x41, 0xfb, 0x20, 0x70, 0xa2, 0x89, 0x72,
8118
+	0xde, 0x53, 0x3a, 0xc1, 0x6b, 0x5a, 0x40, 0x27, 0xe1, 0x3f, 0xa5, 0x13, 0x8e, 0xbe, 0x86, 0x0d,
8119
+	0x3a, 0x83, 0x49, 0x89, 0xb6, 0x4f, 0x86, 0xb2, 0xd7, 0xdb, 0x8e, 0xcf, 0x9c, 0x81, 0x6a, 0x37,
8120
+	0x26, 0xbe, 0x4f, 0xd3, 0xa2, 0x7e, 0x15, 0x23, 0xf6, 0x24, 0x00, 0x71, 0xb0, 0x7a, 0x3e, 0x71,
8121
+	0x06, 0xbe, 0xc7, 0xe5, 0xff, 0x52, 0xa9, 0xb9, 0x59, 0x76, 0x0c, 0xa9, 0xdb, 0xce, 0x15, 0xde,
8122
+	0x6a, 0x75, 0xe6, 0xdc, 0xd4, 0x14, 0xae, 0x33, 0xea, 0xdb, 0xbd, 0xec, 0x5b, 0xd4, 0x81, 0xca,
8123
+	0x28, 0x90, 0xcf, 0xc7, 0x3e, 0x28, 0xdf, 0xd4, 0x07, 0x10, 0xb3, 0x94, 0xe5, 0x1b, 0x60, 0x1e,
8124
+	0xcb, 0x19, 0x46, 0xb6, 0x91, 0x52, 0x1c, 0x5c, 0xbf, 0xec, 0x1e, 0x1e, 0x61, 0x75, 0x8a, 0x5a,
8125
+	0x80, 0x5c, 0x7a, 0x4c, 0x46, 0xbe, 0x68, 0xc7, 0xb5, 0xe5, 0x90, 0x31, 0x5f, 0xf5, 0x8c, 0x32,
8126
+	0xce, 0xb8, 0x41, 0x75, 0x00, 0x3e, 0xea, 0x05, 0x54, 0x1c, 0x79, 0x7f, 0xa4, 0xaa, 0x31, 0xac,
8127
+	0xe0, 0xd4, 0x49, 0x6d, 0x0c, 0x1b, 0x57, 0x99, 0x9a, 0x51, 0x09, 0x1e, 0xa5, 0x2b, 0x41, 0x65,
8128
+	0xfb, 0xf3, 0x2c, 0xeb, 0xb2, 0x45, 0xa6, 0xaa, 0x46, 0x66, 0x92, 0xfc, 0xd5, 0x80, 0xc2, 0x11,
8129
+	0x75, 0x22, 0x2a, 0x3e, 0x6a, 0x8e, 0xec, 0x9c, 0xcb, 0x91, 0x7a, 0xf6, 0xd8, 0x2d, 0x5f, 0x5d,
8130
+	0x48, 0x91, 0x1a, 0x94, 0xbc, 0x40, 0xd0, 0x28, 0x20, 0xbe, 0xca, 0x91, 0x12, 0x9e, 0xed, 0xb3,
8131
+	0xb3, 0xdc, 0x80, 0x42, 0x3c, 0x97, 0xde, 0xb5, 0x01, 0xf1, 0xab, 0x17, 0x0d, 0xc8, 0x54, 0xf2,
8132
+	0xdf, 0x06, 0x94, 0x92, 0xf6, 0xf8, 0x51, 0xd5, 0xbc, 0x30, 0xe7, 0xe5, 0xff, 0xe7, 0x39, 0x0f,
8133
+	0x81, 0x39, 0xf0, 0x02, 0x3d, 0x91, 0x62, 0xb5, 0x46, 0x2d, 0x28, 0x86, 0x64, 0xe2, 0x33, 0xe2,
8134
+	0xea, 0xb2, 0xbc, 0xb6, 0xf0, 0x9b, 0x48, 0x3b, 0x98, 0xe0, 0x04, 0xb4, 0xbb, 0x76, 0x72, 0xda,
8135
+	0x5c, 0x85, 0x6a, 0xda, 0xf2, 0xd7, 0x46, 0xf3, 0x1f, 0x06, 0x94, 0x0f, 0xfe, 0x20, 0x68, 0xa0,
8136
+	0xa6, 0x8f, 0xff, 0x4b, 0xe3, 0x37, 0x17, 0x7f, 0x37, 0x29, 0x9f, 0xfb, 0x49, 0x24, 0xeb, 0xa3,
8137
+	0x76, 0xac, 0xf7, 0x1f, 0xea, 0xf7, 0xfe, 0xf9, 0xa1, 0x7e, 0xef, 0xed, 0xb4, 0x6e, 0xbc, 0x9f,
8138
+	0xd6, 0x8d, 0xbf, 0x4f, 0xeb, 0xc6, 0xbf, 0xa6, 0x75, 0xa3, 0x57, 0x50, 0xfe, 0xf9, 0xd1, 0x7f,
8139
+	0x03, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x6b, 0x9b, 0xd8, 0xfe, 0x13, 0x00, 0x00,
8138 8140
 }
... ...
@@ -342,6 +342,15 @@ message Cluster {
342 342
 	// reject joining the cluster.  Nodes that report themselves to be non-FIPS
343 343
 	// should be rejected from the cluster.
344 344
 	bool fips = 10 [(gogoproto.customname) = "FIPS"];
345
+
346
+	// This field specifies default subnet pools for global scope networks. If
347
+	// unspecified, Docker will use the predefined subnets as it works on older releases.
348
+	// Format Example : {"20.20.0.0/16",""20.20.0.0/16"}
349
+	repeated string defaultAddressPool = 11;
350
+
351
+	// This flag specifies the default subnet size of global scope networks by giving
352
+	// the length of the subnet masks for every such network
353
+	uint32 subnetSize = 12;
345 354
 }
346 355
 
347 356
 // Secret represents a secret that should be passed to a container or a node,
... ...
@@ -1,6 +1,7 @@
1 1
 package allocator
2 2
 
3 3
 import (
4
+	"net"
4 5
 	"sync"
5 6
 
6 7
 	"github.com/docker/docker/pkg/plugingetter"
... ...
@@ -32,6 +33,13 @@ type Allocator struct {
32 32
 
33 33
 	// pluginGetter provides access to docker's plugin inventory.
34 34
 	pluginGetter plugingetter.PluginGetter
35
+
36
+	// DefaultAddrPool specifies default subnet pool for global scope networks
37
+	defaultAddrPool []*net.IPNet
38
+
39
+	// SubnetSize specifies the subnet size of the networks created from
40
+	// the default subnet pool
41
+	subnetSize int
35 42
 }
36 43
 
37 44
 // taskBallot controls how the voting for task allocation is
... ...
@@ -65,15 +73,17 @@ type allocActor struct {
65 65
 
66 66
 // New returns a new instance of Allocator for use during allocation
67 67
 // stage of the manager.
68
-func New(store *store.MemoryStore, pg plugingetter.PluginGetter) (*Allocator, error) {
68
+func New(store *store.MemoryStore, pg plugingetter.PluginGetter, defaultAddrPool []*net.IPNet, subnetSize int) (*Allocator, error) {
69 69
 	a := &Allocator{
70 70
 		store: store,
71 71
 		taskBallot: &taskBallot{
72 72
 			votes: make(map[string][]string),
73 73
 		},
74
-		stopChan:     make(chan struct{}),
75
-		doneChan:     make(chan struct{}),
76
-		pluginGetter: pg,
74
+		stopChan:        make(chan struct{}),
75
+		doneChan:        make(chan struct{}),
76
+		pluginGetter:    pg,
77
+		defaultAddrPool: defaultAddrPool,
78
+		subnetSize:      subnetSize,
77 79
 	}
78 80
 
79 81
 	return a, nil
... ...
@@ -1,14 +1,45 @@
1 1
 package cnmallocator
2 2
 
3 3
 import (
4
+	"net"
5
+	"strconv"
6
+	"strings"
7
+
4 8
 	"github.com/docker/libnetwork/drvregistry"
5 9
 	"github.com/docker/libnetwork/ipamapi"
6 10
 	builtinIpam "github.com/docker/libnetwork/ipams/builtin"
7 11
 	nullIpam "github.com/docker/libnetwork/ipams/null"
8 12
 	remoteIpam "github.com/docker/libnetwork/ipams/remote"
13
+	"github.com/docker/libnetwork/ipamutils"
14
+	"github.com/sirupsen/logrus"
9 15
 )
10 16
 
11
-func initIPAMDrivers(r *drvregistry.DrvRegistry) error {
17
+func initIPAMDrivers(r *drvregistry.DrvRegistry, defaultAddrPool []*net.IPNet, subnetSize int) error {
18
+	var addressPool []*ipamutils.NetworkToSplit
19
+	var str strings.Builder
20
+	str.WriteString("Subnetlist - ")
21
+	// Extract defaultAddrPool param info and construct ipamutils.NetworkToSplit
22
+	// from the info. We will be using it to call Libnetwork API
23
+	// We also need to log new address pool info whenever swarm init
24
+	// happens with default address pool option
25
+	if defaultAddrPool != nil {
26
+		for _, p := range defaultAddrPool {
27
+			addressPool = append(addressPool, &ipamutils.NetworkToSplit{
28
+				Base: p.String(),
29
+				Size: subnetSize,
30
+			})
31
+			str.WriteString(p.String() + ",")
32
+		}
33
+		str.WriteString(": Size ")
34
+		str.WriteString(strconv.Itoa(subnetSize))
35
+	}
36
+	if err := ipamutils.ConfigGlobalScopeDefaultNetworks(addressPool); err != nil {
37
+		return err
38
+	}
39
+	if addressPool != nil {
40
+		logrus.Infof("Swarm initialized global default address pool to: " + str.String())
41
+	}
42
+
12 43
 	for _, fn := range [](func(ipamapi.Callback, interface{}, interface{}) error){
13 44
 		builtinIpam.Init,
14 45
 		remoteIpam.Init,
... ...
@@ -87,7 +87,7 @@ type initializer struct {
87 87
 }
88 88
 
89 89
 // New returns a new NetworkAllocator handle
90
-func New(pg plugingetter.PluginGetter) (networkallocator.NetworkAllocator, error) {
90
+func New(pg plugingetter.PluginGetter, defaultAddrPool []*net.IPNet, subnetSize int) (networkallocator.NetworkAllocator, error) {
91 91
 	na := &cnmNetworkAllocator{
92 92
 		networks: make(map[string]*network),
93 93
 		services: make(map[string]struct{}),
... ...
@@ -106,7 +106,7 @@ func New(pg plugingetter.PluginGetter) (networkallocator.NetworkAllocator, error
106 106
 		return nil, err
107 107
 	}
108 108
 
109
-	if err = initIPAMDrivers(reg); err != nil {
109
+	if err = initIPAMDrivers(reg, defaultAddrPool, subnetSize); err != nil {
110 110
 		return nil, err
111 111
 	}
112 112
 
... ...
@@ -68,7 +68,7 @@ type networkContext struct {
68 68
 }
69 69
 
70 70
 func (a *Allocator) doNetworkInit(ctx context.Context) (err error) {
71
-	na, err := cnmallocator.New(a.pluginGetter)
71
+	na, err := cnmallocator.New(a.pluginGetter, a.defaultAddrPool, a.subnetSize)
72 72
 	if err != nil {
73 73
 		return err
74 74
 	}
... ...
@@ -181,10 +181,6 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) {
181 181
 		if IsIngressNetwork(n) {
182 182
 			nc.ingressNetwork = n
183 183
 		}
184
-		err := a.allocateNodes(ctx, false)
185
-		if err != nil {
186
-			log.G(ctx).WithError(err).Error(err)
187
-		}
188 184
 	case api.EventDeleteNetwork:
189 185
 		n := v.Network.Copy()
190 186
 
... ...
@@ -337,19 +333,12 @@ func (a *Allocator) doNodeAlloc(ctx context.Context, ev events.Event) {
337 337
 			nc.somethingWasDeallocated = true
338 338
 		}
339 339
 	} else {
340
-		allocatedNetworks, err := a.getAllocatedNetworks()
341
-		if err != nil {
342
-			log.G(ctx).WithError(err).Errorf("Error listing allocated networks in network %s", node.ID)
343
-		}
344
-
345
-		isAllocated := a.allocateNode(ctx, node, false, allocatedNetworks)
346
-
347
-		if isAllocated {
348
-			if err := a.store.Batch(func(batch *store.Batch) error {
349
-				return a.commitAllocatedNode(ctx, batch, node)
350
-			}); err != nil {
351
-				log.G(ctx).WithError(err).Errorf("Failed to commit allocation of network resources for node %s", node.ID)
352
-			}
340
+		// if this isn't a delete, we should try reallocating the node. if this
341
+		// is a creation, then the node will be allocated only for ingress.
342
+		if err := a.reallocateNode(ctx, node.ID); err != nil {
343
+			log.G(ctx).WithError(err).Errorf(
344
+				"error reallocating network resources for node %v", node.ID,
345
+			)
353 346
 		}
354 347
 	}
355 348
 }
... ...
@@ -394,6 +383,69 @@ func (a *Allocator) getAllocatedNetworks() ([]*api.Network, error) {
394 394
 	return allocatedNetworks, nil
395 395
 }
396 396
 
397
+// getNodeNetworks returns all networks that should be allocated for a node
398
+func (a *Allocator) getNodeNetworks(nodeID string) ([]*api.Network, error) {
399
+	var (
400
+		// no need to initialize networks. we only append to it, and appending
401
+		// to a nil slice is valid. this has the added bonus of making this nil
402
+		// if we return an error
403
+		networks []*api.Network
404
+		err      error
405
+	)
406
+	a.store.View(func(tx store.ReadTx) {
407
+		// get all tasks currently assigned to this node. it's no big deal if
408
+		// the tasks change in the meantime, there's no race to clean up
409
+		// unneeded network attachments on a node.
410
+		var tasks []*api.Task
411
+		tasks, err = store.FindTasks(tx, store.ByNodeID(nodeID))
412
+		if err != nil {
413
+			return
414
+		}
415
+		// we need to keep track of network IDs that we've already added to the
416
+		// list of networks we're going to return. we could do
417
+		// map[string]*api.Network and then convert to []*api.Network and
418
+		// return that, but it seems cleaner to have a separate set and list.
419
+		networkIDs := map[string]struct{}{}
420
+		for _, task := range tasks {
421
+			// we don't need to check if a task is before the Assigned state.
422
+			// the only way we have a task with a NodeID that isn't yet in
423
+			// Assigned is if it's a global service task. this check is not
424
+			// necessary:
425
+			// if task.Status.State < api.TaskStateAssigned {
426
+			//     continue
427
+			// }
428
+			if task.Status.State > api.TaskStateRunning {
429
+				// we don't need to have network attachments for a task that's
430
+				// already in a terminal state
431
+				continue
432
+			}
433
+
434
+			// now go through the task's network attachments and find all of
435
+			// the networks
436
+			for _, attachment := range task.Networks {
437
+				// if the network is an overlay network, and the network ID is
438
+				// not yet in the set of network IDs, then add it to the set
439
+				// and add the network to the list of networks we'll be
440
+				// returning
441
+				if _, ok := networkIDs[attachment.Network.ID]; isOverlayNetwork(attachment.Network) && !ok {
442
+					networkIDs[attachment.Network.ID] = struct{}{}
443
+					// we don't need to worry about retrieving the network from
444
+					// the store, because the network in the attachment is an
445
+					// identical copy of the network in the store.
446
+					networks = append(networks, attachment.Network)
447
+				}
448
+			}
449
+		}
450
+	})
451
+
452
+	// finally, we need the ingress network if one exists.
453
+	if a.netCtx != nil && a.netCtx.ingressNetwork != nil {
454
+		networks = append(networks, a.netCtx.ingressNetwork)
455
+	}
456
+
457
+	return networks, err
458
+}
459
+
397 460
 func (a *Allocator) allocateNodes(ctx context.Context, existingAddressesOnly bool) error {
398 461
 	// Allocate nodes in the store so far before we process watched events.
399 462
 	var (
... ...
@@ -409,13 +461,12 @@ func (a *Allocator) allocateNodes(ctx context.Context, existingAddressesOnly boo
409 409
 		return errors.Wrap(err, "error listing all nodes in store while trying to allocate network resources")
410 410
 	}
411 411
 
412
-	allocatedNetworks, err := a.getAllocatedNetworks()
413
-	if err != nil {
414
-		return errors.Wrap(err, "error listing all nodes in store while trying to allocate network resources")
415
-	}
416
-
417 412
 	for _, node := range nodes {
418
-		isAllocated := a.allocateNode(ctx, node, existingAddressesOnly, allocatedNetworks)
413
+		networks, err := a.getNodeNetworks(node.ID)
414
+		if err != nil {
415
+			return errors.Wrap(err, "error getting all networks needed by node")
416
+		}
417
+		isAllocated := a.allocateNode(ctx, node, existingAddressesOnly, networks)
419 418
 		if isAllocated {
420 419
 			allocatedNodes = append(allocatedNodes, node)
421 420
 		}
... ...
@@ -842,6 +893,14 @@ func (a *Allocator) doTaskAlloc(ctx context.Context, ev events.Event) {
842 842
 			}
843 843
 		}
844 844
 
845
+		// if we're deallocating the task, we also might need to deallocate the
846
+		// node's network attachment, if this is the last task on the node that
847
+		// needs it. we can do that by doing the same dance to reallocate a
848
+		// node
849
+		if err := a.reallocateNode(ctx, t.NodeID); err != nil {
850
+			logger.WithError(err).Errorf("error reallocating node %v", t.NodeID)
851
+		}
852
+
845 853
 		// Cleanup any task references that might exist
846 854
 		delete(nc.pendingTasks, t.ID)
847 855
 		delete(nc.unallocatedTasks, t.ID)
... ...
@@ -849,6 +908,16 @@ func (a *Allocator) doTaskAlloc(ctx context.Context, ev events.Event) {
849 849
 		return
850 850
 	}
851 851
 
852
+	// if the task has a node ID, we should allocate an attachment for the node
853
+	// this happens if the task is in any non-terminal state.
854
+	if t.NodeID != "" && t.Status.State <= api.TaskStateRunning {
855
+		if err := a.reallocateNode(ctx, t.NodeID); err != nil {
856
+			// TODO(dperny): not entire sure what the error handling flow here
857
+			// should be... for now, just log and keep going
858
+			logger.WithError(err).Errorf("error reallocating node %v", t.NodeID)
859
+		}
860
+	}
861
+
852 862
 	// If we are already in allocated state, there is
853 863
 	// absolutely nothing else to do.
854 864
 	if t.Status.State >= api.TaskStatePending {
... ...
@@ -887,13 +956,25 @@ func (a *Allocator) doTaskAlloc(ctx context.Context, ev events.Event) {
887 887
 	log.G(ctx).Debugf("task %v was marked pending allocation", t.ID)
888 888
 }
889 889
 
890
+// allocateNode takes a context, a node, whether or not new allocations should
891
+// be made, and the networks to allocate. it then makes sure an attachment is
892
+// allocated for every network in the provided networks, allocating new
893
+// attachments if existingAddressesOnly is false. it return true if something
894
+// new was allocated or something was removed, or false otherwise.
895
+//
896
+// additionally, allocateNode will remove and free any attachments for networks
897
+// not in the set of networks passed in.
890 898
 func (a *Allocator) allocateNode(ctx context.Context, node *api.Node, existingAddressesOnly bool, networks []*api.Network) bool {
891 899
 	var allocated bool
892 900
 
893 901
 	nc := a.netCtx
894 902
 
903
+	// go through all of the networks we've passed in
895 904
 	for _, network := range networks {
896 905
 
906
+		// for each one, create space for an attachment. then, search through
907
+		// all of the attachments already on the node. if the attachment
908
+		// exists, then copy it to the node. if not, we'll allocate it below.
897 909
 		var lbAttachment *api.NetworkAttachment
898 910
 		for _, na := range node.Attachments {
899 911
 			if na.Network != nil && na.Network.ID == network.ID {
... ...
@@ -927,8 +1008,83 @@ func (a *Allocator) allocateNode(ctx context.Context, node *api.Node, existingAd
927 927
 
928 928
 		allocated = true
929 929
 	}
930
+
931
+	// if we're only initializing existing addresses, we should stop here and
932
+	// not deallocate anything
933
+	if existingAddressesOnly {
934
+		return allocated
935
+	}
936
+
937
+	// now that we've allocated everything new, we have to remove things that
938
+	// do not belong. we have to do this last because we can easily roll back
939
+	// attachments we've allocated if something goes wrong by freeing them, but
940
+	// we can't roll back deallocating attachments by reacquiring them.
941
+
942
+	// we're using a trick to filter without allocating see the official go
943
+	// wiki on github:
944
+	// https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating
945
+	attachments := node.Attachments[:0]
946
+	for _, attach := range node.Attachments {
947
+		// for every attachment, go through every network. if the attachment
948
+		// belongs to one of the networks, then go to the next attachment. if
949
+		// no network matches, then the the attachment should be removed.
950
+		attachmentBelongs := false
951
+		for _, network := range networks {
952
+			if network.ID == attach.Network.ID {
953
+				attachmentBelongs = true
954
+				break
955
+			}
956
+		}
957
+		if attachmentBelongs {
958
+			attachments = append(attachments, attach)
959
+		} else {
960
+			// free the attachment and remove it from the node's attachments by
961
+			// re-slicing
962
+			if err := a.netCtx.nwkAllocator.DeallocateAttachment(node, attach); err != nil {
963
+				// if deallocation fails, there's nothing we can do besides log
964
+				// an error and keep going
965
+				log.G(ctx).WithError(err).Errorf(
966
+					"error deallocating attachment for network %v on node %v",
967
+					attach.Network.ID, node.ID,
968
+				)
969
+			}
970
+			// strictly speaking, nothing was allocated, but something was
971
+			// deallocated and that counts.
972
+			allocated = true
973
+			// also, set the somethingWasDeallocated flag so the allocator
974
+			// knows that it can now try again.
975
+			a.netCtx.somethingWasDeallocated = true
976
+		}
977
+	}
978
+	node.Attachments = attachments
979
+
930 980
 	return allocated
981
+}
982
+
983
+func (a *Allocator) reallocateNode(ctx context.Context, nodeID string) error {
984
+	var (
985
+		node *api.Node
986
+	)
987
+	a.store.View(func(tx store.ReadTx) {
988
+		node = store.GetNode(tx, nodeID)
989
+	})
990
+	if node == nil {
991
+		return errors.Errorf("node %v cannot be found", nodeID)
992
+	}
931 993
 
994
+	networks, err := a.getNodeNetworks(node.ID)
995
+	if err != nil {
996
+		return errors.Wrapf(err, "error getting networks for node %v", nodeID)
997
+	}
998
+	if a.allocateNode(ctx, node, false, networks) {
999
+		// if something was allocated, commit the node
1000
+		if err := a.store.Batch(func(batch *store.Batch) error {
1001
+			return a.commitAllocatedNode(ctx, batch, node)
1002
+		}); err != nil {
1003
+			return errors.Wrapf(err, "error committing allocation for node %v", nodeID)
1004
+		}
1005
+	}
1006
+	return nil
932 1007
 }
933 1008
 
934 1009
 func (a *Allocator) commitAllocatedNode(ctx context.Context, batch *store.Batch, node *api.Node) error {
... ...
@@ -265,6 +265,8 @@ func redactClusters(clusters []*api.Cluster) []*api.Cluster {
265 265
 			Spec:                    *redactedSpec,
266 266
 			RootCA:                  *redactedRootCA,
267 267
 			BlacklistedCertificates: cluster.BlacklistedCertificates,
268
+			DefaultAddressPool:      cluster.DefaultAddressPool,
269
+			SubnetSize:              cluster.SubnetSize,
268 270
 		}
269 271
 		redactedClusters = append(redactedClusters, newCluster)
270 272
 	}
... ...
@@ -142,6 +142,12 @@ func (s *Server) ListNodes(ctx context.Context, request *api.ListNodesRequest) (
142 142
 				return filterMatchLabels(e.Description.Engine.Labels, request.Filters.Labels)
143 143
 			},
144 144
 			func(e *api.Node) bool {
145
+				if len(request.Filters.NodeLabels) == 0 {
146
+					return true
147
+				}
148
+				return filterMatchLabels(e.Spec.Annotations.Labels, request.Filters.NodeLabels)
149
+			},
150
+			func(e *api.Node) bool {
145 151
 				if len(request.Filters.Roles) == 0 {
146 152
 					return true
147 153
 				}
... ...
@@ -126,6 +126,13 @@ type Config struct {
126 126
 	// first node in the cluster, this setting is used to set the cluster-wide mandatory
127 127
 	// FIPS setting.
128 128
 	FIPS bool
129
+
130
+	// DefaultAddrPool specifies default subnet pool for global scope networks
131
+	DefaultAddrPool []*net.IPNet
132
+
133
+	// SubnetSize specifies the subnet size of the networks created from
134
+	// the default subnet pool
135
+	SubnetSize int
129 136
 }
130 137
 
131 138
 // Manager is the cluster manager for Swarm.
... ...
@@ -924,20 +931,33 @@ func (m *Manager) becomeLeader(ctx context.Context) {
924 924
 			Key:       m.config.UnlockKey,
925 925
 		}}
926 926
 	}
927
-
928 927
 	s.Update(func(tx store.Tx) error {
929 928
 		// Add a default cluster object to the
930 929
 		// store. Don't check the error because
931 930
 		// we expect this to fail unless this
932 931
 		// is a brand new cluster.
933
-		err := store.CreateCluster(tx, defaultClusterObject(
932
+		clusterObj := defaultClusterObject(
934 933
 			clusterID,
935 934
 			initialCAConfig,
936 935
 			raftCfg,
937 936
 			api.EncryptionConfig{AutoLockManagers: m.config.AutoLockManagers},
938 937
 			unlockKeys,
939 938
 			rootCA,
940
-			m.config.FIPS))
939
+			m.config.FIPS,
940
+			nil,
941
+			0)
942
+
943
+		var defaultAddrPool []string
944
+		for _, p := range m.config.DefaultAddrPool {
945
+			defaultAddrPool = append(defaultAddrPool, p.String())
946
+		}
947
+		// If defaultAddrPool is valid we update cluster object with new value
948
+		if defaultAddrPool != nil {
949
+			clusterObj.DefaultAddressPool = defaultAddrPool
950
+			clusterObj.SubnetSize = uint32(m.config.SubnetSize)
951
+		}
952
+
953
+		err := store.CreateCluster(tx, clusterObj)
941 954
 
942 955
 		if err != nil && err != store.ErrExist {
943 956
 			log.G(ctx).WithError(err).Errorf("error creating cluster object")
... ...
@@ -981,7 +1001,26 @@ func (m *Manager) becomeLeader(ctx context.Context) {
981 981
 	// shutdown underlying manager processes when leadership is
982 982
 	// lost.
983 983
 
984
-	m.allocator, err = allocator.New(s, m.config.PluginGetter)
984
+	// If DefaultAddrPool is null, Read from store and check if
985
+	// DefaultAddrPool info is stored in cluster object
986
+	if m.config.DefaultAddrPool == nil {
987
+		var cluster *api.Cluster
988
+		s.View(func(tx store.ReadTx) {
989
+			cluster = store.GetCluster(tx, clusterID)
990
+		})
991
+		if cluster.DefaultAddressPool != nil {
992
+			for _, address := range cluster.DefaultAddressPool {
993
+				_, b, err := net.ParseCIDR(address)
994
+				if err != nil {
995
+					log.G(ctx).WithError(err).Error("Default Address Pool reading failed for cluster object  %s", address)
996
+				}
997
+				m.config.DefaultAddrPool = append(m.config.DefaultAddrPool, b)
998
+			}
999
+		}
1000
+		m.config.SubnetSize = int(cluster.SubnetSize)
1001
+	}
1002
+
1003
+	m.allocator, err = allocator.New(s, m.config.PluginGetter, m.config.DefaultAddrPool, m.config.SubnetSize)
985 1004
 	if err != nil {
986 1005
 		log.G(ctx).WithError(err).Error("failed to create allocator")
987 1006
 		// TODO(stevvooe): It doesn't seem correct here to fail
... ...
@@ -1103,7 +1142,9 @@ func defaultClusterObject(
1103 1103
 	encryptionConfig api.EncryptionConfig,
1104 1104
 	initialUnlockKeys []*api.EncryptionKey,
1105 1105
 	rootCA *ca.RootCA,
1106
-	fips bool) *api.Cluster {
1106
+	fips bool,
1107
+	defaultAddressPool []string,
1108
+	subnetSize int) *api.Cluster {
1107 1109
 	var caKey []byte
1108 1110
 	if rcaSigner, err := rootCA.Signer(); err == nil {
1109 1111
 		caKey = rcaSigner.Key
... ...
@@ -1134,8 +1175,10 @@ func defaultClusterObject(
1134 1134
 				Manager: ca.GenerateJoinToken(rootCA, fips),
1135 1135
 			},
1136 1136
 		},
1137
-		UnlockKeys: initialUnlockKeys,
1138
-		FIPS:       fips,
1137
+		UnlockKeys:         initialUnlockKeys,
1138
+		FIPS:               fips,
1139
+		DefaultAddressPool: defaultAddressPool,
1140
+		SubnetSize:         uint32(subnetSize),
1139 1141
 	}
1140 1142
 }
1141 1143
 
... ...
@@ -105,6 +105,13 @@ type Config struct {
105 105
 	// for connections to the remote API (including the raft service).
106 106
 	AdvertiseRemoteAPI string
107 107
 
108
+	// DefaultAddrPool specifies default subnet pool for global scope networks
109
+	DefaultAddrPool []*net.IPNet
110
+
111
+	// SubnetSize specifies the subnet size of the networks created from
112
+	// the default subnet pool
113
+	SubnetSize int
114
+
108 115
 	// Executor specifies the executor to use for the agent.
109 116
 	Executor exec.Executor
110 117
 
... ...
@@ -995,6 +1002,8 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
995 995
 		PluginGetter:     n.config.PluginGetter,
996 996
 		RootCAPaths:      rootPaths,
997 997
 		FIPS:             n.config.FIPS,
998
+		DefaultAddrPool:  n.config.DefaultAddrPool,
999
+		SubnetSize:       n.config.SubnetSize,
998 1000
 	})
999 1001
 	if err != nil {
1000 1002
 		return false, err
... ...
@@ -33,7 +33,7 @@ github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6
33 33
 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
34 34
 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
35 35
 github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef
36
-github.com/docker/libnetwork d00ceed44cc447c77f25cdf5d59e83163bdcb4c9
36
+github.com/docker/libnetwork a79d3687931697244b8e03485bf7b2042f8ec6b6
37 37
 github.com/opencontainers/runc ad0f5255060d36872be04de22f8731f38ef2d7b1
38 38
 github.com/opencontainers/go-digest v1.0.0-rc1
39 39
 github.com/opencontainers/image-spec v1.0.1