From 7ff032de117abfa8a25e550a1879b8136596c723 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Fri, 15 Sep 2017 12:38:41 +0200 Subject: [PATCH] Add support for --network=netns:/proc/pid/ns/net Signed-off-by: Antonio Murdaca --- api/types/container/host_config.go | 6 ++++++ daemon/container_operations.go | 11 ++++++++--- daemon/oci_linux.go | 2 ++ runconfig/hostconfig_unix.go | 8 ++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/api/types/container/host_config.go b/api/types/container/host_config.go index 0c82d625e8232..f1f7c6aafcf14 100644 --- a/api/types/container/host_config.go +++ b/api/types/container/host_config.go @@ -36,6 +36,12 @@ func (n IpcMode) IsHost() bool { return n == "host" } +// IsNetNs indicates whether container uses a container network namespace path. +func (n NetworkMode) IsNetNs() bool { + parts := strings.SplitN(string(n), ":", 2) + return len(parts) > 1 && parts[0] == "netns" +} + // IsContainer indicates whether the container uses a container's ipc stack. func (n IpcMode) IsContainer() bool { parts := strings.SplitN(string(n), ":", 2) diff --git a/daemon/container_operations.go b/daemon/container_operations.go index c30250622da0b..dbaf2c732985d 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -415,7 +415,7 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai var n libnetwork.Network mode := container.HostConfig.NetworkMode - if container.Config.NetworkDisabled || mode.IsContainer() { + if container.Config.NetworkDisabled || mode.IsContainer() || mode.IsNetNs() { return } @@ -497,7 +497,7 @@ func (daemon *Daemon) allocateNetwork(container *container.Container) error { updateSettings := false if len(container.NetworkSettings.Networks) == 0 { - if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() { + if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() || container.HostConfig.NetworkMode.IsNetNs() { return nil } @@ -650,6 +650,9 @@ func (daemon *Daemon) updateNetworkConfig(container *container.Container, n libn func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error) { start := time.Now() + if container.HostConfig.NetworkMode.IsNetNs() { + return nil + } if container.HostConfig.NetworkMode.IsContainer() { return runconfig.ErrConflictSharedNetwork } @@ -863,6 +866,8 @@ func (daemon *Daemon) initializeNetworking(container *container.Container) error return err } + // build hostname file based on netns via --network=netns:/path/to/netns ? + return container.BuildHostnameFile() } @@ -889,7 +894,7 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) { if daemon.netController == nil { return } - if container.HostConfig.NetworkMode.IsContainer() || container.Config.NetworkDisabled { + if container.HostConfig.NetworkMode.IsContainer() || container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsNetNs() { return } diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 1afbd7e340bc4..cccc029a7cc9e 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -251,6 +251,8 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", nc.State.GetPID()) setNamespace(s, nsUser) } + } else if c.HostConfig.NetworkMode.IsNetNs() { + ns.Path = parts[1] } else if c.HostConfig.NetworkMode.IsHost() { ns.Path = c.NetworkSettings.SandboxKey } diff --git a/runconfig/hostconfig_unix.go b/runconfig/hostconfig_unix.go index 6e2b7f5ff70c9..0f81dcd8dd0ed 100644 --- a/runconfig/hostconfig_unix.go +++ b/runconfig/hostconfig_unix.go @@ -37,6 +37,14 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error { } } + if parts[0] == "netns" { + if len(parts) < 2 || parts[1] == "" { + return fmt.Errorf("--net: invalid net mode: invalid netns format netns:/path/to/netns") + } else { + return nil + } + } + if hc.NetworkMode.IsContainer() && c.Hostname != "" { return ErrConflictNetworkHostname }