Signed-off-by: Dong Chen <dongluo.chen@docker.com>
| ... | ... |
@@ -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. |