From 95cbc8940e4d1d7d2dc7ff0061ebdcad03f3e738 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 25 Jan 2016 17:21:12 +0000 Subject: [PATCH] Sync 'owned' data with existing containers at startup --- common/docker/client.go | 12 ++++++++++++ ipam/allocator.go | 27 +++++++++++++++++++++++++++ prog/weaver/main.go | 3 +++ 3 files changed, 42 insertions(+) diff --git a/common/docker/client.go b/common/docker/client.go index 1a9e2c09..c0233bf4 100644 --- a/common/docker/client.go +++ b/common/docker/client.go @@ -94,6 +94,18 @@ func (c *Client) AddObserver(ob ContainerObserver) error { return nil } +func (c *Client) AllContainerIDs() ([]string, error) { + all, err := c.ListContainers(docker.ListContainersOptions{All: true}) + if err != nil { + return nil, err + } + var ids []string + for _, c := range all { + ids = append(ids, c.ID) + } + return ids, nil +} + // IsContainerNotRunning returns true if we have checked with Docker that the ID is not running func (c *Client) IsContainerNotRunning(idStr string) bool { container, err := c.InspectContainer(idStr) diff --git a/ipam/allocator.go b/ipam/allocator.go index 637f3787..4ea0eb81 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -267,6 +267,16 @@ func (alloc *Allocator) ContainerStarted(ident string) { } } +func (alloc *Allocator) AllContainerIDs(ids []string) { + alloc.actionChan <- func() { + idmap := make(map[string]struct{}, len(ids)) + for _, id := range ids { + idmap[id] = struct{}{} + } + alloc.syncOwned(idmap) + } +} + // Delete (Sync) - release all IP addresses for container with given name func (alloc *Allocator) Delete(ident string) error { errChan := make(chan error) @@ -871,6 +881,23 @@ func (alloc *Allocator) findOwner(addr address.Address) string { return "" } +// For each ID in the 'owned' map, remove the entry if it isn't in the map +func (alloc *Allocator) syncOwned(ids map[string]struct{}) { + changed := false + for ident, addrs := range alloc.owned { + if _, found := ids[ident]; !found { + for _, addr := range addrs { + alloc.space.Free(addr) + } + delete(alloc.owned, ident) + changed = true + } + } + if changed { + alloc.persistOwned() + } +} + // Logging func (alloc *Allocator) fatalf(fmt string, args ...interface{}) { diff --git a/prog/weaver/main.go b/prog/weaver/main.go index e4b9ec70..09ee7f48 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -228,6 +228,9 @@ func main() { if iprangeCIDR != "" { allocator, defaultSubnet = createAllocator(router.Router, iprangeCIDR, ipsubnetCIDR, determineQuorum(peerCount, peers), db, isKnownPeer) observeContainers(allocator) + ids, err := dockerCli.AllContainerIDs() + checkFatal(err) + allocator.AllContainerIDs(ids) } else if peerCount > 0 { Log.Fatal("--init-peer-count flag specified without --ipalloc-range") }