(*) Support --net:container:<containername/id> for windows
(*) (vdemeester) Removed duplicate code across Windows and Unix wrt Net:Containers (*) Return unsupported error for network sharing for hyperv isolation containers Signed-off-by: Madhan Raj Mookkandy <MadhanRaj.Mookkandy@microsoft.com>
This commit is contained in:
parent
6e04fbf748
commit
040afcce8f
12 changed files with 122 additions and 127 deletions
|
@ -10,9 +10,6 @@ import (
|
|||
"github.com/docker/go-units"
|
||||
)
|
||||
|
||||
// NetworkMode represents the container network stack.
|
||||
type NetworkMode string
|
||||
|
||||
// Isolation represents the isolation technology of a container. The supported
|
||||
// values are platform specific
|
||||
type Isolation string
|
||||
|
@ -66,6 +63,47 @@ func (n IpcMode) Container() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// NetworkMode represents the container network stack.
|
||||
type NetworkMode string
|
||||
|
||||
// IsNone indicates whether container isn't using a network stack.
|
||||
func (n NetworkMode) IsNone() bool {
|
||||
return n == "none"
|
||||
}
|
||||
|
||||
// IsDefault indicates whether container uses the default network stack.
|
||||
func (n NetworkMode) IsDefault() bool {
|
||||
return n == "default"
|
||||
}
|
||||
|
||||
// IsPrivate indicates whether container uses its private network stack.
|
||||
func (n NetworkMode) IsPrivate() bool {
|
||||
return !(n.IsHost() || n.IsContainer())
|
||||
}
|
||||
|
||||
// IsContainer indicates whether container uses a container network stack.
|
||||
func (n NetworkMode) IsContainer() bool {
|
||||
parts := strings.SplitN(string(n), ":", 2)
|
||||
return len(parts) > 1 && parts[0] == "container"
|
||||
}
|
||||
|
||||
// ConnectedContainer is the id of the container which network this container is connected to.
|
||||
func (n NetworkMode) ConnectedContainer() string {
|
||||
parts := strings.SplitN(string(n), ":", 2)
|
||||
if len(parts) > 1 {
|
||||
return parts[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
//UserDefined indicates user-created network
|
||||
func (n NetworkMode) UserDefined() string {
|
||||
if n.IsUserDefined() {
|
||||
return string(n)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// UsernsMode represents userns mode in the container.
|
||||
type UsernsMode string
|
||||
|
||||
|
|
|
@ -2,23 +2,11 @@
|
|||
|
||||
package container
|
||||
|
||||
import "strings"
|
||||
|
||||
// IsValid indicates if an isolation technology is valid
|
||||
func (i Isolation) IsValid() bool {
|
||||
return i.IsDefault()
|
||||
}
|
||||
|
||||
// IsPrivate indicates whether container uses its private network stack.
|
||||
func (n NetworkMode) IsPrivate() bool {
|
||||
return !(n.IsHost() || n.IsContainer())
|
||||
}
|
||||
|
||||
// IsDefault indicates whether container uses the default network stack.
|
||||
func (n NetworkMode) IsDefault() bool {
|
||||
return n == "default"
|
||||
}
|
||||
|
||||
// NetworkName returns the name of the network stack.
|
||||
func (n NetworkMode) NetworkName() string {
|
||||
if n.IsBridge() {
|
||||
|
@ -47,35 +35,7 @@ func (n NetworkMode) IsHost() bool {
|
|||
return n == "host"
|
||||
}
|
||||
|
||||
// IsContainer indicates whether container uses a container network stack.
|
||||
func (n NetworkMode) IsContainer() bool {
|
||||
parts := strings.SplitN(string(n), ":", 2)
|
||||
return len(parts) > 1 && parts[0] == "container"
|
||||
}
|
||||
|
||||
// IsNone indicates whether container isn't using a network stack.
|
||||
func (n NetworkMode) IsNone() bool {
|
||||
return n == "none"
|
||||
}
|
||||
|
||||
// ConnectedContainer is the id of the container which network this container is connected to.
|
||||
func (n NetworkMode) ConnectedContainer() string {
|
||||
parts := strings.SplitN(string(n), ":", 2)
|
||||
if len(parts) > 1 {
|
||||
return parts[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsUserDefined indicates user-created network
|
||||
func (n NetworkMode) IsUserDefined() bool {
|
||||
return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer()
|
||||
}
|
||||
|
||||
//UserDefined indicates user-created network
|
||||
func (n NetworkMode) UserDefined() string {
|
||||
if n.IsUserDefined() {
|
||||
return string(n)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -4,22 +4,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// IsDefault indicates whether container uses the default network stack.
|
||||
func (n NetworkMode) IsDefault() bool {
|
||||
return n == "default"
|
||||
}
|
||||
|
||||
// IsNone indicates whether container isn't using a network stack.
|
||||
func (n NetworkMode) IsNone() bool {
|
||||
return n == "none"
|
||||
}
|
||||
|
||||
// IsContainer indicates whether container uses a container network stack.
|
||||
// Returns false as windows doesn't support this mode
|
||||
func (n NetworkMode) IsContainer() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsBridge indicates whether container uses the bridge network stack
|
||||
// in windows it is given the name NAT
|
||||
func (n NetworkMode) IsBridge() bool {
|
||||
|
@ -32,20 +16,9 @@ func (n NetworkMode) IsHost() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// IsPrivate indicates whether container uses its private network stack.
|
||||
func (n NetworkMode) IsPrivate() bool {
|
||||
return !(n.IsHost() || n.IsContainer())
|
||||
}
|
||||
|
||||
// ConnectedContainer is the id of the container which network this container is connected to.
|
||||
// Returns blank string on windows
|
||||
func (n NetworkMode) ConnectedContainer() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsUserDefined indicates user-created network
|
||||
func (n NetworkMode) IsUserDefined() bool {
|
||||
return !n.IsDefault() && !n.IsNone() && !n.IsBridge()
|
||||
return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
|
||||
}
|
||||
|
||||
// IsHyperV indicates the use of a Hyper-V partition for isolation
|
||||
|
@ -71,17 +44,11 @@ func (n NetworkMode) NetworkName() string {
|
|||
return "nat"
|
||||
} else if n.IsNone() {
|
||||
return "none"
|
||||
} else if n.IsContainer() {
|
||||
return "container"
|
||||
} else if n.IsUserDefined() {
|
||||
return n.UserDefined()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
//UserDefined indicates user-created network
|
||||
func (n NetworkMode) UserDefined() string {
|
||||
if n.IsUserDefined() {
|
||||
return string(n)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ type Container struct {
|
|||
CommonContainer
|
||||
|
||||
// Fields below here are platform specific.
|
||||
NetworkSharedContainerID string
|
||||
}
|
||||
|
||||
// ExitStatus provides exit reasons for a container.
|
||||
|
|
|
@ -505,12 +505,13 @@ func (daemon *Daemon) allocateNetwork(container *container.Container) error {
|
|||
logrus.Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
|
||||
}
|
||||
|
||||
updateSettings := false
|
||||
if len(container.NetworkSettings.Networks) == 0 {
|
||||
if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
|
||||
return nil
|
||||
}
|
||||
if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
|
||||
return nil
|
||||
}
|
||||
|
||||
updateSettings := false
|
||||
|
||||
if len(container.NetworkSettings.Networks) == 0 {
|
||||
daemon.updateContainerNetworkSettings(container, nil)
|
||||
updateSettings = true
|
||||
}
|
||||
|
|
|
@ -56,4 +56,5 @@ func setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]
|
|||
}
|
||||
|
||||
func initializeNetworkingPaths(container *container.Container, nc *container.Container) {
|
||||
container.NetworkSharedContainerID = nc.ID
|
||||
}
|
||||
|
|
|
@ -157,14 +157,17 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain
|
|||
createOptions = append(createOptions, &libcontainerd.FlushOption{IgnoreFlushesDuringBoot: !container.HasBeenStartedBefore})
|
||||
createOptions = append(createOptions, hvOpts)
|
||||
createOptions = append(createOptions, layerOpts)
|
||||
if epList != nil {
|
||||
createOptions = append(createOptions, &libcontainerd.NetworkEndpointsOption{
|
||||
Endpoints: epList,
|
||||
AllowUnqualifiedDNSQuery: AllowUnqualifiedDNSQuery,
|
||||
DNSSearchList: dnsSearch,
|
||||
})
|
||||
}
|
||||
|
||||
var networkSharedContainerID string
|
||||
if container.HostConfig.NetworkMode.IsContainer() {
|
||||
networkSharedContainerID = container.NetworkSharedContainerID
|
||||
}
|
||||
createOptions = append(createOptions, &libcontainerd.NetworkEndpointsOption{
|
||||
Endpoints: epList,
|
||||
AllowUnqualifiedDNSQuery: AllowUnqualifiedDNSQuery,
|
||||
DNSSearchList: dnsSearch,
|
||||
NetworkSharedContainerID: networkSharedContainerID,
|
||||
})
|
||||
return createOptions, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir
|
|||
if n.DNSSearchList != nil {
|
||||
configuration.DNSSearchList = strings.Join(n.DNSSearchList, ",")
|
||||
}
|
||||
configuration.NetworkSharedContainerName = n.NetworkSharedContainerID
|
||||
continue
|
||||
}
|
||||
if c, ok := option.(*CredentialsOption); ok {
|
||||
|
|
|
@ -60,6 +60,7 @@ type NetworkEndpointsOption struct {
|
|||
Endpoints []string
|
||||
AllowUnqualifiedDNSQuery bool
|
||||
DNSSearchList []string
|
||||
NetworkSharedContainerID string
|
||||
}
|
||||
|
||||
// CredentialsOption is a CreateOption that indicates the credentials from
|
||||
|
|
|
@ -2,7 +2,9 @@ package runconfig
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
)
|
||||
|
@ -32,3 +34,47 @@ func SetDefaultNetModeIfBlank(hc *container.HostConfig) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateNetContainerMode ensures that the various combinations of requested
|
||||
// network settings wrt container mode are valid.
|
||||
func ValidateNetContainerMode(c *container.Config, hc *container.HostConfig) error {
|
||||
// We may not be passed a host config, such as in the case of docker commit
|
||||
if hc == nil {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(string(hc.NetworkMode), ":")
|
||||
if parts[0] == "container" {
|
||||
if len(parts) < 2 || parts[1] == "" {
|
||||
return fmt.Errorf("--net: invalid net mode: invalid container format container:<name|id>")
|
||||
}
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && c.Hostname != "" {
|
||||
return ErrConflictNetworkHostname
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.Links) > 0 {
|
||||
return ErrConflictContainerNetworkAndLinks
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.DNS) > 0 {
|
||||
return ErrConflictNetworkAndDNS
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 {
|
||||
return ErrConflictNetworkHosts
|
||||
}
|
||||
|
||||
if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && c.MacAddress != "" {
|
||||
return ErrConflictContainerNetworkAndMac
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts == true) {
|
||||
return ErrConflictNetworkPublishPorts
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(c.ExposedPorts) > 0 {
|
||||
return ErrConflictNetworkExposePorts
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ package runconfig
|
|||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
|
@ -30,15 +29,10 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
|
|||
if hc == nil {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(string(hc.NetworkMode), ":")
|
||||
if parts[0] == "container" {
|
||||
if len(parts) < 2 || parts[1] == "" {
|
||||
return fmt.Errorf("--net: invalid net mode: invalid container format container:<name|id>")
|
||||
}
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && c.Hostname != "" {
|
||||
return ErrConflictNetworkHostname
|
||||
err := ValidateNetContainerMode(c, hc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hc.UTSMode.IsHost() && c.Hostname != "" {
|
||||
|
@ -49,29 +43,6 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
|
|||
return ErrConflictHostNetworkAndLinks
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.Links) > 0 {
|
||||
return ErrConflictContainerNetworkAndLinks
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.DNS) > 0 {
|
||||
return ErrConflictNetworkAndDNS
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 {
|
||||
return ErrConflictNetworkHosts
|
||||
}
|
||||
|
||||
if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && c.MacAddress != "" {
|
||||
return ErrConflictContainerNetworkAndMac
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts == true) {
|
||||
return ErrConflictNetworkPublishPorts
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(c.ExposedPorts) > 0 {
|
||||
return ErrConflictNetworkExposePorts
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package runconfig
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
|
@ -25,10 +24,16 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
|
|||
if hc == nil {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(string(hc.NetworkMode), ":")
|
||||
if len(parts) > 1 {
|
||||
return fmt.Errorf("invalid --net: %s", hc.NetworkMode)
|
||||
|
||||
err := ValidateNetContainerMode(c, hc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && hc.Isolation.IsHyperV() {
|
||||
return fmt.Errorf("net mode --net=container:<NameOrId> unsupported for hyperv isolation")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue