mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Fixed support for docker compose by allowing connect/disconnect on stopped containers
Signed-off-by: msabansal <sabansal@microsoft.com>
This commit is contained in:
parent
2a3205d7b7
commit
50f02b585c
4 changed files with 95 additions and 110 deletions
|
@ -6,6 +6,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
@ -907,3 +908,83 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) {
|
||||||
daemon.LogNetworkEventWithAttributes(nw, "disconnect", attributes)
|
daemon.LogNetworkEventWithAttributes(nw, "disconnect", attributes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func errRemovalContainer(containerID string) error {
|
||||||
|
return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectToNetwork connects a container to a network
|
||||||
|
func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
|
||||||
|
if endpointConfig == nil {
|
||||||
|
endpointConfig = &networktypes.EndpointSettings{}
|
||||||
|
}
|
||||||
|
if !container.Running {
|
||||||
|
if container.RemovalInProgress || container.Dead {
|
||||||
|
return errRemovalContainer(container.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := daemon.FindNetwork(idOrName)
|
||||||
|
if err == nil && n != nil {
|
||||||
|
if err := daemon.updateNetworkConfig(container, n, endpointConfig, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
container.NetworkSettings.Networks[idOrName] = &network.EndpointSettings{
|
||||||
|
EndpointSettings: endpointConfig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if !daemon.isNetworkHotPluggable() {
|
||||||
|
return fmt.Errorf(runtime.GOOS + " does not support connecting a running container to a network")
|
||||||
|
} else {
|
||||||
|
if err := daemon.connectToNetwork(container, idOrName, endpointConfig, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := container.ToDiskLocking(); err != nil {
|
||||||
|
return fmt.Errorf("Error saving container to disk: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisconnectFromNetwork disconnects container from network n.
|
||||||
|
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
|
||||||
|
n, err := daemon.FindNetwork(networkName)
|
||||||
|
if !container.Running || (err != nil && force) {
|
||||||
|
if container.RemovalInProgress || container.Dead {
|
||||||
|
return errRemovalContainer(container.ID)
|
||||||
|
}
|
||||||
|
// In case networkName is resolved we will use n.Name()
|
||||||
|
// this will cover the case where network id is passed.
|
||||||
|
if n != nil {
|
||||||
|
networkName = n.Name()
|
||||||
|
}
|
||||||
|
if _, ok := container.NetworkSettings.Networks[networkName]; !ok {
|
||||||
|
return fmt.Errorf("container %s is not connected to the network %s", container.ID, networkName)
|
||||||
|
}
|
||||||
|
delete(container.NetworkSettings.Networks, networkName)
|
||||||
|
} else if err == nil && !daemon.isNetworkHotPluggable() {
|
||||||
|
return fmt.Errorf(runtime.GOOS + " does not support connecting a running container to a network")
|
||||||
|
} else if err == nil {
|
||||||
|
if container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() {
|
||||||
|
return runconfig.ErrConflictHostNetwork
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := daemon.disconnectFromNetwork(container, n, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := container.ToDiskLocking(); err != nil {
|
||||||
|
return fmt.Errorf("Error saving container to disk: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n != nil {
|
||||||
|
attributes := map[string]string{
|
||||||
|
"container": container.ID,
|
||||||
|
}
|
||||||
|
daemon.LogNetworkEventWithAttributes(n, "disconnect", attributes)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -2,32 +2,17 @@
|
||||||
|
|
||||||
package daemon
|
package daemon
|
||||||
|
|
||||||
import (
|
import "github.com/docker/docker/container"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
networktypes "github.com/docker/docker/api/types/network"
|
|
||||||
"github.com/docker/docker/container"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
|
func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnectToNetwork connects a container to a network
|
|
||||||
func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
|
|
||||||
return fmt.Errorf("Solaris does not support connecting a running container to a network")
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSize returns real size & virtual size
|
// getSize returns real size & virtual size
|
||||||
func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisconnectFromNetwork disconnects a container from the network
|
|
||||||
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
|
|
||||||
return fmt.Errorf("Solaris does not support disconnecting a running container from a network")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
|
func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -47,3 +32,7 @@ func detachMounted(path string) error {
|
||||||
func isLinkable(child *container.Container) bool {
|
func isLinkable(child *container.Container) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (daemon *Daemon) isNetworkHotPluggable() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -13,10 +13,8 @@ import (
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
containertypes "github.com/docker/docker/api/types/container"
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
networktypes "github.com/docker/docker/api/types/network"
|
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
"github.com/docker/docker/daemon/links"
|
"github.com/docker/docker/daemon/links"
|
||||||
"github.com/docker/docker/daemon/network"
|
|
||||||
"github.com/docker/docker/pkg/fileutils"
|
"github.com/docker/docker/pkg/fileutils"
|
||||||
"github.com/docker/docker/pkg/idtools"
|
"github.com/docker/docker/pkg/idtools"
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
|
@ -99,78 +97,6 @@ func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
||||||
return sizeRw, sizeRootfs
|
return sizeRw, sizeRootfs
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnectToNetwork connects a container to a network
|
|
||||||
func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
|
|
||||||
if endpointConfig == nil {
|
|
||||||
endpointConfig = &networktypes.EndpointSettings{}
|
|
||||||
}
|
|
||||||
if !container.Running {
|
|
||||||
if container.RemovalInProgress || container.Dead {
|
|
||||||
return errRemovalContainer(container.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := daemon.FindNetwork(idOrName)
|
|
||||||
if err == nil && n != nil {
|
|
||||||
if err := daemon.updateNetworkConfig(container, n, endpointConfig, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
container.NetworkSettings.Networks[idOrName] = &network.EndpointSettings{
|
|
||||||
EndpointSettings: endpointConfig,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := daemon.connectToNetwork(container, idOrName, endpointConfig, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := container.ToDiskLocking(); err != nil {
|
|
||||||
return fmt.Errorf("Error saving container to disk: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisconnectFromNetwork disconnects container from network n.
|
|
||||||
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
|
|
||||||
n, err := daemon.FindNetwork(networkName)
|
|
||||||
if !container.Running || (err != nil && force) {
|
|
||||||
if container.RemovalInProgress || container.Dead {
|
|
||||||
return errRemovalContainer(container.ID)
|
|
||||||
}
|
|
||||||
// In case networkName is resolved we will use n.Name()
|
|
||||||
// this will cover the case where network id is passed.
|
|
||||||
if n != nil {
|
|
||||||
networkName = n.Name()
|
|
||||||
}
|
|
||||||
if _, ok := container.NetworkSettings.Networks[networkName]; !ok {
|
|
||||||
return fmt.Errorf("container %s is not connected to the network %s", container.ID, networkName)
|
|
||||||
}
|
|
||||||
delete(container.NetworkSettings.Networks, networkName)
|
|
||||||
} else if err == nil {
|
|
||||||
if container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() {
|
|
||||||
return runconfig.ErrConflictHostNetwork
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := daemon.disconnectFromNetwork(container, n, false); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := container.ToDiskLocking(); err != nil {
|
|
||||||
return fmt.Errorf("Error saving container to disk: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n != nil {
|
|
||||||
attributes := map[string]string{
|
|
||||||
"container": container.ID,
|
|
||||||
}
|
|
||||||
daemon.LogNetworkEventWithAttributes(n, "disconnect", attributes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (daemon *Daemon) getIpcContainer(container *container.Container) (*container.Container, error) {
|
func (daemon *Daemon) getIpcContainer(container *container.Container) (*container.Container, error) {
|
||||||
containerID := container.HostConfig.IpcMode.Container()
|
containerID := container.HostConfig.IpcMode.Container()
|
||||||
c, err := daemon.GetContainer(containerID)
|
c, err := daemon.GetContainer(containerID)
|
||||||
|
@ -397,10 +323,10 @@ func isLinkable(child *container.Container) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func errRemovalContainer(containerID string) error {
|
|
||||||
return fmt.Errorf("Container %s is marked for removal and cannot be connected or disconnected to the network", containerID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func enableIPOnPredefinedNetwork() bool {
|
func enableIPOnPredefinedNetwork() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (daemon *Daemon) isNetworkHotPluggable() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -2,27 +2,12 @@
|
||||||
|
|
||||||
package daemon
|
package daemon
|
||||||
|
|
||||||
import (
|
import "github.com/docker/docker/container"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
networktypes "github.com/docker/docker/api/types/network"
|
|
||||||
"github.com/docker/docker/container"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
|
func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnectToNetwork connects a container to a network
|
|
||||||
func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
|
|
||||||
return fmt.Errorf("Windows does not support connecting a running container to a network")
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisconnectFromNetwork disconnects container from a network.
|
|
||||||
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, networkName string, force bool) error {
|
|
||||||
return fmt.Errorf("Windows does not support disconnecting a running container from a network")
|
|
||||||
}
|
|
||||||
|
|
||||||
// getSize returns real size & virtual size
|
// getSize returns real size & virtual size
|
||||||
func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
||||||
// TODO Windows
|
// TODO Windows
|
||||||
|
@ -58,3 +43,7 @@ func isLinkable(child *container.Container) bool {
|
||||||
func enableIPOnPredefinedNetwork() bool {
|
func enableIPOnPredefinedNetwork() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (daemon *Daemon) isNetworkHotPluggable() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue