Browse code

Vendor libnetwork a98901aebe7ce920b6fbf02ebe5c3afc9ca975b8.

Signed-off-by: Dong Chen <dongluo.chen@docker.com>

Dong Chen authored on 2016/11/05 02:25:16
Showing 4 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 9ab6e136fa628b5bb4af4a75f76609ef2c21c024
26
+github.com/docker/libnetwork a98901aebe7ce920b6fbf02ebe5c3afc9ca975b8
27 27
 github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
28 28
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
29 29
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -74,6 +74,7 @@ type endpoint struct {
74 74
 	ingressPorts      []*PortConfig
75 75
 	dbIndex           uint64
76 76
 	dbExists          bool
77
+	serviceEnabled    bool
77 78
 	sync.Mutex
78 79
 }
79 80
 
... ...
@@ -303,6 +304,18 @@ func (ep *endpoint) isAnonymous() bool {
303 303
 	return ep.anonymous
304 304
 }
305 305
 
306
+// enableService sets ep's serviceEnabled to the passed value if it's not in the
307
+// current state and returns true; false otherwise.
308
+func (ep *endpoint) enableService(state bool) bool {
309
+	ep.Lock()
310
+	defer ep.Unlock()
311
+	if ep.serviceEnabled != state {
312
+		ep.serviceEnabled = state
313
+		return true
314
+	}
315
+	return false
316
+}
317
+
306 318
 func (ep *endpoint) needResolver() bool {
307 319
 	ep.Lock()
308 320
 	defer ep.Unlock()
... ...
@@ -502,10 +515,6 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
502 502
 		return err
503 503
 	}
504 504
 
505
-	if e := ep.addToCluster(); e != nil {
506
-		log.Errorf("Could not update state for endpoint %s into cluster: %v", ep.Name(), e)
507
-	}
508
-
509 505
 	if sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
510 506
 		return sb.setupDefaultGW()
511 507
 	}
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"github.com/Sirupsen/logrus"
12 12
 	"github.com/armon/go-radix"
13 13
 	"github.com/docker/go-events"
14
+	"github.com/docker/libnetwork/types"
14 15
 	"github.com/hashicorp/memberlist"
15 16
 	"github.com/hashicorp/serf/serf"
16 17
 )
... ...
@@ -237,7 +238,7 @@ func (nDB *NetworkDB) getEntry(tname, nid, key string) (*entry, error) {
237 237
 
238 238
 	e, ok := nDB.indexes[byTable].Get(fmt.Sprintf("/%s/%s/%s", tname, nid, key))
239 239
 	if !ok {
240
-		return nil, fmt.Errorf("could not get entry in table %s with network id %s and key %s", tname, nid, key)
240
+		return nil, types.NotFoundErrorf("could not get entry in table %s with network id %s and key %s", tname, nid, key)
241 241
 	}
242 242
 
243 243
 	return e.(*entry), nil
... ...
@@ -247,10 +248,16 @@ func (nDB *NetworkDB) getEntry(tname, nid, key string) (*entry, error) {
247 247
 // table, key) tuple and if the NetworkDB is part of the cluster
248 248
 // propogates this event to the cluster. It is an error to create an
249 249
 // entry for the same tuple for which there is already an existing
250
-// entry.
250
+// entry unless the current entry is deleting state.
251 251
 func (nDB *NetworkDB) CreateEntry(tname, nid, key string, value []byte) error {
252
-	if _, err := nDB.GetEntry(tname, nid, key); err == nil {
253
-		return fmt.Errorf("cannot create entry as the entry in table %s with network id %s and key %s already exists", tname, nid, key)
252
+	oldEntry, err := nDB.getEntry(tname, nid, key)
253
+	if err != nil {
254
+		if _, ok := err.(types.NotFoundError); !ok {
255
+			return fmt.Errorf("cannot create entry in table %s with network id %s and key %s: %v", tname, nid, key, err)
256
+		}
257
+	}
258
+	if oldEntry != nil && !oldEntry.deleting {
259
+		return fmt.Errorf("cannot create entry in table %s with network id %s and key %s, already exists", tname, nid, key)
254 260
 	}
255 261
 
256 262
 	entry := &entry{
... ...
@@ -42,6 +42,12 @@ type Sandbox interface {
42 42
 	// ResolveService returns all the backend details about the containers or hosts
43 43
 	// backing a service. Its purpose is to satisfy an SRV query
44 44
 	ResolveService(name string) ([]*net.SRV, []net.IP)
45
+	// EnableService  makes a managed container's service available by adding the
46
+	// endpoint to the service load balancer and service discovery
47
+	EnableService() error
48
+	// DisableService removes a managed contianer's endpoints from the load balancer
49
+	// and service discovery
50
+	DisableService() error
45 51
 }
46 52
 
47 53
 // SandboxOption is an option setter function type used to pass various options to
... ...
@@ -655,6 +661,30 @@ func (sb *sandbox) SetKey(basePath string) error {
655 655
 	return nil
656 656
 }
657 657
 
658
+func (sb *sandbox) EnableService() error {
659
+	for _, ep := range sb.getConnectedEndpoints() {
660
+		if ep.enableService(true) {
661
+			if err := ep.addToCluster(); err != nil {
662
+				ep.enableService(false)
663
+				return fmt.Errorf("could not update state for endpoint %s into cluster: %v", ep.Name(), err)
664
+			}
665
+		}
666
+	}
667
+	return nil
668
+}
669
+
670
+func (sb *sandbox) DisableService() error {
671
+	for _, ep := range sb.getConnectedEndpoints() {
672
+		if ep.enableService(false) {
673
+			if err := ep.deleteFromCluster(); err != nil {
674
+				ep.enableService(true)
675
+				return fmt.Errorf("could not delete state for endpoint %s from cluster: %v", ep.Name(), err)
676
+			}
677
+		}
678
+	}
679
+	return nil
680
+}
681
+
658 682
 func releaseOSSboxResources(osSbox osl.Sandbox, ep *endpoint) {
659 683
 	for _, i := range osSbox.Info().Interfaces() {
660 684
 		// Only remove the interfaces owned by this endpoint from the sandbox.