ソースを参照

Fix docker startup failure due to dangling endpoints

Fixes docker startup failure due to dangling endpoints
which makes docker to not come up.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 9 年 前
コミット
8adfc7e2d2
1 ファイル変更38 行追加36 行削除
  1. 38 36
      daemon/container_unix.go

+ 38 - 36
daemon/container_unix.go

@@ -914,6 +914,8 @@ func (container *Container) ConnectToNetwork(idOrName string) error {
 }
 }
 
 
 func (container *Container) connectToNetwork(idOrName string, updateSettings bool) error {
 func (container *Container) connectToNetwork(idOrName string, updateSettings bool) error {
+	var err error
+
 	if container.hostConfig.NetworkMode.IsContainer() {
 	if container.hostConfig.NetworkMode.IsContainer() {
 		return runconfig.ErrConflictSharedNetwork
 		return runconfig.ErrConflictSharedNetwork
 	}
 	}
@@ -938,22 +940,31 @@ func (container *Container) connectToNetwork(idOrName string, updateSettings boo
 	}
 	}
 
 
 	ep, err := container.getEndpointInNetwork(n)
 	ep, err := container.getEndpointInNetwork(n)
-	if err != nil {
-		if _, ok := err.(libnetwork.ErrNoSuchEndpoint); !ok {
-			return err
-		}
+	if err == nil {
+		return fmt.Errorf("container already connected to network %s", idOrName)
+	}
 
 
-		createOptions, err := container.buildCreateEndpointOptions()
-		if err != nil {
-			return err
-		}
+	if _, ok := err.(libnetwork.ErrNoSuchEndpoint); !ok {
+		return err
+	}
+
+	createOptions, err := container.buildCreateEndpointOptions()
+	if err != nil {
+		return err
+	}
 
 
-		endpointName := strings.TrimPrefix(container.Name, "/")
-		ep, err = n.CreateEndpoint(endpointName, createOptions...)
+	endpointName := strings.TrimPrefix(container.Name, "/")
+	ep, err = n.CreateEndpoint(endpointName, createOptions...)
+	if err != nil {
+		return err
+	}
+	defer func() {
 		if err != nil {
 		if err != nil {
-			return err
+			if e := ep.Delete(); e != nil {
+				logrus.Warnf("Could not rollback container connection to network %s", idOrName)
+			}
 		}
 		}
-	}
+	}()
 
 
 	if err := container.updateEndpointNetworkSettings(n, ep); err != nil {
 	if err := container.updateEndpointNetworkSettings(n, ep); err != nil {
 		return err
 		return err
@@ -976,9 +987,9 @@ func (container *Container) connectToNetwork(idOrName string, updateSettings boo
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-	}
 
 
-	container.updateSandboxNetworkSettings(sb)
+		container.updateSandboxNetworkSettings(sb)
+	}
 
 
 	if err := ep.Join(sb); err != nil {
 	if err := ep.Join(sb); err != nil {
 		return err
 		return err
@@ -1124,14 +1135,6 @@ func (container *Container) releaseNetwork() {
 		return
 		return
 	}
 	}
 
 
-	for _, ns := range networks {
-		n, err := container.daemon.FindNetwork(ns)
-		if err != nil {
-			continue
-		}
-		container.disconnectFromNetwork(n, false)
-	}
-
 	if err := sb.Delete(); err != nil {
 	if err := sb.Delete(); err != nil {
 		logrus.Errorf("Error deleting sandbox id %s for container %s: %v", sid, container.ID, err)
 		logrus.Errorf("Error deleting sandbox id %s for container %s: %v", sid, container.ID, err)
 	}
 	}
@@ -1143,10 +1146,10 @@ func (container *Container) DisconnectFromNetwork(n libnetwork.Network) error {
 		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
 		return derr.ErrorCodeNotRunning.WithArgs(container.ID)
 	}
 	}
 
 
-	return container.disconnectFromNetwork(n, true)
+	return container.disconnectFromNetwork(n)
 }
 }
 
 
-func (container *Container) disconnectFromNetwork(n libnetwork.Network, updateSettings bool) error {
+func (container *Container) disconnectFromNetwork(n libnetwork.Network) error {
 	var (
 	var (
 		ep   libnetwork.Endpoint
 		ep   libnetwork.Endpoint
 		sbox libnetwork.Sandbox
 		sbox libnetwork.Sandbox
@@ -1176,20 +1179,19 @@ func (container *Container) disconnectFromNetwork(n libnetwork.Network, updateSe
 		return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err)
 		return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err)
 	}
 	}
 
 
-	if updateSettings {
-		networks := container.NetworkSettings.Networks
-		for i, s := range networks {
-			sn, err := container.daemon.FindNetwork(s)
-			if err != nil {
-				continue
-			}
-			if sn.Name() == n.Name() {
-				networks = append(networks[:i], networks[i+1:]...)
-				container.NetworkSettings.Networks = networks
-				break
-			}
+	networks := container.NetworkSettings.Networks
+	for i, s := range networks {
+		sn, err := container.daemon.FindNetwork(s)
+		if err != nil {
+			continue
+		}
+		if sn.Name() == n.Name() {
+			networks = append(networks[:i], networks[i+1:]...)
+			container.NetworkSettings.Networks = networks
+			break
 		}
 		}
 	}
 	}
+
 	return nil
 	return nil
 }
 }