runconfig: add -net container:name option

Docker-DCO-1.1-Signed-off-by: Johan Euphrosine <proppy@google.com> (github: proppy)
This commit is contained in:
Johan Euphrosine 2014-04-30 15:46:56 -07:00 committed by Michael Crosby
parent d103f0186a
commit a60159f3b1
5 changed files with 84 additions and 29 deletions

View File

@ -325,7 +325,7 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
}) })
} }
func populateCommand(c *Container, env []string) { func populateCommand(c *Container, env []string) error {
var ( var (
en *execdriver.Network en *execdriver.Network
context = make(map[string][]string) context = make(map[string][]string)
@ -351,6 +351,14 @@ func populateCommand(c *Container, env []string) {
// TODO: this can be removed after lxc-conf is fully deprecated // TODO: this can be removed after lxc-conf is fully deprecated
mergeLxcConfIntoOptions(c.hostConfig, context) mergeLxcConfIntoOptions(c.hostConfig, context)
if netContainer := c.hostConfig.UseContainerNetwork; netContainer != "" {
nc := c.daemon.Get(netContainer)
if nc == nil {
return fmt.Errorf("no such container to join network: %q", netContainer)
}
en.ContainerID = nc.ID
}
resources := &execdriver.Resources{ resources := &execdriver.Resources{
Memory: c.Config.Memory, Memory: c.Config.Memory,
MemorySwap: c.Config.MemorySwap, MemorySwap: c.Config.MemorySwap,
@ -372,6 +380,7 @@ func populateCommand(c *Container, env []string) {
} }
c.command.SysProcAttr = &syscall.SysProcAttr{Setsid: true} c.command.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
c.command.Env = env c.command.Env = env
return nil
} }
func (container *Container) Start() (err error) { func (container *Container) Start() (err error) {
@ -415,7 +424,9 @@ func (container *Container) Start() (err error) {
if err := container.setupWorkingDirectory(); err != nil { if err := container.setupWorkingDirectory(); err != nil {
return err return err
} }
populateCommand(container, env) if err := populateCommand(container, env); err != nil {
return err
}
if err := setupMountsForContainer(container); err != nil { if err := setupMountsForContainer(container); err != nil {
return err return err
} }

View File

@ -89,8 +89,9 @@ type Driver interface {
// Network settings of the container // Network settings of the container
type Network struct { type Network struct {
Interface *NetworkInterface `json:"interface"` // if interface is nil then networking is disabled Interface *NetworkInterface `json:"interface"` // if interface is nil then networking is disabled
Mtu int `json:"mtu"` Mtu int `json:"mtu"`
ContainerID string `json:"container_id"` // id of the container to join network.
} }
type NetworkInterface struct { type NetworkInterface struct {

View File

@ -3,6 +3,7 @@ package native
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"github.com/dotcloud/docker/daemon/execdriver" "github.com/dotcloud/docker/daemon/execdriver"
"github.com/dotcloud/docker/daemon/execdriver/native/configuration" "github.com/dotcloud/docker/daemon/execdriver/native/configuration"
@ -75,6 +76,21 @@ func (d *driver) createNetwork(container *libcontainer.Container, c *execdriver.
} }
container.Networks = append(container.Networks, &vethNetwork) container.Networks = append(container.Networks, &vethNetwork)
} }
if c.Network.ContainerID != "" {
cmd := d.activeContainers[c.Network.ContainerID]
if cmd == nil || cmd.Process == nil {
return fmt.Errorf("%s is not a valid running container to join", c.Network.ContainerID)
}
nspath := filepath.Join("/proc", fmt.Sprint(cmd.Process.Pid), "ns", "net")
container.Networks = append(container.Networks, &libcontainer.Network{
Type: "netns",
Context: libcontainer.Context{
"nspath": nspath,
},
})
}
return nil return nil
} }

View File

@ -7,16 +7,17 @@ import (
) )
type HostConfig struct { type HostConfig struct {
Binds []string Binds []string
ContainerIDFile string ContainerIDFile string
LxcConf []utils.KeyValuePair LxcConf []utils.KeyValuePair
Privileged bool Privileged bool
PortBindings nat.PortMap PortBindings nat.PortMap
Links []string Links []string
PublishAllPorts bool PublishAllPorts bool
Dns []string Dns []string
DnsSearch []string DnsSearch []string
VolumesFrom []string VolumesFrom []string
UseContainerNetwork string
} }
func ContainerHostConfigFromJob(job *engine.Job) *HostConfig { func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
@ -42,5 +43,8 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
if VolumesFrom := job.GetenvList("VolumesFrom"); VolumesFrom != nil { if VolumesFrom := job.GetenvList("VolumesFrom"); VolumesFrom != nil {
hostConfig.VolumesFrom = VolumesFrom hostConfig.VolumesFrom = VolumesFrom
} }
if UseContainerNetwork := job.Getenv("UseContainerNetwork"); UseContainerNetwork != "" {
hostConfig.UseContainerNetwork = UseContainerNetwork
}
return hostConfig return hostConfig
} }

View File

@ -2,14 +2,15 @@ package runconfig
import ( import (
"fmt" "fmt"
"io/ioutil"
"path"
"strings"
"github.com/dotcloud/docker/nat" "github.com/dotcloud/docker/nat"
"github.com/dotcloud/docker/opts" "github.com/dotcloud/docker/opts"
flag "github.com/dotcloud/docker/pkg/mflag" flag "github.com/dotcloud/docker/pkg/mflag"
"github.com/dotcloud/docker/pkg/sysinfo" "github.com/dotcloud/docker/pkg/sysinfo"
"github.com/dotcloud/docker/utils" "github.com/dotcloud/docker/utils"
"io/ioutil"
"path"
"strings"
) )
var ( var (
@ -61,7 +62,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID") flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID")
flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container") flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
flCpuShares = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)") flCpuShares = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
flNetMode = cmd.String([]string{"#net", "-net"}, "bridge", "Set the Network mode for the container ('bridge': creates a new network stack for the container on the docker bridge, 'disable': disable networking for this container, 'container:name_or_id': reuses another container network stack)")
// For documentation purpose // For documentation purpose
_ = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)") _ = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)")
_ = cmd.String([]string{"#name", "-name"}, "", "Assign a name to the container") _ = cmd.String([]string{"#name", "-name"}, "", "Assign a name to the container")
@ -197,6 +198,11 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
// boo, there's no debug output for docker run // boo, there's no debug output for docker run
//utils.Debugf("Environment variables for the container: %#v", envVariables) //utils.Debugf("Environment variables for the container: %#v", envVariables)
netMode, useContainerNetwork, err := parseNetMode(*flNetMode)
if err != nil {
return nil, nil, cmd, fmt.Errorf("-net: invalid net mode: %v", err)
}
config := &Config{ config := &Config{
Hostname: hostname, Hostname: hostname,
Domainname: domainname, Domainname: domainname,
@ -204,7 +210,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
ExposedPorts: ports, ExposedPorts: ports,
User: *flUser, User: *flUser,
Tty: *flTty, Tty: *flTty,
NetworkDisabled: !*flNetwork, NetworkDisabled: !*flNetwork || netMode == "disable",
OpenStdin: *flStdin, OpenStdin: *flStdin,
Memory: flMemory, Memory: flMemory,
CpuShares: *flCpuShares, CpuShares: *flCpuShares,
@ -220,16 +226,17 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
} }
hostConfig := &HostConfig{ hostConfig := &HostConfig{
Binds: binds, Binds: binds,
ContainerIDFile: *flContainerIDFile, ContainerIDFile: *flContainerIDFile,
LxcConf: lxcConf, LxcConf: lxcConf,
Privileged: *flPrivileged, Privileged: *flPrivileged,
PortBindings: portBindings, PortBindings: portBindings,
Links: flLinks.GetAll(), Links: flLinks.GetAll(),
PublishAllPorts: *flPublishAll, PublishAllPorts: *flPublishAll,
Dns: flDns.GetAll(), Dns: flDns.GetAll(),
DnsSearch: flDnsSearch.GetAll(), DnsSearch: flDnsSearch.GetAll(),
VolumesFrom: flVolumesFrom.GetAll(), VolumesFrom: flVolumesFrom.GetAll(),
UseContainerNetwork: useContainerNetwork,
} }
if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit { if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit {
@ -274,3 +281,19 @@ func parseKeyValueOpts(opts opts.ListOpts) ([]utils.KeyValuePair, error) {
} }
return out, nil return out, nil
} }
func parseNetMode(netMode string) (string, string, error) {
parts := strings.Split(netMode, ":")
if len(parts) < 1 {
return "", "", fmt.Errorf("'netmode' cannot be empty", netMode)
}
mode := parts[0]
var container string
if mode == "container" {
if len(parts) < 2 {
return "", "", fmt.Errorf("'container:' netmode requires a container id or name", netMode)
}
container = parts[1]
}
return mode, container, nil
}