소스 검색

Merge pull request #4702 from timthelion/Issue#4681-1

Fix Issue#4681
Victor Vieux 11 년 전
부모
커밋
30541ade82

+ 47 - 22
integration/container_test.go

@@ -434,28 +434,6 @@ func TestOutput(t *testing.T) {
 	}
 }
 
-func TestContainerNetwork(t *testing.T) {
-	runtime := mkRuntime(t)
-	defer nuke(runtime)
-	container, _, err := runtime.Create(
-		&runconfig.Config{
-			Image: GetTestImage(runtime).ID,
-			Cmd:   []string{"ping", "-c", "1", "127.0.0.1"},
-		},
-		"",
-	)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer runtime.Destroy(container)
-	if err := container.Run(); err != nil {
-		t.Fatal(err)
-	}
-	if code := container.State.GetExitCode(); code != 0 {
-		t.Fatalf("Unexpected ping 127.0.0.1 exit code %d (expected 0)", code)
-	}
-}
-
 func TestKillDifferentUser(t *testing.T) {
 	runtime := mkRuntime(t)
 	defer nuke(runtime)
@@ -1523,6 +1501,53 @@ func TestVolumesFromWithVolumes(t *testing.T) {
 	}
 }
 
+func TestContainerNetwork(t *testing.T) {
+	runtime := mkRuntime(t)
+	defer nuke(runtime)
+	container, _, err := runtime.Create(
+		&runconfig.Config{
+			Image: GetTestImage(runtime).ID,
+			// If I change this to ping 8.8.8.8 it fails.  Any idea why? - timthelion
+			Cmd: []string{"ping", "-c", "1", "127.0.0.1"},
+		},
+		"",
+	)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer runtime.Destroy(container)
+	if err := container.Run(); err != nil {
+		t.Fatal(err)
+	}
+	if code := container.State.GetExitCode(); code != 0 {
+		t.Fatalf("Unexpected ping 127.0.0.1 exit code %d (expected 0)", code)
+	}
+}
+
+// Issue #4681
+func TestLoopbackFunctionsWhenNetworkingIsDissabled(t *testing.T) {
+	runtime := mkRuntime(t)
+	defer nuke(runtime)
+	container, _, err := runtime.Create(
+		&runconfig.Config{
+			Image:           GetTestImage(runtime).ID,
+			Cmd:             []string{"ping", "-c", "1", "127.0.0.1"},
+			NetworkDisabled: true,
+		},
+		"",
+	)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer runtime.Destroy(container)
+	if err := container.Run(); err != nil {
+		t.Fatal(err)
+	}
+	if code := container.State.GetExitCode(); code != 0 {
+		t.Fatalf("Unexpected ping 127.0.0.1 exit code %d (expected 0)", code)
+	}
+}
+
 func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
 	eng := NewTestEngine(t)
 	runtime := mkRuntimeFromEngine(eng, t)

+ 24 - 0
pkg/libcontainer/network/loopback.go

@@ -0,0 +1,24 @@
+package network
+
+import (
+	"fmt"
+	"github.com/dotcloud/docker/pkg/libcontainer"
+)
+
+// Loopback is a network strategy that provides a basic loopback device
+type Loopback struct {
+}
+
+func (l *Loopback) Create(n *libcontainer.Network, nspid int, context libcontainer.Context) error {
+	return nil
+}
+
+func (l *Loopback) Initialize(config *libcontainer.Network, context libcontainer.Context) error {
+	if err := SetMtu("lo", config.Mtu); err != nil {
+		return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err)
+	}
+	if err := InterfaceUp("lo"); err != nil {
+		return fmt.Errorf("lo up %s", err)
+	}
+	return nil
+}

+ 2 - 1
pkg/libcontainer/network/strategy.go

@@ -10,7 +10,8 @@ var (
 )
 
 var strategies = map[string]NetworkStrategy{
-	"veth": &Veth{},
+	"veth":     &Veth{},
+	"loopback": &Loopback{},
 }
 
 // NetworkStrategy represents a specific network configuration for

+ 0 - 6
pkg/libcontainer/network/veth.go

@@ -68,12 +68,6 @@ func (v *Veth) Initialize(config *libcontainer.Network, context libcontainer.Con
 	if err := InterfaceUp("eth0"); err != nil {
 		return fmt.Errorf("eth0 up %s", err)
 	}
-	if err := SetMtu("lo", config.Mtu); err != nil {
-		return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err)
-	}
-	if err := InterfaceUp("lo"); err != nil {
-		return fmt.Errorf("lo up %s", err)
-	}
 	if config.Gateway != "" {
 		if err := SetDefaultGateway(config.Gateway); err != nil {
 			return fmt.Errorf("set gateway to %s %s", config.Gateway, err)

+ 5 - 1
pkg/libcontainer/nsinit/init.go

@@ -134,7 +134,11 @@ func setupNetwork(container *libcontainer.Container, context libcontainer.Contex
 		if err != nil {
 			return err
 		}
-		return strategy.Initialize(config, context)
+
+		err1 := strategy.Initialize(config, context)
+		if err1 != nil {
+			return err1
+		}
 	}
 	return nil
 }

+ 6 - 2
runtime/container.go

@@ -364,14 +364,18 @@ func populateCommand(c *Container) {
 		driverConfig []string
 	)
 
+	en = &execdriver.Network{
+		Mtu:       c.runtime.config.Mtu,
+		Interface: nil,
+	}
+
 	if !c.Config.NetworkDisabled {
 		network := c.NetworkSettings
-		en = &execdriver.Network{
+		en.Interface = &execdriver.NetworkInterface{
 			Gateway:     network.Gateway,
 			Bridge:      network.Bridge,
 			IPAddress:   network.IPAddress,
 			IPPrefixLen: network.IPPrefixLen,
-			Mtu:         c.runtime.config.Mtu,
 		}
 	}
 

+ 7 - 3
runtime/execdriver/driver.go

@@ -84,11 +84,15 @@ type Driver interface {
 
 // Network settings of the container
 type Network struct {
+	Interface *NetworkInterface `json:"interface"` // if interface is nil then networking is disabled
+	Mtu       int               `json:"mtu"`
+}
+
+type NetworkInterface struct {
 	Gateway     string `json:"gateway"`
 	IPAddress   string `json:"ip"`
 	Bridge      string `json:"bridge"`
 	IPPrefixLen int    `json:"ip_prefix_len"`
-	Mtu         int    `json:"mtu"`
 }
 
 type Resources struct {
@@ -118,8 +122,8 @@ type Command struct {
 	WorkingDir string     `json:"working_dir"`
 	ConfigPath string     `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver
 	Tty        bool       `json:"tty"`
-	Network    *Network   `json:"network"` // if network is nil then networking is disabled
-	Config     []string   `json:"config"`  //  generic values that specific drivers can consume
+	Network    *Network   `json:"network"`
+	Config     []string   `json:"config"` //  generic values that specific drivers can consume
 	Resources  *Resources `json:"resources"`
 	Mounts     []Mount    `json:"mounts"`
 

+ 6 - 4
runtime/execdriver/lxc/driver.go

@@ -98,13 +98,15 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 		DriverName,
 	}
 
-	if c.Network != nil {
+	if c.Network.Interface != nil {
 		params = append(params,
-			"-g", c.Network.Gateway,
-			"-i", fmt.Sprintf("%s/%d", c.Network.IPAddress, c.Network.IPPrefixLen),
-			"-mtu", strconv.Itoa(c.Network.Mtu),
+			"-g", c.Network.Interface.Gateway,
+			"-i", fmt.Sprintf("%s/%d", c.Network.Interface.IPAddress, c.Network.Interface.IPPrefixLen),
 		)
 	}
+	params = append(params,
+		"-mtu", strconv.Itoa(c.Network.Mtu),
+	)
 
 	if c.User != "" {
 		params = append(params, "-u", c.User)

+ 3 - 3
runtime/execdriver/lxc/lxc_template.go

@@ -7,17 +7,17 @@ import (
 )
 
 const LxcTemplate = `
-{{if .Network}}
+{{if .Network.Interface}}
 # network configuration
 lxc.network.type = veth
-lxc.network.link = {{.Network.Bridge}}
+lxc.network.link = {{.Network.Interface.Bridge}}
 lxc.network.name = eth0
-lxc.network.mtu = {{.Network.Mtu}}
 {{else}}
 # network is disabled (-n=false)
 lxc.network.type = empty
 lxc.network.flags = up
 {{end}}
+lxc.network.mtu = {{.Network.Mtu}}
 
 # root filesystem
 {{$ROOTFS := .Rootfs}}

+ 8 - 0
runtime/execdriver/lxc/lxc_template_unit_test.go

@@ -43,6 +43,10 @@ func TestLXCConfig(t *testing.T) {
 			Memory:    int64(mem),
 			CpuShares: int64(cpu),
 		},
+		Network: &execdriver.Network{
+			Mtu:       1500,
+			Interface: nil,
+		},
 	}
 	p, err := driver.generateLXCConfig(command)
 	if err != nil {
@@ -75,6 +79,10 @@ func TestCustomLxcConfig(t *testing.T) {
 			"lxc.utsname = docker",
 			"lxc.cgroup.cpuset.cpus = 0,1",
 		},
+		Network: &execdriver.Network{
+			Mtu:       1500,
+			Interface: nil,
+		},
 	}
 
 	p, err := driver.generateLXCConfig(command)

+ 22 - 11
runtime/execdriver/native/default_template.go

@@ -19,19 +19,30 @@ func createContainer(c *execdriver.Command) *libcontainer.Container {
 	container.WorkingDir = c.WorkingDir
 	container.Env = c.Env
 
-	if c.Network != nil {
-		container.Networks = []*libcontainer.Network{
-			{
-				Mtu:     c.Network.Mtu,
-				Address: fmt.Sprintf("%s/%d", c.Network.IPAddress, c.Network.IPPrefixLen),
-				Gateway: c.Network.Gateway,
-				Type:    "veth",
-				Context: libcontainer.Context{
-					"prefix": "veth",
-					"bridge": c.Network.Bridge,
-				},
+	loopbackNetwork := libcontainer.Network{
+		Mtu:     c.Network.Mtu,
+		Address: fmt.Sprintf("%s/%d", "127.0.0.1", 0),
+		Gateway: "localhost",
+		Type:    "loopback",
+		Context: libcontainer.Context{},
+	}
+
+	container.Networks = []*libcontainer.Network{
+		&loopbackNetwork,
+	}
+
+	if c.Network.Interface != nil {
+		vethNetwork := libcontainer.Network{
+			Mtu:     c.Network.Mtu,
+			Address: fmt.Sprintf("%s/%d", c.Network.Interface.IPAddress, c.Network.Interface.IPPrefixLen),
+			Gateway: c.Network.Interface.Gateway,
+			Type:    "veth",
+			Context: libcontainer.Context{
+				"prefix": "veth",
+				"bridge": c.Network.Interface.Bridge,
 			},
 		}
+		container.Networks = append(container.Networks, &vethNetwork)
 	}
 
 	container.Cgroups.Name = c.ID