From 5492f4ab825a1fd972714829f1457042ad48ca67 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Sat, 6 Feb 2016 11:49:56 -0800 Subject: [PATCH 1/3] remove refresh networks Signed-off-by: Victor Vieux --- cluster/engine.go | 26 +++++++++++++++++++++++--- cluster/swarm/cluster.go | 25 +++++++++++-------------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/cluster/engine.go b/cluster/engine.go index c49be1f08a..c5e63ccbfa 100644 --- a/cluster/engine.go +++ b/cluster/engine.go @@ -427,12 +427,32 @@ func (e *Engine) RemoveImage(image *Image, name string, force bool) ([]*dockercl } -// RemoveNetwork deletes a network from the engine. +// RemoveNetwork removes a network from the engine. func (e *Engine) RemoveNetwork(network *Network) error { err := e.client.RemoveNetwork(network.ID) e.CheckConnectionErr(err) - e.RefreshNetworks() - return err + if err != nil { + return err + } + + // Remove the container from the state. Eventually, the state refresh loop + // will rewrite this. + e.DeleteNetwork(network) + return nil +} + +// DeleteNetwork deletes a network from the internal engine state. +func (e *Engine) DeleteNetwork(network *Network) { + e.Lock() + delete(e.networks, network.ID) + e.Unlock() +} + +// AddNetwork adds a network to the internal engine state. +func (e *Engine) AddNetwork(network *Network) { + e.Lock() + e.networks[network.ID] = network + e.Unlock() } // RemoveVolume deletes a volume from the engine. diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index 51d78543dc..d9b882f3b8 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -216,7 +216,11 @@ func (c *Cluster) RemoveContainer(container *cluster.Container, force, volumes b // RemoveNetwork removes a network from the cluster func (c *Cluster) RemoveNetwork(network *cluster.Network) error { err := network.Engine.RemoveNetwork(network) - c.refreshNetworks() + if err == nil { + for _, engine := range c.engines { + engine.DeleteNetwork(network) + } + } return err } @@ -434,18 +438,6 @@ func (c *Cluster) RemoveImages(name string, force bool) ([]*dockerclient.ImageDe return out, err } -func (c *Cluster) refreshNetworks() { - var wg sync.WaitGroup - for _, e := range c.engines { - wg.Add(1) - go func(e *cluster.Engine) { - e.RefreshNetworks() - wg.Done() - }(e) - } - wg.Wait() -} - func (c *Cluster) refreshVolumes() { var wg sync.WaitGroup for _, e := range c.engines { @@ -477,7 +469,12 @@ func (c *Cluster) CreateNetwork(request *dockerclient.NetworkCreate) (response * } if nodes != nil { resp, err := c.engines[nodes[0].ID].CreateNetwork(request) - c.refreshNetworks() + if err == nil { + network := c.engines[nodes[0].ID].Networks().Get(resp.ID) + for _, engine := range c.engines { + engine.AddNetwork(network) + } + } return resp, err } return nil, nil From 3747ec9b9f6a94596be9d2dcc99659d9662cd9a4 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 9 Feb 2016 21:34:40 -0800 Subject: [PATCH 2/3] change refresh logic with new events Signed-off-by: Victor Vieux --- cluster/engine.go | 54 ++++++++++++++++++++++++++++------------ cluster/swarm/cluster.go | 9 ++++--- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/cluster/engine.go b/cluster/engine.go index c5e63ccbfa..1cfd1232ac 100644 --- a/cluster/engine.go +++ b/cluster/engine.go @@ -451,7 +451,10 @@ func (e *Engine) DeleteNetwork(network *Network) { // AddNetwork adds a network to the internal engine state. func (e *Engine) AddNetwork(network *Network) { e.Lock() - e.networks[network.ID] = network + e.networks[network.ID] = &Network{ + NetworkResource: network.NetworkResource, + Engine: e, + } e.Unlock() } @@ -924,22 +927,41 @@ func (e *Engine) String() string { func (e *Engine) handler(ev *dockerclient.Event, _ chan error, args ...interface{}) { // Something changed - refresh our internal state. - switch ev.Status { - case "pull", "untag", "delete", "commit": - // These events refer to images so there's no need to update - // containers. + + switch ev.Type { + case "network": + e.RefreshNetworks() + case "volume": + e.RefreshVolumes() + case "image": e.RefreshImages() - case "die", "kill", "oom", "pause", "start", "stop", "unpause", "rename": - // If the container state changes, we have to do an inspect in - // order to update container.Info and get the new NetworkSettings. - e.refreshContainer(ev.ID, true) - e.RefreshVolumes() - e.RefreshNetworks() - default: - // Otherwise, do a "soft" refresh of the container. - e.refreshContainer(ev.ID, false) - e.RefreshVolumes() - e.RefreshNetworks() + case "container": + switch ev.Action { + case "die", "kill", "oom", "pause", "start", "stop", "unpause", "rename": + e.refreshContainer(ev.ID, true) + default: + e.refreshContainer(ev.ID, false) + } + case "": + // docker < 1.10 + switch ev.Status { + case "pull", "untag", "delete", "commit": + // These events refer to images so there's no need to update + // containers. + e.RefreshImages() + case "die", "kill", "oom", "pause", "start", "stop", "unpause", "rename": + // If the container state changes, we have to do an inspect in + // order to update container.Info and get the new NetworkSettings. + e.refreshContainer(ev.ID, true) + e.RefreshVolumes() + e.RefreshNetworks() + default: + // Otherwise, do a "soft" refresh of the container. + e.refreshContainer(ev.ID, false) + e.RefreshVolumes() + e.RefreshNetworks() + } + } // If there is no event handler registered, abort right now. diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index d9b882f3b8..75e2a84235 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -216,7 +216,7 @@ func (c *Cluster) RemoveContainer(container *cluster.Container, force, volumes b // RemoveNetwork removes a network from the cluster func (c *Cluster) RemoveNetwork(network *cluster.Network) error { err := network.Engine.RemoveNetwork(network) - if err == nil { + if err == nil && network.Scope == "global" { for _, engine := range c.engines { engine.DeleteNetwork(network) } @@ -470,9 +470,10 @@ func (c *Cluster) CreateNetwork(request *dockerclient.NetworkCreate) (response * if nodes != nil { resp, err := c.engines[nodes[0].ID].CreateNetwork(request) if err == nil { - network := c.engines[nodes[0].ID].Networks().Get(resp.ID) - for _, engine := range c.engines { - engine.AddNetwork(network) + if network := c.engines[nodes[0].ID].Networks().Get(resp.ID); network != nil && network.Scope == "global" { + for _, engine := range c.engines { + engine.AddNetwork(network) + } } } return resp, err From cd3b1d5bd1cc079b68f7303ec7df741e9859c031 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 11 Feb 2016 11:00:15 -0800 Subject: [PATCH 3/3] improve addNetwork Signed-off-by: Victor Vieux --- cluster/swarm/cluster.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index 75e2a84235..9d7e847cc3 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -471,8 +471,10 @@ func (c *Cluster) CreateNetwork(request *dockerclient.NetworkCreate) (response * resp, err := c.engines[nodes[0].ID].CreateNetwork(request) if err == nil { if network := c.engines[nodes[0].ID].Networks().Get(resp.ID); network != nil && network.Scope == "global" { - for _, engine := range c.engines { - engine.AddNetwork(network) + for id, engine := range c.engines { + if id != nodes[0].ID { + engine.AddNetwork(network) + } } } }