Browse code

Fixed support for docker compose by allowing connect/disconnect on stopped containers

Signed-off-by: msabansal <sabansal@microsoft.com>

msabansal authored on 2016/09/22 04:02:20
Showing 4 changed files
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"net"
7 7
 	"os"
8 8
 	"path"
9
+	"runtime"
9 10
 	"strings"
10 11
 
11 12
 	"github.com/Sirupsen/logrus"
... ...
@@ -907,3 +908,83 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) {
907 907
 		daemon.LogNetworkEventWithAttributes(nw, "disconnect", attributes)
908 908
 	}
909 909
 }
910
+
911
+func errRemovalContainer(containerID string) error {
912
+	return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
913
+}
914
+
915
+// ConnectToNetwork connects a container to a network
916
+func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
917
+	if endpointConfig == nil {
918
+		endpointConfig = &networktypes.EndpointSettings{}
919
+	}
920
+	if !container.Running {
921
+		if container.RemovalInProgress || container.Dead {
922
+			return errRemovalContainer(container.ID)
923
+		}
924
+
925
+		n, err := daemon.FindNetwork(idOrName)
926
+		if err == nil && n != nil {
927
+			if err := daemon.updateNetworkConfig(container, n, endpointConfig, true); err != nil {
928
+				return err
929
+			}
930
+		} else {
931
+			container.NetworkSettings.Networks[idOrName] = &network.EndpointSettings{
932
+				EndpointSettings: endpointConfig,
933
+			}
934
+		}
935
+	} else if !daemon.isNetworkHotPluggable() {
936
+		return fmt.Errorf(runtime.GOOS + " does not support connecting a running container to a network")
937
+	} else {
938
+		if err := daemon.connectToNetwork(container, idOrName, endpointConfig, true); err != nil {
939
+			return err
940
+		}
941
+	}
942
+	if err := container.ToDiskLocking(); err != nil {
943
+		return fmt.Errorf("Error saving container to disk: %v", err)
944
+	}
945
+	return nil
946
+}
947
+
948
+// DisconnectFromNetwork disconnects container from network n.
949
+func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
950
+	n, err := daemon.FindNetwork(networkName)
951
+	if !container.Running || (err != nil && force) {
952
+		if container.RemovalInProgress || container.Dead {
953
+			return errRemovalContainer(container.ID)
954
+		}
955
+		// In case networkName is resolved we will use n.Name()
956
+		// this will cover the case where network id is passed.
957
+		if n != nil {
958
+			networkName = n.Name()
959
+		}
960
+		if _, ok := container.NetworkSettings.Networks[networkName]; !ok {
961
+			return fmt.Errorf("container %s is not connected to the network %s", container.ID, networkName)
962
+		}
963
+		delete(container.NetworkSettings.Networks, networkName)
964
+	} else if err == nil && !daemon.isNetworkHotPluggable() {
965
+		return fmt.Errorf(runtime.GOOS + " does not support connecting a running container to a network")
966
+	} else if err == nil {
967
+		if container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() {
968
+			return runconfig.ErrConflictHostNetwork
969
+		}
970
+
971
+		if err := daemon.disconnectFromNetwork(container, n, false); err != nil {
972
+			return err
973
+		}
974
+	} else {
975
+		return err
976
+	}
977
+
978
+	if err := container.ToDiskLocking(); err != nil {
979
+		return fmt.Errorf("Error saving container to disk: %v", err)
980
+	}
981
+
982
+	if n != nil {
983
+		attributes := map[string]string{
984
+			"container": container.ID,
985
+		}
986
+		daemon.LogNetworkEventWithAttributes(n, "disconnect", attributes)
987
+	}
988
+	return nil
989
+}
... ...
@@ -2,32 +2,17 @@
2 2
 
3 3
 package daemon
4 4
 
5
-import (
6
-	"fmt"
7
-
8
-	networktypes "github.com/docker/docker/api/types/network"
9
-	"github.com/docker/docker/container"
10
-)
5
+import "github.com/docker/docker/container"
11 6
 
12 7
 func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
13 8
 	return nil, nil
14 9
 }
15 10
 
16
-// ConnectToNetwork connects a container to a network
17
-func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
18
-	return fmt.Errorf("Solaris does not support connecting a running container to a network")
19
-}
20
-
21 11
 // getSize returns real size & virtual size
22 12
 func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
23 13
 	return 0, 0
24 14
 }
25 15
 
26
-// DisconnectFromNetwork disconnects a container from the network
27
-func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
28
-	return fmt.Errorf("Solaris does not support disconnecting a running container from a network")
29
-}
30
-
31 16
 func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
32 17
 	return nil
33 18
 }
... ...
@@ -47,3 +32,7 @@ func detachMounted(path string) error {
47 47
 func isLinkable(child *container.Container) bool {
48 48
 	return false
49 49
 }
50
+
51
+func (daemon *Daemon) isNetworkHotPluggable() bool {
52
+	return false
53
+}
... ...
@@ -13,10 +13,8 @@ import (
13 13
 
14 14
 	"github.com/Sirupsen/logrus"
15 15
 	containertypes "github.com/docker/docker/api/types/container"
16
-	networktypes "github.com/docker/docker/api/types/network"
17 16
 	"github.com/docker/docker/container"
18 17
 	"github.com/docker/docker/daemon/links"
19
-	"github.com/docker/docker/daemon/network"
20 18
 	"github.com/docker/docker/pkg/fileutils"
21 19
 	"github.com/docker/docker/pkg/idtools"
22 20
 	"github.com/docker/docker/pkg/mount"
... ...
@@ -99,78 +97,6 @@ func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
99 99
 	return sizeRw, sizeRootfs
100 100
 }
101 101
 
102
-// ConnectToNetwork connects a container to a network
103
-func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
104
-	if endpointConfig == nil {
105
-		endpointConfig = &networktypes.EndpointSettings{}
106
-	}
107
-	if !container.Running {
108
-		if container.RemovalInProgress || container.Dead {
109
-			return errRemovalContainer(container.ID)
110
-		}
111
-
112
-		n, err := daemon.FindNetwork(idOrName)
113
-		if err == nil && n != nil {
114
-			if err := daemon.updateNetworkConfig(container, n, endpointConfig, true); err != nil {
115
-				return err
116
-			}
117
-		} else {
118
-			container.NetworkSettings.Networks[idOrName] = &network.EndpointSettings{
119
-				EndpointSettings: endpointConfig,
120
-			}
121
-		}
122
-	} else {
123
-		if err := daemon.connectToNetwork(container, idOrName, endpointConfig, true); err != nil {
124
-			return err
125
-		}
126
-	}
127
-	if err := container.ToDiskLocking(); err != nil {
128
-		return fmt.Errorf("Error saving container to disk: %v", err)
129
-	}
130
-	return nil
131
-}
132
-
133
-// DisconnectFromNetwork disconnects container from network n.
134
-func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
135
-	n, err := daemon.FindNetwork(networkName)
136
-	if !container.Running || (err != nil && force) {
137
-		if container.RemovalInProgress || container.Dead {
138
-			return errRemovalContainer(container.ID)
139
-		}
140
-		// In case networkName is resolved we will use n.Name()
141
-		// this will cover the case where network id is passed.
142
-		if n != nil {
143
-			networkName = n.Name()
144
-		}
145
-		if _, ok := container.NetworkSettings.Networks[networkName]; !ok {
146
-			return fmt.Errorf("container %s is not connected to the network %s", container.ID, networkName)
147
-		}
148
-		delete(container.NetworkSettings.Networks, networkName)
149
-	} else if err == nil {
150
-		if container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() {
151
-			return runconfig.ErrConflictHostNetwork
152
-		}
153
-
154
-		if err := daemon.disconnectFromNetwork(container, n, false); err != nil {
155
-			return err
156
-		}
157
-	} else {
158
-		return err
159
-	}
160
-
161
-	if err := container.ToDiskLocking(); err != nil {
162
-		return fmt.Errorf("Error saving container to disk: %v", err)
163
-	}
164
-
165
-	if n != nil {
166
-		attributes := map[string]string{
167
-			"container": container.ID,
168
-		}
169
-		daemon.LogNetworkEventWithAttributes(n, "disconnect", attributes)
170
-	}
171
-	return nil
172
-}
173
-
174 102
 func (daemon *Daemon) getIpcContainer(container *container.Container) (*container.Container, error) {
175 103
 	containerID := container.HostConfig.IpcMode.Container()
176 104
 	c, err := daemon.GetContainer(containerID)
... ...
@@ -397,10 +323,10 @@ func isLinkable(child *container.Container) bool {
397 397
 	return ok
398 398
 }
399 399
 
400
-func errRemovalContainer(containerID string) error {
401
-	return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
402
-}
403
-
404 400
 func enableIPOnPredefinedNetwork() bool {
405 401
 	return false
406 402
 }
403
+
404
+func (daemon *Daemon) isNetworkHotPluggable() bool {
405
+	return true
406
+}
... ...
@@ -2,27 +2,12 @@
2 2
 
3 3
 package daemon
4 4
 
5
-import (
6
-	"fmt"
7
-
8
-	networktypes "github.com/docker/docker/api/types/network"
9
-	"github.com/docker/docker/container"
10
-)
5
+import "github.com/docker/docker/container"
11 6
 
12 7
 func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
13 8
 	return nil, nil
14 9
 }
15 10
 
16
-// ConnectToNetwork connects a container to a network
17
-func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
18
-	return fmt.Errorf("Windows does not support connecting a running container to a network")
19
-}
20
-
21
-// DisconnectFromNetwork disconnects container from a network.
22
-func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
23
-	return fmt.Errorf("Windows does not support disconnecting a running container from a network")
24
-}
25
-
26 11
 // getSize returns real size & virtual size
27 12
 func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
28 13
 	// TODO Windows
... ...
@@ -58,3 +43,7 @@ func isLinkable(child *container.Container) bool {
58 58
 func enableIPOnPredefinedNetwork() bool {
59 59
 	return true
60 60
 }
61
+
62
+func (daemon *Daemon) isNetworkHotPluggable() bool {
63
+	return false
64
+}