From 1c1efd72ecd3cac466de9787b2c3472c54a79e31 Mon Sep 17 00:00:00 2001 From: Santhosh Manohar Date: Fri, 23 Oct 2015 08:11:57 -0700 Subject: [PATCH] Vendor in libnetwork changes to support container rename Signed-off-by: Santhosh Manohar Upstream-commit: 1041f3967086052438a3e34cee3db14e2277b629 Component: engine --- components/engine/hack/vendor.sh | 2 +- .../docker/libnetwork/controller.go | 1 + .../github.com/docker/libnetwork/endpoint.go | 45 +++++++++++++++++++ .../docker/libnetwork/endpoint_cnt.go | 15 +++++++ .../github.com/docker/libnetwork/sandbox.go | 26 +++++++++++ .../src/github.com/docker/libnetwork/store.go | 33 ++++++++------ 6 files changed, 107 insertions(+), 15 deletions(-) diff --git a/components/engine/hack/vendor.sh b/components/engine/hack/vendor.sh index 8398e56c3c..d872d4a3fa 100755 --- a/components/engine/hack/vendor.sh +++ b/components/engine/hack/vendor.sh @@ -21,7 +21,7 @@ clone git github.com/vdemeester/shakers 3c10293ce22b900c27acad7b28656196fcc2f73b clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git #get libnetwork packages -clone git github.com/docker/libnetwork c92c21bca42a3581fd108d3222848faa16372249 +clone git github.com/docker/libnetwork abc0807d72e309f53155ec4f6374a77fd6613849 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4 diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/controller.go b/components/engine/vendor/src/github.com/docker/libnetwork/controller.go index a81a9d67a0..3b75ae213c 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/controller.go +++ b/components/engine/vendor/src/github.com/docker/libnetwork/controller.go @@ -143,6 +143,7 @@ type controller struct { watchCh chan *endpoint unWatchCh chan *endpoint svcDb map[string]svcMap + nmap map[string]*netWatch sync.Mutex } diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/endpoint.go b/components/engine/vendor/src/github.com/docker/libnetwork/endpoint.go index 4288366a8a..de7b652dc5 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/endpoint.go +++ b/components/engine/vendor/src/github.com/docker/libnetwork/endpoint.go @@ -431,6 +431,51 @@ func (ep *endpoint) sbJoin(sbox Sandbox, options ...EndpointOption) error { return sb.clearDefaultGW() } +func (ep *endpoint) rename(name string) error { + var err error + n := ep.getNetwork() + if n == nil { + return fmt.Errorf("network not connected for ep %q", ep.name) + } + + n.getController().Lock() + netWatch, ok := n.getController().nmap[n.ID()] + n.getController().Unlock() + + if !ok { + return fmt.Errorf("watch null for network %q", n.Name()) + } + + n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), false) + + oldName := ep.name + ep.name = name + + n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), true) + defer func() { + if err != nil { + n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), false) + ep.name = oldName + n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), true) + } + }() + + // Update the store with the updated name + if err = n.getController().updateToStore(ep); err != nil { + return err + } + // After the name change do a dummy endpoint count update to + // trigger the service record update in the peer nodes + + // Ignore the error because updateStore fail for EpCnt is a + // benign error. Besides there is no meaningful recovery that + // we can do. When the cluster recovers subsequent EpCnt update + // will force the peers to get the correct EP name. + n.getEpCnt().updateStore() + + return err +} + func (ep *endpoint) hasInterface(iName string) bool { ep.Lock() defer ep.Unlock() diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/endpoint_cnt.go b/components/engine/vendor/src/github.com/docker/libnetwork/endpoint_cnt.go index 550a2a3cfd..507de393b8 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/endpoint_cnt.go +++ b/components/engine/vendor/src/github.com/docker/libnetwork/endpoint_cnt.go @@ -108,6 +108,21 @@ func (ec *endpointCnt) EndpointCnt() uint64 { return ec.Count } +func (ec *endpointCnt) updateStore() error { + store := ec.n.getController().getStore(ec.DataScope()) + if store == nil { + return fmt.Errorf("store not found for scope %s on endpoint count update", ec.DataScope()) + } + for { + if err := ec.n.getController().updateToStore(ec); err == nil || err != datastore.ErrKeyModified { + return err + } + if err := store.GetObject(datastore.Key(ec.Key()...), ec); err != nil { + return fmt.Errorf("could not update the kvobject to latest on endpoint count update: %v", err) + } + } +} + func (ec *endpointCnt) atomicIncDecEpCnt(inc bool) error { retry: ec.Lock() diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go b/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go index ff0c66fc9c..bb5097935c 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go +++ b/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go @@ -34,6 +34,8 @@ type Sandbox interface { Refresh(options ...SandboxOption) error // SetKey updates the Sandbox Key SetKey(key string) error + // Rename changes the name of all attached Endpoints + Rename(name string) error // Delete destroys this container after detaching it from all connected endpoints. Delete() error } @@ -201,6 +203,30 @@ func (sb *sandbox) Delete() error { return nil } +func (sb *sandbox) Rename(name string) error { + var err error + + for _, ep := range sb.getConnectedEndpoints() { + if ep.endpointInGWNetwork() { + continue + } + + oldName := ep.Name() + lEp := ep + if err = ep.rename(name); err != nil { + break + } + + defer func() { + if err != nil { + lEp.rename(oldName) + } + }() + } + + return err +} + func (sb *sandbox) Refresh(options ...SandboxOption) error { // Store connected endpoints epList := sb.getConnectedEndpoints() diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/store.go b/components/engine/vendor/src/github.com/docker/libnetwork/store.go index 7bbb9aa1bb..299e83ad6d 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/store.go +++ b/components/engine/vendor/src/github.com/docker/libnetwork/store.go @@ -274,25 +274,30 @@ func (c *controller) networkWatchLoop(nw *netWatch, ep *endpoint, ecCh <-chan da continue } - if _, ok := nw.remoteEps[lEp.ID()]; ok { - delete(delEpMap, lEp.ID()) - continue + if ep, ok := nw.remoteEps[lEp.ID()]; ok { + // On a container rename EP ID will remain + // the same but the name will change. service + // records should reflect the change. + // Keep old EP entry in the delEpMap and add + // EP from the store (which has the new name) + // into the new list + if lEp.name == ep.name { + delete(delEpMap, lEp.ID()) + continue + } } - nw.remoteEps[lEp.ID()] = lEp addEp = append(addEp, lEp) - } c.Unlock() - for _, lEp := range addEp { - ep.getNetwork().updateSvcRecord(lEp, c.getLocalEps(nw), true) - } - for _, lEp := range delEpMap { ep.getNetwork().updateSvcRecord(lEp, c.getLocalEps(nw), false) } + for _, lEp := range addEp { + ep.getNetwork().updateSvcRecord(lEp, c.getLocalEps(nw), true) + } } } } @@ -378,13 +383,13 @@ func (c *controller) processEndpointDelete(nmap map[string]*netWatch, ep *endpoi c.Unlock() } -func (c *controller) watchLoop(nmap map[string]*netWatch) { +func (c *controller) watchLoop() { for { select { case ep := <-c.watchCh: - c.processEndpointCreate(nmap, ep) + c.processEndpointCreate(c.nmap, ep) case ep := <-c.unWatchCh: - c.processEndpointDelete(nmap, ep) + c.processEndpointDelete(c.nmap, ep) } } } @@ -392,7 +397,7 @@ func (c *controller) watchLoop(nmap map[string]*netWatch) { func (c *controller) startWatch() { c.watchCh = make(chan *endpoint) c.unWatchCh = make(chan *endpoint) - nmap := make(map[string]*netWatch) + c.nmap = make(map[string]*netWatch) - go c.watchLoop(nmap) + go c.watchLoop() }