Browse Source

Fix removing containers on leaving from pending state

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 826f6f07031abc4dea6f71ed69d33a4e0789ee11)
Tonis Tiigi 9 years ago
parent
commit
efc10a92ef
2 changed files with 31 additions and 4 deletions
  1. 5 4
      daemon/cluster/cluster.go
  2. 26 0
      integration-cli/docker_api_swarm_test.go

+ 5 - 4
daemon/cluster/cluster.go

@@ -389,10 +389,11 @@ func (c *Cluster) Leave(force bool) error {
 	if err := node.Stop(ctx); err != nil && !strings.Contains(err.Error(), "context canceled") {
 	if err := node.Stop(ctx); err != nil && !strings.Contains(err.Error(), "context canceled") {
 		return err
 		return err
 	}
 	}
-	nodeID := node.NodeID()
-	for _, id := range c.config.Backend.ListContainersForNode(nodeID) {
-		if err := c.config.Backend.ContainerRm(id, &apitypes.ContainerRmConfig{ForceRemove: true}); err != nil {
-			logrus.Errorf("error removing %v: %v", id, err)
+	if nodeID := node.NodeID(); nodeID != "" {
+		for _, id := range c.config.Backend.ListContainersForNode(nodeID) {
+			if err := c.config.Backend.ContainerRm(id, &apitypes.ContainerRmConfig{ForceRemove: true}); err != nil {
+				logrus.Errorf("error removing %v: %v", id, err)
+			}
 		}
 		}
 	}
 	}
 	c.Lock()
 	c.Lock()

+ 26 - 0
integration-cli/docker_api_swarm_test.go

@@ -552,6 +552,32 @@ func (s *DockerSwarmSuite) TestApiSwarmLeaveRemovesContainer(c *check.C) {
 	c.Assert(id, checker.HasPrefix, strings.TrimSpace(id2))
 	c.Assert(id, checker.HasPrefix, strings.TrimSpace(id2))
 }
 }
 
 
+// #23629
+func (s *DockerSwarmSuite) TestApiSwarmLeaveOnPendingJoin(c *check.C) {
+	s.AddDaemon(c, true, true)
+	d2 := s.AddDaemon(c, false, false)
+
+	id, err := d2.Cmd("run", "-d", "busybox", "top")
+	c.Assert(err, checker.IsNil)
+	id = strings.TrimSpace(id)
+
+	go d2.Join("nosuchhost:1234", "", "", false) // will block on pending state
+
+	time.Sleep(1 * time.Second)
+
+	info, err := d2.info()
+	c.Assert(err, checker.IsNil)
+	c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStatePending)
+
+	c.Assert(d2.Leave(true), checker.IsNil)
+
+	waitAndAssert(c, defaultReconciliationTimeout, d2.checkActiveContainerCount, checker.Equals, 1)
+
+	id2, err := d2.Cmd("ps", "-q")
+	c.Assert(err, checker.IsNil)
+	c.Assert(id, checker.HasPrefix, strings.TrimSpace(id2))
+}
+
 func (s *DockerSwarmSuite) TestApiSwarmManagerRestore(c *check.C) {
 func (s *DockerSwarmSuite) TestApiSwarmManagerRestore(c *check.C) {
 	d1 := s.AddDaemon(c, true, true)
 	d1 := s.AddDaemon(c, true, true)