Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove attachable network on swarm leave #30157

Merged
merged 1 commit into from Jan 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions daemon/cluster/cluster.go
Expand Up @@ -244,7 +244,7 @@ func (c *Cluster) newNodeRunner(conf nodeStartConfig) (*nodeRunner, error) {
return nil, err
}

c.config.Backend.SetClusterProvider(c)
c.config.Backend.DaemonJoinsCluster(c)

return nr, nil
}
Expand Down Expand Up @@ -562,7 +562,7 @@ func (c *Cluster) Leave(force bool) error {
if err := clearPersistentState(c.root); err != nil {
return err
}
c.config.Backend.SetClusterProvider(nil)
c.config.Backend.DaemonLeavesCluster()
return nil
}

Expand Down
3 changes: 2 additions & 1 deletion daemon/cluster/executor/backend.go
Expand Up @@ -47,7 +47,8 @@ type Backend interface {
VolumeCreate(name, driverName string, opts, labels map[string]string) (*types.Volume, error)
Containers(config *types.ContainerListOptions) ([]*types.Container, error)
SetNetworkBootstrapKeys([]*networktypes.EncryptionKey) error
SetClusterProvider(provider cluster.Provider)
DaemonJoinsCluster(provider cluster.Provider)
DaemonLeavesCluster()
IsSwarmCompatible() error
SubscribeToEvents(since, until time.Time, filter filters.Args) ([]events.Message, chan interface{})
UnsubscribeFromEvents(listener chan interface{})
Expand Down
18 changes: 16 additions & 2 deletions daemon/daemon.go
Expand Up @@ -433,8 +433,22 @@ func (daemon *Daemon) registerLink(parent, child *container.Container, alias str
return nil
}

// SetClusterProvider sets a component for querying the current cluster state.
func (daemon *Daemon) SetClusterProvider(clusterProvider cluster.Provider) {
// DaemonJoinsCluster informs the daemon has joined the cluster and provides
// the handler to query the cluster component
func (daemon *Daemon) DaemonJoinsCluster(clusterProvider cluster.Provider) {
daemon.setClusterProvider(clusterProvider)
}

// DaemonLeavesCluster informs the daemon has left the cluster
func (daemon *Daemon) DaemonLeavesCluster() {
// Daemon is in charge of removing the attachable networks with
// connected containers when the node leaves the swarm
daemon.clearAttachableNetworks()
daemon.setClusterProvider(nil)
}

// setClusterProvider sets a component for querying the current cluster state.
func (daemon *Daemon) setClusterProvider(clusterProvider cluster.Provider) {
daemon.clusterProvider = clusterProvider
daemon.netController.SetClusterProvider(clusterProvider)
}
Expand Down
28 changes: 28 additions & 0 deletions daemon/network.go
Expand Up @@ -468,3 +468,31 @@ func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
func (daemon *Daemon) GetNetworks() []libnetwork.Network {
return daemon.getAllNetworks()
}

// clearAttachableNetworks removes the attachable networks
// after disconnecting any connected container
func (daemon *Daemon) clearAttachableNetworks() {
for _, n := range daemon.GetNetworks() {
if !n.Info().Attachable() {
continue
}
for _, ep := range n.Endpoints() {
epInfo := ep.Info()
if epInfo == nil {
continue
}
sb := epInfo.Sandbox()
if sb == nil {
continue
}
containerID := sb.ContainerID()
if err := daemon.DisconnectContainerFromNetwork(containerID, n.ID(), true); err != nil {
logrus.Warnf("Failed to disconnect container %s from swarm network %s on cluster leave: %v",
containerID, n.Name(), err)
}
}
if err := daemon.DeleteManagedNetwork(n.ID()); err != nil {
logrus.Warnf("Failed to remove swarm network %s on cluster leave: %v", n.Name(), err)
}
}
}
27 changes: 27 additions & 0 deletions integration-cli/docker_cli_swarm_test.go
Expand Up @@ -358,6 +358,33 @@ func (s *DockerSwarmSuite) TestOverlayAttachable(c *check.C) {
c.Assert(strings.TrimSpace(out), checker.Equals, "true")
}

func (s *DockerSwarmSuite) TestOverlayAttachableOnSwarmLeave(c *check.C) {
d := s.AddDaemon(c, true, true)

// Create an attachable swarm network
nwName := "attovl"
out, err := d.Cmd("network", "create", "-d", "overlay", "--attachable", nwName)
c.Assert(err, checker.IsNil, check.Commentf(out))

// Connect a container to the network
out, err = d.Cmd("run", "-d", "--network", nwName, "--name", "c1", "busybox", "top")
c.Assert(err, checker.IsNil, check.Commentf(out))

// Leave the swarm
err = d.Leave(true)
c.Assert(err, checker.IsNil)

// Check the container is disconnected
out, err = d.Cmd("inspect", "c1", "--format", "{{.NetworkSettings.Networks."+nwName+"}}")
c.Assert(err, checker.IsNil)
c.Assert(strings.TrimSpace(out), checker.Equals, "<no value>")

// Check the network is gone
out, err = d.Cmd("network", "ls", "--format", "{{.Name}}")
c.Assert(err, checker.IsNil)
c.Assert(out, checker.Not(checker.Contains), nwName)
}

func (s *DockerSwarmSuite) TestSwarmRemoveInternalNetwork(c *check.C) {
d := s.AddDaemon(c, true, true)

Expand Down