Browse code

Update libnetwork to latest version

Signed-off-by: Tom Denham <tom@tomdee.co.uk>

Tom Denham authored on 2016/11/20 09:03:22
Showing 18 changed files
... ...
@@ -23,7 +23,7 @@ github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e
23 23
 github.com/imdario/mergo 0.2.1
24 24
 
25 25
 #get libnetwork packages
26
-github.com/docker/libnetwork 57be722e077059d1ee0539be31743a3642ccbeb3
26
+github.com/docker/libnetwork f36e733a08cd8239a2db296994cb6613fef1cece 
27 27
 github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
28 28
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
29 29
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -381,7 +381,57 @@ func (n *network) leaveCluster() error {
381 381
 	return c.agent.networkDB.LeaveNetwork(n.ID())
382 382
 }
383 383
 
384
-func (ep *endpoint) addToCluster() error {
384
+func (ep *endpoint) addDriverInfoToCluster() error {
385
+	n := ep.getNetwork()
386
+	if !n.isClusterEligible() {
387
+		return nil
388
+	}
389
+	if ep.joinInfo == nil {
390
+		return nil
391
+	}
392
+
393
+	ctrlr := n.ctrlr
394
+	ctrlr.Lock()
395
+	agent := ctrlr.agent
396
+	ctrlr.Unlock()
397
+	if agent == nil {
398
+		return nil
399
+	}
400
+
401
+	for _, te := range ep.joinInfo.driverTableEntries {
402
+		if err := agent.networkDB.CreateEntry(te.tableName, n.ID(), te.key, te.value); err != nil {
403
+			return err
404
+		}
405
+	}
406
+	return nil
407
+}
408
+
409
+func (ep *endpoint) deleteDriverInfoFromCluster() error {
410
+	n := ep.getNetwork()
411
+	if !n.isClusterEligible() {
412
+		return nil
413
+	}
414
+	if ep.joinInfo == nil {
415
+		return nil
416
+	}
417
+
418
+	ctrlr := n.ctrlr
419
+	ctrlr.Lock()
420
+	agent := ctrlr.agent
421
+	ctrlr.Unlock()
422
+	if agent == nil {
423
+		return nil
424
+	}
425
+
426
+	for _, te := range ep.joinInfo.driverTableEntries {
427
+		if err := agent.networkDB.DeleteEntry(te.tableName, n.ID(), te.key); err != nil {
428
+			return err
429
+		}
430
+	}
431
+	return nil
432
+}
433
+
434
+func (ep *endpoint) addServiceInfoToCluster() error {
385 435
 	n := ep.getNetwork()
386 436
 	if !n.isClusterEligible() {
387 437
 		return nil
... ...
@@ -421,16 +471,10 @@ func (ep *endpoint) addToCluster() error {
421 421
 		}
422 422
 	}
423 423
 
424
-	for _, te := range ep.joinInfo.driverTableEntries {
425
-		if err := c.agent.networkDB.CreateEntry(te.tableName, n.ID(), te.key, te.value); err != nil {
426
-			return err
427
-		}
428
-	}
429
-
430 424
 	return nil
431 425
 }
432 426
 
433
-func (ep *endpoint) deleteFromCluster() error {
427
+func (ep *endpoint) deleteServiceInfoFromCluster() error {
434 428
 	n := ep.getNetwork()
435 429
 	if !n.isClusterEligible() {
436 430
 		return nil
... ...
@@ -453,17 +497,6 @@ func (ep *endpoint) deleteFromCluster() error {
453 453
 			return err
454 454
 		}
455 455
 	}
456
-
457
-	if ep.joinInfo == nil {
458
-		return nil
459
-	}
460
-
461
-	for _, te := range ep.joinInfo.driverTableEntries {
462
-		if err := c.agent.networkDB.DeleteEntry(te.tableName, n.ID(), te.key); err != nil {
463
-			return err
464
-		}
465
-	}
466
-
467 456
 	return nil
468 457
 }
469 458
 
... ...
@@ -17,11 +17,11 @@ import (
17 17
 	"github.com/docker/libnetwork/osl"
18 18
 )
19 19
 
20
-// RestrictedNameChars collects the characters allowed to represent a network or endpoint name.
21
-const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
20
+// restrictedNameRegex represents the regular expression which regulates the allowed network or endpoint names.
21
+const restrictedNameRegex = `^[\w]+[\w-. ]*[\w]+$`
22 22
 
23 23
 // RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters.
24
-var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`)
24
+var restrictedNamePattern = regexp.MustCompile(restrictedNameRegex)
25 25
 
26 26
 // Config encapsulates configurations of various Libnetwork components
27 27
 type Config struct {
... ...
@@ -234,7 +234,7 @@ func (c *Config) ProcessOptions(options ...Option) {
234 234
 // ValidateName validates configuration objects supported by libnetwork
235 235
 func ValidateName(name string) error {
236 236
 	if !restrictedNamePattern.MatchString(name) {
237
-		return fmt.Errorf("%s includes invalid characters, only %q are allowed", name, restrictedNameChars)
237
+		return fmt.Errorf("%q includes invalid characters, resource name has to conform to %q", name, restrictedNameRegex)
238 238
 	}
239 239
 	return nil
240 240
 }
... ...
@@ -77,7 +77,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
77 77
 	}
78 78
 
79 79
 	if s := n.getSubnetforIP(ep.addr); s == nil {
80
-		return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
80
+		return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
81 81
 	}
82 82
 
83 83
 	if ep.mac == nil {
... ...
@@ -320,6 +320,11 @@ func populateVNITbl() {
320 320
 			}
321 321
 			defer nlh.Delete()
322 322
 
323
+			err = nlh.SetSocketTimeout(soTimeout)
324
+			if err != nil {
325
+				logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vni table population: %v", err)
326
+			}
327
+
323 328
 			links, err := nlh.LinkList()
324 329
 			if err != nil {
325 330
 				logrus.Errorf("Failed to list interfaces during vni population for ns %s: %v", path, err)
... ...
@@ -13,6 +13,8 @@ import (
13 13
 	"github.com/vishvananda/netns"
14 14
 )
15 15
 
16
+var soTimeout = ns.NetlinkSocketsTimeout
17
+
16 18
 func validateID(nid, eid string) error {
17 19
 	if nid == "" {
18 20
 		return fmt.Errorf("invalid network id")
... ...
@@ -134,6 +136,10 @@ func deleteVxlanByVNI(path string, vni uint32) error {
134 134
 			return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err)
135 135
 		}
136 136
 		defer nlh.Delete()
137
+		err = nlh.SetSocketTimeout(soTimeout)
138
+		if err != nil {
139
+			logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err)
140
+		}
137 141
 	}
138 142
 
139 143
 	links, err := nlh.LinkList()
... ...
@@ -277,7 +277,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
277 277
 
278 278
 	s := n.getSubnetforIP(IP)
279 279
 	if s == nil {
280
-		return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id)
280
+		return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id)
281 281
 	}
282 282
 
283 283
 	if err := n.obtainVxlanID(s); err != nil {
... ...
@@ -76,7 +76,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
76 76
 	}
77 77
 
78 78
 	if s := n.getSubnetforIP(ep.addr); s == nil {
79
-		return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
79
+		return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
80 80
 	}
81 81
 
82 82
 	if ep.mac == nil {
... ...
@@ -263,7 +263,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
263 263
 
264 264
 	s := n.getSubnetforIP(IP)
265 265
 	if s == nil {
266
-		return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id)
266
+		return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id)
267 267
 	}
268 268
 
269 269
 	if err := n.obtainVxlanID(s); err != nil {
... ...
@@ -515,6 +515,10 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
515 515
 		return err
516 516
 	}
517 517
 
518
+	if err = ep.addDriverInfoToCluster(); err != nil {
519
+		return err
520
+	}
521
+
518 522
 	if sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
519 523
 		return sb.setupDefaultGW()
520 524
 	}
... ...
@@ -709,8 +713,12 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption)
709 709
 		return err
710 710
 	}
711 711
 
712
-	if e := ep.deleteFromCluster(); e != nil {
713
-		logrus.Errorf("Could not delete state for endpoint %s from cluster: %v", ep.Name(), e)
712
+	if e := ep.deleteServiceInfoFromCluster(); e != nil {
713
+		logrus.Errorf("Could not delete service state for endpoint %s from cluster: %v", ep.Name(), e)
714
+	}
715
+
716
+	if e := ep.deleteDriverInfoFromCluster(); e != nil {
717
+		logrus.Errorf("Could not delete endpoint state for endpoint %s from cluster: %v", ep.Name(), e)
714 718
 	}
715 719
 
716 720
 	sb.deleteHostsEntries(n.getSvcRecords(ep))
... ...
@@ -413,7 +413,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error)
413 413
 		}
414 414
 	}
415 415
 
416
-	return nil, types.NotFoundErrorf("could not find an available non-overlapping address pool among the defaults to auto assign to the network")
416
+	return nil, types.NotFoundErrorf("could not find an available, non-overlapping IPv%d address pool among the defaults to assign to the network", v)
417 417
 }
418 418
 
419 419
 // RequestAddress returns an address from the specified pool ID
... ...
@@ -130,7 +130,7 @@ func NewChain(name string, table Table, hairpinMode bool) (*ChainInfo, error) {
130 130
 // ProgramChain is used to add rules to a chain
131 131
 func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) error {
132 132
 	if c.Name == "" {
133
-		return fmt.Errorf("Could not program chain, missing chain name.")
133
+		return fmt.Errorf("Could not program chain, missing chain name")
134 134
 	}
135 135
 
136 136
 	switch c.Table {
... ...
@@ -166,7 +166,7 @@ func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) err
166 166
 		}
167 167
 	case Filter:
168 168
 		if bridgeName == "" {
169
-			return fmt.Errorf("Could not program chain %s/%s, missing bridge name.",
169
+			return fmt.Errorf("Could not program chain %s/%s, missing bridge name",
170 170
 				c.Table, c.Name)
171 171
 		}
172 172
 		link := []string{
... ...
@@ -65,6 +65,7 @@ type NetworkInfo interface {
65 65
 	Scope() string
66 66
 	IPv6Enabled() bool
67 67
 	Internal() bool
68
+	Attachable() bool
68 69
 	Labels() map[string]string
69 70
 	Dynamic() bool
70 71
 	Created() time.Time
... ...
@@ -196,6 +197,7 @@ type network struct {
196 196
 	resolverOnce sync.Once
197 197
 	resolver     []Resolver
198 198
 	internal     bool
199
+	attachable   bool
199 200
 	inDelete     bool
200 201
 	ingress      bool
201 202
 	driverTables []string
... ...
@@ -348,6 +350,7 @@ func (n *network) CopyTo(o datastore.KVObject) error {
348 348
 	dstN.dbExists = n.dbExists
349 349
 	dstN.drvOnce = n.drvOnce
350 350
 	dstN.internal = n.internal
351
+	dstN.attachable = n.attachable
351 352
 	dstN.inDelete = n.inDelete
352 353
 	dstN.ingress = n.ingress
353 354
 
... ...
@@ -456,6 +459,7 @@ func (n *network) MarshalJSON() ([]byte, error) {
456 456
 		netMap["ipamV6Info"] = string(iis)
457 457
 	}
458 458
 	netMap["internal"] = n.internal
459
+	netMap["attachable"] = n.attachable
459 460
 	netMap["inDelete"] = n.inDelete
460 461
 	netMap["ingress"] = n.ingress
461 462
 	return json.Marshal(netMap)
... ...
@@ -550,6 +554,9 @@ func (n *network) UnmarshalJSON(b []byte) (err error) {
550 550
 	if v, ok := netMap["internal"]; ok {
551 551
 		n.internal = v.(bool)
552 552
 	}
553
+	if v, ok := netMap["attachable"]; ok {
554
+		n.attachable = v.(bool)
555
+	}
553 556
 	if s, ok := netMap["scope"]; ok {
554 557
 		n.scope = s.(string)
555 558
 	}
... ...
@@ -628,6 +635,13 @@ func NetworkOptionInternalNetwork() NetworkOption {
628 628
 	}
629 629
 }
630 630
 
631
+// NetworkOptionAttachable returns an option setter to set attachable for a network
632
+func NetworkOptionAttachable(attachable bool) NetworkOption {
633
+	return func(n *network) {
634
+		n.attachable = attachable
635
+	}
636
+}
637
+
631 638
 // NetworkOptionIpam function returns an option setter for the ipam configuration for this network
632 639
 func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf, opts map[string]string) NetworkOption {
633 640
 	return func(n *network) {
... ...
@@ -1289,9 +1303,6 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
1289 1289
 	}
1290 1290
 
1291 1291
 	if len(*cfgList) == 0 {
1292
-		if ipVer == 6 {
1293
-			return nil
1294
-		}
1295 1292
 		*cfgList = []*IpamConf{{}}
1296 1293
 	}
1297 1294
 
... ...
@@ -1555,6 +1566,13 @@ func (n *network) Internal() bool {
1555 1555
 	return n.internal
1556 1556
 }
1557 1557
 
1558
+func (n *network) Attachable() bool {
1559
+	n.Lock()
1560
+	defer n.Unlock()
1561
+
1562
+	return n.attachable
1563
+}
1564
+
1558 1565
 func (n *network) Dynamic() bool {
1559 1566
 	n.Lock()
1560 1567
 	defer n.Unlock()
... ...
@@ -265,7 +265,7 @@ func (nDB *NetworkDB) CreateEntry(tname, nid, key string, value []byte) error {
265 265
 	}
266 266
 
267 267
 	if err := nDB.sendTableEvent(TableEventTypeCreate, nid, tname, key, entry); err != nil {
268
-		return fmt.Errorf("cannot send table create event: %v", err)
268
+		return fmt.Errorf("cannot send create event for table %s, %v", tname, err)
269 269
 	}
270 270
 
271 271
 	nDB.Lock()
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	"strings"
8 8
 	"sync"
9 9
 	"syscall"
10
+	"time"
10 11
 
11 12
 	"github.com/Sirupsen/logrus"
12 13
 	"github.com/vishvananda/netlink"
... ...
@@ -17,6 +18,8 @@ var (
17 17
 	initNs   netns.NsHandle
18 18
 	initNl   *netlink.Handle
19 19
 	initOnce sync.Once
20
+	// NetlinkSocketsTimeout represents the default timeout duration for the sockets
21
+	NetlinkSocketsTimeout = 3 * time.Second
20 22
 )
21 23
 
22 24
 // Init initializes a new network namespace
... ...
@@ -30,6 +33,10 @@ func Init() {
30 30
 	if err != nil {
31 31
 		logrus.Errorf("could not create netlink handle on initial namespace: %v", err)
32 32
 	}
33
+	err = initNl.SetSocketTimeout(NetlinkSocketsTimeout)
34
+	if err != nil {
35
+		logrus.Warnf("Failed to set the timeout on the default netlink handle sockets: %v", err)
36
+	}
33 37
 }
34 38
 
35 39
 // SetNamespace sets the initial namespace handler
... ...
@@ -211,6 +211,11 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) {
211 211
 		return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
212 212
 	}
213 213
 
214
+	err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout)
215
+	if err != nil {
216
+		logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err)
217
+	}
218
+
214 219
 	if err = n.loopbackUp(); err != nil {
215 220
 		n.nlHandle.Delete()
216 221
 		return nil, err
... ...
@@ -253,6 +258,11 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) {
253 253
 		return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
254 254
 	}
255 255
 
256
+	err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout)
257
+	if err != nil {
258
+		logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err)
259
+	}
260
+
256 261
 	if err = n.loopbackUp(); err != nil {
257 262
 		n.nlHandle.Delete()
258 263
 		return nil, err
... ...
@@ -80,6 +80,7 @@ func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr,
80 80
 	for i, nh := range n.neighbors {
81 81
 		if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) {
82 82
 			n.neighbors = append(n.neighbors[:i], n.neighbors[i+1:]...)
83
+			break
83 84
 		}
84 85
 	}
85 86
 	n.Unlock()
... ...
@@ -427,7 +427,13 @@ func (sb *sandbox) ResolveIP(ip string) string {
427 427
 }
428 428
 
429 429
 func (sb *sandbox) ExecFunc(f func()) error {
430
-	return sb.osSbox.InvokeFunc(f)
430
+	sb.Lock()
431
+	osSbox := sb.osSbox
432
+	sb.Unlock()
433
+	if osSbox != nil {
434
+		return osSbox.InvokeFunc(f)
435
+	}
436
+	return fmt.Errorf("osl sandbox unavailable in ExecFunc for %v", sb.ContainerID())
431 437
 }
432 438
 
433 439
 func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
... ...
@@ -664,7 +670,7 @@ func (sb *sandbox) SetKey(basePath string) error {
664 664
 func (sb *sandbox) EnableService() error {
665 665
 	for _, ep := range sb.getConnectedEndpoints() {
666 666
 		if ep.enableService(true) {
667
-			if err := ep.addToCluster(); err != nil {
667
+			if err := ep.addServiceInfoToCluster(); err != nil {
668 668
 				ep.enableService(false)
669 669
 				return fmt.Errorf("could not update state for endpoint %s into cluster: %v", ep.Name(), err)
670 670
 			}
... ...
@@ -676,7 +682,7 @@ func (sb *sandbox) EnableService() error {
676 676
 func (sb *sandbox) DisableService() error {
677 677
 	for _, ep := range sb.getConnectedEndpoints() {
678 678
 		if ep.enableService(false) {
679
-			if err := ep.deleteFromCluster(); err != nil {
679
+			if err := ep.deleteServiceInfoFromCluster(); err != nil {
680 680
 				ep.enableService(true)
681 681
 				return fmt.Errorf("could not delete state for endpoint %s from cluster: %v", ep.Name(), err)
682 682
 			}