Merge branch 'master' into 1167_events_endpoint-feature

This commit is contained in:
Victor Vieux 2013-07-24 11:49:04 +00:00
commit ee05f97c9a
9 changed files with 132 additions and 44 deletions

View File

@ -76,6 +76,7 @@ Shawn Siefkas <shawn.siefkas@meredith.com>
Silas Sewell <silas@sewell.org> Silas Sewell <silas@sewell.org>
Solomon Hykes <solomon@dotcloud.com> Solomon Hykes <solomon@dotcloud.com>
Sridhar Ratnakumar <sridharr@activestate.com> Sridhar Ratnakumar <sridharr@activestate.com>
Stefan Praszalowicz <stefan@greplin.com>
Thatcher Peskens <thatcher@dotcloud.com> Thatcher Peskens <thatcher@dotcloud.com>
Thomas Bikeev <thomas.bikeev@mac.com> Thomas Bikeev <thomas.bikeev@mac.com>
Thomas Hansen <thomas.hansen@gmail.com> Thomas Hansen <thomas.hansen@gmail.com>

View File

@ -11,7 +11,7 @@ BUILD_DIR := $(CURDIR)/.gopath
GOPATH ?= $(BUILD_DIR) GOPATH ?= $(BUILD_DIR)
export GOPATH export GOPATH
GO_OPTIONS ?= GO_OPTIONS ?= -a -ldflags='-w -d'
ifeq ($(VERBOSE), 1) ifeq ($(VERBOSE), 1)
GO_OPTIONS += -v GO_OPTIONS += -v
endif endif
@ -80,10 +80,10 @@ test:
tar --exclude=${BUILD_SRC} -cz . | tar -xz -C ${BUILD_PATH} tar --exclude=${BUILD_SRC} -cz . | tar -xz -C ${BUILD_PATH}
GOPATH=${CURDIR}/${BUILD_SRC} go get -d GOPATH=${CURDIR}/${BUILD_SRC} go get -d
# Do the test # Do the test
sudo -E GOPATH=${CURDIR}/${BUILD_SRC} go test ${GO_OPTIONS} sudo -E GOPATH=${CURDIR}/${BUILD_SRC} CGO_ENABLED=0 go test ${GO_OPTIONS}
testall: all testall: all
@(cd $(DOCKER_DIR); sudo -E go test ./... $(GO_OPTIONS)) @(cd $(DOCKER_DIR); CGO_ENABLED=0 sudo -E go test ./... $(GO_OPTIONS))
fmt: fmt:
@gofmt -s -l -w . @gofmt -s -l -w .

View File

@ -77,6 +77,7 @@ type Config struct {
Volumes map[string]struct{} Volumes map[string]struct{}
VolumesFrom string VolumesFrom string
Entrypoint []string Entrypoint []string
NetworkDisabled bool
} }
type HostConfig struct { type HostConfig struct {
@ -106,6 +107,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
flTty := cmd.Bool("t", false, "Allocate a pseudo-tty") flTty := cmd.Bool("t", false, "Allocate a pseudo-tty")
flMemory := cmd.Int64("m", 0, "Memory limit (in bytes)") flMemory := cmd.Int64("m", 0, "Memory limit (in bytes)")
flContainerIDFile := cmd.String("cidfile", "", "Write the container ID to the file") flContainerIDFile := cmd.String("cidfile", "", "Write the container ID to the file")
flNetwork := cmd.Bool("n", true, "Enable networking for this container")
if capabilities != nil && *flMemory > 0 && !capabilities.MemoryLimit { if capabilities != nil && *flMemory > 0 && !capabilities.MemoryLimit {
//fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n") //fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n")
@ -178,6 +180,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
PortSpecs: flPorts, PortSpecs: flPorts,
User: *flUser, User: *flUser,
Tty: *flTty, Tty: *flTty,
NetworkDisabled: !*flNetwork,
OpenStdin: *flStdin, OpenStdin: *flStdin,
Memory: *flMemory, Memory: *flMemory,
CpuShares: *flCpuShares, CpuShares: *flCpuShares,
@ -511,9 +514,13 @@ func (container *Container) Start(hostConfig *HostConfig) error {
if err := container.EnsureMounted(); err != nil { if err := container.EnsureMounted(); err != nil {
return err return err
} }
if container.runtime.networkManager.disabled {
container.Config.NetworkDisabled = true
} else {
if err := container.allocateNetwork(); err != nil { if err := container.allocateNetwork(); err != nil {
return err return err
} }
}
// Make sure the config is compatible with the current kernel // Make sure the config is compatible with the current kernel
if container.Config.Memory > 0 && !container.runtime.capabilities.MemoryLimit { if container.Config.Memory > 0 && !container.runtime.capabilities.MemoryLimit {
@ -626,7 +633,9 @@ func (container *Container) Start(hostConfig *HostConfig) error {
} }
// Networking // Networking
if !container.Config.NetworkDisabled {
params = append(params, "-g", container.network.Gateway.String()) params = append(params, "-g", container.network.Gateway.String())
}
// User // User
if container.Config.User != "" { if container.Config.User != "" {
@ -728,6 +737,10 @@ func (container *Container) StderrPipe() (io.ReadCloser, error) {
} }
func (container *Container) allocateNetwork() error { func (container *Container) allocateNetwork() error {
if container.Config.NetworkDisabled {
return nil
}
iface, err := container.runtime.networkManager.Allocate() iface, err := container.runtime.networkManager.Allocate()
if err != nil { if err != nil {
return err return err
@ -754,6 +767,9 @@ func (container *Container) allocateNetwork() error {
} }
func (container *Container) releaseNetwork() { func (container *Container) releaseNetwork() {
if container.Config.NetworkDisabled {
return
}
container.network.Release() container.network.Release()
container.network = nil container.network = nil
container.NetworkSettings = &NetworkSettings{} container.NetworkSettings = &NetworkSettings{}

View File

@ -1252,3 +1252,41 @@ func TestRestartWithVolumes(t *testing.T) {
t.Fatalf("Expected volume path: %s Actual path: %s", expected, actual) t.Fatalf("Expected volume path: %s Actual path: %s", expected, actual)
} }
} }
func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
runtime := mkRuntime(t)
defer nuke(runtime)
config, hc, _, err := ParseRun([]string{"-n=false", GetTestImage(runtime).ID, "ip", "addr", "show"}, nil)
if err != nil {
t.Fatal(err)
}
c, err := NewBuilder(runtime).Create(config)
if err != nil {
t.Fatal(err)
}
stdout, err := c.StdoutPipe()
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(c)
if err := c.Start(hc); err != nil {
t.Fatal(err)
}
c.WaitTimeout(500 * time.Millisecond)
c.Wait()
output, err := ioutil.ReadAll(stdout)
if err != nil {
t.Fatal(err)
}
interfaces := regexp.MustCompile(`(?m)^[0-9]+: [a-zA-Z0-9]+`).FindAllString(string(output), -1)
if len(interfaces) != 1 {
t.Fatalf("Wrong interface count in test container: expected [1: lo], got [%s]", interfaces)
}
if interfaces[0] != "1: lo" {
t.Fatalf("Wrong interface in test container: expected [1: lo], got [%s]", interfaces)
}
}

View File

@ -28,7 +28,7 @@ func main() {
flDaemon := flag.Bool("d", false, "Daemon mode") flDaemon := flag.Bool("d", false, "Daemon mode")
flDebug := flag.Bool("D", false, "Debug mode") flDebug := flag.Bool("D", false, "Debug mode")
flAutoRestart := flag.Bool("r", false, "Restart previously running containers") flAutoRestart := flag.Bool("r", false, "Restart previously running containers")
bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge") bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge. Use 'none' to disable container networking")
pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID") pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID")
flGraphPath := flag.String("g", "/var/lib/docker", "Path to graph storage base dir.") flGraphPath := flag.String("g", "/var/lib/docker", "Path to graph storage base dir.")
flEnableCors := flag.Bool("api-enable-cors", false, "Enable CORS requests in the remote api.") flEnableCors := flag.Bool("api-enable-cors", false, "Enable CORS requests in the remote api.")

View File

@ -20,6 +20,7 @@
-h="": Container host name -h="": Container host name
-i=false: Keep stdin open even if not attached -i=false: Keep stdin open even if not attached
-m=0: Memory limit (in bytes) -m=0: Memory limit (in bytes)
-n=true: Enable networking for this container
-p=[]: Map a network port to the container -p=[]: Map a network port to the container
-t=false: Allocate a pseudo-tty -t=false: Allocate a pseudo-tty
-u="": Username or UID -u="": Username or UID

View File

@ -187,7 +187,7 @@ The copy obeys the following rules:
3.8 ENTRYPOINT 3.8 ENTRYPOINT
-------------- --------------
``ENTRYPOINT /bin/echo`` ``ENTRYPOINT ["/bin/echo"]``
The ``ENTRYPOINT`` instruction adds an entry command that will not be The ``ENTRYPOINT`` instruction adds an entry command that will not be
overwritten when arguments are passed to docker run, unlike the overwritten when arguments are passed to docker run, unlike the

View File

@ -13,6 +13,10 @@ lxc.utsname = {{.Id}}
{{end}} {{end}}
#lxc.aa_profile = unconfined #lxc.aa_profile = unconfined
{{if .Config.NetworkDisabled}}
# network is disabled (-n=false)
lxc.network.type = empty
{{else}}
# network configuration # network configuration
lxc.network.type = veth lxc.network.type = veth
lxc.network.flags = up lxc.network.flags = up
@ -20,6 +24,7 @@ lxc.network.link = {{.NetworkSettings.Bridge}}
lxc.network.name = eth0 lxc.network.name = eth0
lxc.network.mtu = 1500 lxc.network.mtu = 1500
lxc.network.ipv4 = {{.NetworkSettings.IPAddress}}/{{.NetworkSettings.IPPrefixLen}} lxc.network.ipv4 = {{.NetworkSettings.IPAddress}}/{{.NetworkSettings.IPPrefixLen}}
{{end}}
# root filesystem # root filesystem
{{$ROOTFS := .RootfsPath}} {{$ROOTFS := .RootfsPath}}

View File

@ -17,6 +17,7 @@ var NetworkBridgeIface string
const ( const (
DefaultNetworkBridge = "docker0" DefaultNetworkBridge = "docker0"
DisableNetworkBridge = "none"
portRangeStart = 49153 portRangeStart = 49153
portRangeEnd = 65535 portRangeEnd = 65535
) )
@ -472,10 +473,16 @@ type NetworkInterface struct {
manager *NetworkManager manager *NetworkManager
extPorts []*Nat extPorts []*Nat
disabled bool
} }
// Allocate an external TCP port and map it to the interface // Allocate an external TCP port and map it to the interface
func (iface *NetworkInterface) AllocatePort(spec string) (*Nat, error) { func (iface *NetworkInterface) AllocatePort(spec string) (*Nat, error) {
if iface.disabled {
return nil, fmt.Errorf("Trying to allocate port for interface %v, which is disabled", iface) // FIXME
}
nat, err := parseNat(spec) nat, err := parseNat(spec)
if err != nil { if err != nil {
return nil, err return nil, err
@ -571,6 +578,11 @@ func parseNat(spec string) (*Nat, error) {
// Release: Network cleanup - release all resources // Release: Network cleanup - release all resources
func (iface *NetworkInterface) Release() { func (iface *NetworkInterface) Release() {
if iface.disabled {
return
}
for _, nat := range iface.extPorts { for _, nat := range iface.extPorts {
utils.Debugf("Unmaping %v/%v", nat.Proto, nat.Frontend) utils.Debugf("Unmaping %v/%v", nat.Proto, nat.Frontend)
if err := iface.manager.portMapper.Unmap(nat.Frontend, nat.Proto); err != nil { if err := iface.manager.portMapper.Unmap(nat.Frontend, nat.Proto); err != nil {
@ -598,10 +610,17 @@ type NetworkManager struct {
tcpPortAllocator *PortAllocator tcpPortAllocator *PortAllocator
udpPortAllocator *PortAllocator udpPortAllocator *PortAllocator
portMapper *PortMapper portMapper *PortMapper
disabled bool
} }
// Allocate a network interface // Allocate a network interface
func (manager *NetworkManager) Allocate() (*NetworkInterface, error) { func (manager *NetworkManager) Allocate() (*NetworkInterface, error) {
if manager.disabled {
return &NetworkInterface{disabled: true}, nil
}
ip, err := manager.ipAllocator.Acquire() ip, err := manager.ipAllocator.Acquire()
if err != nil { if err != nil {
return nil, err return nil, err
@ -615,6 +634,14 @@ func (manager *NetworkManager) Allocate() (*NetworkInterface, error) {
} }
func newNetworkManager(bridgeIface string) (*NetworkManager, error) { func newNetworkManager(bridgeIface string) (*NetworkManager, error) {
if bridgeIface == DisableNetworkBridge {
manager := &NetworkManager{
disabled: true,
}
return manager, nil
}
addr, err := getIfaceAddr(bridgeIface) addr, err := getIfaceAddr(bridgeIface)
if err != nil { if err != nil {
// If the iface is not found, try to create it // If the iface is not found, try to create it