diff --git a/daemon/container_windows.go b/daemon/container_windows.go index d471034d0d..bed2d52010 100644 --- a/daemon/container_windows.go +++ b/daemon/container_windows.go @@ -67,22 +67,17 @@ func populateCommand(c *Container, env []string) error { Interface: nil, } - // TODO Windows. Appropriate network mode (will refactor as part of - // libnetwork. For now, even through bridge not used, let it succeed to - // allow the Windows daemon to limp during its bring-up parts := strings.SplitN(string(c.hostConfig.NetworkMode), ":", 2) switch parts[0] { + case "none": - case "bridge", "": // empty string to support existing containers + case "default", "": // empty string to support existing containers if !c.Config.NetworkDisabled { network := c.NetworkSettings en.Interface = &execdriver.NetworkInterface{ - Bridge: network.Bridge, MacAddress: network.MacAddress, } } - case "host", "container": - return fmt.Errorf("unsupported network mode: %s", c.hostConfig.NetworkMode) default: return fmt.Errorf("invalid network mode: %s", c.hostConfig.NetworkMode) } diff --git a/daemon/daemon.go b/daemon/daemon.go index e2c373988c..92d7de1aa4 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -29,7 +29,6 @@ import ( "github.com/docker/docker/pkg/graphdb" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/namesgenerator" - "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/sysinfo" "github.com/docker/docker/pkg/system" @@ -553,43 +552,6 @@ func (daemon *Daemon) RegisterLink(parent, child *Container, alias string) error return nil } -func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error { - if hostConfig != nil && hostConfig.Links != nil { - for _, l := range hostConfig.Links { - name, alias, err := parsers.ParseLink(l) - if err != nil { - return err - } - child, err := daemon.Get(name) - if err != nil { - //An error from daemon.Get() means this name could not be found - return fmt.Errorf("Could not get container for %s", name) - } - for child.hostConfig.NetworkMode.IsContainer() { - parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2) - child, err = daemon.Get(parts[1]) - if err != nil { - return fmt.Errorf("Could not get container for %s", parts[1]) - } - } - if child.hostConfig.NetworkMode.IsHost() { - return runconfig.ErrConflictHostNetworkAndLinks - } - if err := daemon.RegisterLink(container, child, alias); err != nil { - return err - } - } - - // After we load all the links into the daemon - // set them to nil on the hostconfig - hostConfig.Links = nil - if err := container.WriteHostConfig(); err != nil { - return err - } - } - return nil -} - func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemon, err error) { setDefaultMtu(config) diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 2fcc6a77ba..99007824b4 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -17,6 +17,7 @@ import ( "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/fileutils" + "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers/kernel" "github.com/docker/docker/pkg/system" "github.com/docker/docker/runconfig" @@ -460,3 +461,44 @@ func setupInitLayer(initLayer string) error { func (daemon *Daemon) NetworkApiRouter() func(w http.ResponseWriter, req *http.Request) { return nwapi.NewHTTPHandler(daemon.netController) } + +func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error { + + if hostConfig == nil || hostConfig.Links == nil { + return nil + } + + for _, l := range hostConfig.Links { + name, alias, err := parsers.ParseLink(l) + if err != nil { + return err + } + child, err := daemon.Get(name) + if err != nil { + //An error from daemon.Get() means this name could not be found + return fmt.Errorf("Could not get container for %s", name) + } + for child.hostConfig.NetworkMode.IsContainer() { + parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2) + child, err = daemon.Get(parts[1]) + if err != nil { + return fmt.Errorf("Could not get container for %s", parts[1]) + } + } + if child.hostConfig.NetworkMode.IsHost() { + return runconfig.ErrConflictHostNetworkAndLinks + } + if err := daemon.RegisterLink(container, child, alias); err != nil { + return err + } + } + + // After we load all the links into the daemon + // set them to nil on the hostconfig + hostConfig.Links = nil + if err := container.WriteHostConfig(); err != nil { + return err + } + + return nil +} diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index 05d7bd2d1f..18a2f08b35 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -8,6 +8,7 @@ import ( "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/pkg/archive" + "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/runconfig" "github.com/docker/libnetwork" ) @@ -103,3 +104,35 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error) // TODO Windows return nil, nil } + +func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error { + // TODO Windows. Factored out for network modes. There may be more + // refactoring required here. + + if hostConfig == nil || hostConfig.Links == nil { + return nil + } + + for _, l := range hostConfig.Links { + name, alias, err := parsers.ParseLink(l) + if err != nil { + return err + } + child, err := daemon.Get(name) + if err != nil { + //An error from daemon.Get() means this name could not be found + return fmt.Errorf("Could not get container for %s", name) + } + if err := daemon.RegisterLink(container, child, alias); err != nil { + return err + } + } + + // After we load all the links into the daemon + // set them to nil on the hostconfig + hostConfig.Links = nil + if err := container.WriteHostConfig(); err != nil { + return err + } + return nil +} diff --git a/runconfig/hostconfig.go b/runconfig/hostconfig.go index 4c388d7a31..5df9fa467a 100644 --- a/runconfig/hostconfig.go +++ b/runconfig/hostconfig.go @@ -16,51 +16,6 @@ type KeyValuePair struct { type NetworkMode string -// IsPrivate indicates whether container use it's private network stack -func (n NetworkMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -func (n NetworkMode) IsDefault() bool { - return n == "default" -} - -func DefaultDaemonNetworkMode() NetworkMode { - return NetworkMode("bridge") -} - -func (n NetworkMode) NetworkName() string { - if n.IsBridge() { - return "bridge" - } else if n.IsHost() { - return "host" - } else if n.IsContainer() { - return "container" - } else if n.IsNone() { - return "none" - } else if n.IsDefault() { - return "default" - } - return "" -} - -func (n NetworkMode) IsBridge() bool { - return n == "bridge" -} - -func (n NetworkMode) IsHost() bool { - return n == "host" -} - -func (n NetworkMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -func (n NetworkMode) IsNone() bool { - return n == "none" -} - type IpcMode string // IsPrivate indicates whether container use it's private ipc stack diff --git a/runconfig/hostconfig_unix.go b/runconfig/hostconfig_unix.go new file mode 100644 index 0000000000..af470a8b3d --- /dev/null +++ b/runconfig/hostconfig_unix.go @@ -0,0 +1,52 @@ +// +build !windows + +package runconfig + +import ( + "strings" +) + +// IsPrivate indicates whether container use it's private network stack +func (n NetworkMode) IsPrivate() bool { + return !(n.IsHost() || n.IsContainer()) +} + +func (n NetworkMode) IsDefault() bool { + return n == "default" +} + +func DefaultDaemonNetworkMode() NetworkMode { + return NetworkMode("bridge") +} + +func (n NetworkMode) NetworkName() string { + if n.IsBridge() { + return "bridge" + } else if n.IsHost() { + return "host" + } else if n.IsContainer() { + return "container" + } else if n.IsNone() { + return "none" + } else if n.IsDefault() { + return "default" + } + return "" +} + +func (n NetworkMode) IsBridge() bool { + return n == "bridge" +} + +func (n NetworkMode) IsHost() bool { + return n == "host" +} + +func (n NetworkMode) IsContainer() bool { + parts := strings.SplitN(string(n), ":", 2) + return len(parts) > 1 && parts[0] == "container" +} + +func (n NetworkMode) IsNone() bool { + return n == "none" +} diff --git a/runconfig/hostconfig_windows.go b/runconfig/hostconfig_windows.go new file mode 100644 index 0000000000..90eaf7ef1c --- /dev/null +++ b/runconfig/hostconfig_windows.go @@ -0,0 +1,18 @@ +// +build !windows + +package runconfig + +func (n NetworkMode) IsDefault() bool { + return n == "default" +} + +func DefaultDaemonNetworkMode() NetworkMode { + return NetworkMode("default") +} + +func (n NetworkMode) NetworkName() string { + if n.IsDefault() { + return "default" + } + return "" +} diff --git a/runconfig/parse.go b/runconfig/parse.go index 87bf4ac676..11884b4a6a 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -24,6 +24,19 @@ var ( ErrConflictNetworkExposePorts = fmt.Errorf("Conflicting options: --expose and the network mode (--expose)") ) +// validateNM is the set of fields passed to validateNetMode() +type validateNM struct { + netMode NetworkMode + flHostname *string + flLinks opts.ListOpts + flDns opts.ListOpts + flExtraHosts opts.ListOpts + flMacAddress *string + flPublish opts.ListOpts + flPublishAll *bool + flExpose opts.ListOpts +} + func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSet, error) { var ( // FIXME: use utils.ListOpts for attach and volumes? @@ -121,37 +134,22 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe return nil, nil, cmd, fmt.Errorf("--net: invalid net mode: %v", err) } - if (netMode.IsHost() || netMode.IsContainer()) && *flHostname != "" { - return nil, nil, cmd, ErrConflictNetworkHostname + vals := validateNM{ + netMode: netMode, + flHostname: flHostname, + flLinks: flLinks, + flDns: flDns, + flExtraHosts: flExtraHosts, + flMacAddress: flMacAddress, + flPublish: flPublish, + flPublishAll: flPublishAll, + flExpose: flExpose, } - if netMode.IsHost() && flLinks.Len() > 0 { - return nil, nil, cmd, ErrConflictHostNetworkAndLinks + if err := validateNetMode(&vals); err != nil { + return nil, nil, cmd, err } - if netMode.IsContainer() && flLinks.Len() > 0 { - return nil, nil, cmd, ErrConflictContainerNetworkAndLinks - } - - if (netMode.IsHost() || netMode.IsContainer()) && flDns.Len() > 0 { - return nil, nil, cmd, ErrConflictNetworkAndDns - } - - if (netMode.IsContainer() || netMode.IsHost()) && flExtraHosts.Len() > 0 { - return nil, nil, cmd, ErrConflictNetworkHosts - } - - if (netMode.IsContainer() || netMode.IsHost()) && *flMacAddress != "" { - return nil, nil, cmd, ErrConflictContainerNetworkAndMac - } - - if netMode.IsContainer() && (flPublish.Len() > 0 || *flPublishAll == true) { - return nil, nil, cmd, ErrConflictNetworkPublishPorts - } - - if netMode.IsContainer() && flExpose.Len() > 0 { - return nil, nil, cmd, ErrConflictNetworkExposePorts - } // Validate the input mac address if *flMacAddress != "" { if _, err := opts.ValidateMACAddress(*flMacAddress); err != nil { @@ -463,20 +461,6 @@ func parseKeyValueOpts(opts opts.ListOpts) ([]KeyValuePair, error) { return out, nil } -func parseNetMode(netMode string) (NetworkMode, error) { - parts := strings.Split(netMode, ":") - switch mode := parts[0]; mode { - case "default", "bridge", "none", "host": - case "container": - if len(parts) < 2 || parts[1] == "" { - return "", fmt.Errorf("invalid container format container:") - } - default: - return "", fmt.Errorf("invalid --net: %s", netMode) - } - return NetworkMode(netMode), nil -} - func ParseDevice(device string) (DeviceMapping, error) { src := "" dst := "" diff --git a/runconfig/parse_unix.go b/runconfig/parse_unix.go new file mode 100644 index 0000000000..067140c7b7 --- /dev/null +++ b/runconfig/parse_unix.go @@ -0,0 +1,58 @@ +// +build !windows + +package runconfig + +import ( + "fmt" + "strings" +) + +func parseNetMode(netMode string) (NetworkMode, error) { + parts := strings.Split(netMode, ":") + switch mode := parts[0]; mode { + case "default", "bridge", "none", "host": + case "container": + if len(parts) < 2 || parts[1] == "" { + return "", fmt.Errorf("invalid container format container:") + } + default: + return "", fmt.Errorf("invalid --net: %s", netMode) + } + return NetworkMode(netMode), nil +} + +func validateNetMode(vals *validateNM) error { + + if (vals.netMode.IsHost() || vals.netMode.IsContainer()) && *vals.flHostname != "" { + return ErrConflictNetworkHostname + } + + if vals.netMode.IsHost() && vals.flLinks.Len() > 0 { + return ErrConflictHostNetworkAndLinks + } + + if vals.netMode.IsContainer() && vals.flLinks.Len() > 0 { + return ErrConflictContainerNetworkAndLinks + } + + if (vals.netMode.IsHost() || vals.netMode.IsContainer()) && vals.flDns.Len() > 0 { + return ErrConflictNetworkAndDns + } + + if (vals.netMode.IsContainer() || vals.netMode.IsHost()) && vals.flExtraHosts.Len() > 0 { + return ErrConflictNetworkHosts + } + + if (vals.netMode.IsContainer() || vals.netMode.IsHost()) && *vals.flMacAddress != "" { + return ErrConflictContainerNetworkAndMac + } + + if vals.netMode.IsContainer() && (vals.flPublish.Len() > 0 || *vals.flPublishAll == true) { + return ErrConflictNetworkPublishPorts + } + + if vals.netMode.IsContainer() && vals.flExpose.Len() > 0 { + return ErrConflictNetworkExposePorts + } + return nil +} diff --git a/runconfig/parse_windows.go b/runconfig/parse_windows.go new file mode 100644 index 0000000000..83de2bb229 --- /dev/null +++ b/runconfig/parse_windows.go @@ -0,0 +1,20 @@ +package runconfig + +import ( + "fmt" + "strings" +) + +func parseNetMode(netMode string) (NetworkMode, error) { + parts := strings.Split(netMode, ":") + switch mode := parts[0]; mode { + case "default": + default: + return "", fmt.Errorf("invalid --net: %s", netMode) + } + return NetworkMode(netMode), nil +} + +func validateNetMode(vals *validateNM) error { + return nil +}