Browse code

Extract network settings types for inspect.

Keeping backwards compatibility.

Signed-off-by: David Calavera <david.calavera@gmail.com>
Signed-off-by: Tibor Vass <tibor@docker.com>

David Calavera authored on 2015/10/27 11:35:49
Showing 12 changed files
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"time"
6 6
 
7 7
 	"github.com/docker/docker/daemon/network"
8
+	"github.com/docker/docker/pkg/nat"
8 9
 	"github.com/docker/docker/pkg/version"
9 10
 	"github.com/docker/docker/registry"
10 11
 	"github.com/docker/docker/runconfig"
... ...
@@ -255,7 +256,6 @@ type ContainerJSONBase struct {
255 255
 	Args            []string
256 256
 	State           *ContainerState
257 257
 	Image           string
258
-	NetworkSettings *network.Settings
259 258
 	ResolvConfPath  string
260 259
 	HostnamePath    string
261 260
 	HostsPath       string
... ...
@@ -277,8 +277,28 @@ type ContainerJSONBase struct {
277 277
 // ContainerJSON is newly used struct along with MountPoint
278 278
 type ContainerJSON struct {
279 279
 	*ContainerJSONBase
280
-	Mounts []MountPoint
281
-	Config *runconfig.Config
280
+	Mounts          []MountPoint
281
+	Config          *runconfig.Config
282
+	NetworkSettings *NetworkSettings
283
+}
284
+
285
+// NetworkSettings exposes the network settings in the api
286
+type NetworkSettings struct {
287
+	NetworkSettingsBase
288
+	Networks map[string]*network.EndpointSettings
289
+}
290
+
291
+// NetworkSettingsBase holds basic information about networks
292
+type NetworkSettingsBase struct {
293
+	Bridge                 string
294
+	SandboxID              string
295
+	HairpinMode            bool
296
+	LinkLocalIPv6Address   string
297
+	LinkLocalIPv6PrefixLen int
298
+	Ports                  nat.PortMap
299
+	SandboxKey             string
300
+	SecondaryIPAddresses   []network.Address
301
+	SecondaryIPv6Addresses []network.Address
282 302
 }
283 303
 
284 304
 // MountPoint represents a mount point configuration inside the container.
... ...
@@ -3,6 +3,7 @@ package v1p19
3 3
 
4 4
 import (
5 5
 	"github.com/docker/docker/api/types"
6
+	"github.com/docker/docker/api/types/versions/v1p20"
6 7
 	"github.com/docker/docker/pkg/nat"
7 8
 	"github.com/docker/docker/runconfig"
8 9
 )
... ...
@@ -11,9 +12,10 @@ import (
11 11
 // Note this is not used by the Windows daemon.
12 12
 type ContainerJSON struct {
13 13
 	*types.ContainerJSONBase
14
-	Volumes   map[string]string
15
-	VolumesRW map[string]bool
16
-	Config    *ContainerConfig
14
+	Volumes         map[string]string
15
+	VolumesRW       map[string]bool
16
+	Config          *ContainerConfig
17
+	NetworkSettings *v1p20.NetworkSettings
17 18
 }
18 19
 
19 20
 // ContainerConfig is a backcompatibility struct for APIs prior to 1.20.
... ...
@@ -10,8 +10,9 @@ import (
10 10
 // ContainerJSON is a backcompatibility struct for the API 1.20
11 11
 type ContainerJSON struct {
12 12
 	*types.ContainerJSONBase
13
-	Mounts []types.MountPoint
14
-	Config *ContainerConfig
13
+	Mounts          []types.MountPoint
14
+	Config          *ContainerConfig
15
+	NetworkSettings *NetworkSettings
15 16
 }
16 17
 
17 18
 // ContainerConfig is a backcompatibility struct used in ContainerJSON for the API 1.20
... ...
@@ -31,3 +32,16 @@ type StatsJSON struct {
31 31
 	types.Stats
32 32
 	Network types.NetworkStats `json:"network,omitempty"`
33 33
 }
34
+
35
+// NetworkSettings is a backward compatible struct for APIs prior to 1.21
36
+type NetworkSettings struct {
37
+	types.NetworkSettingsBase
38
+	EndpointID          string
39
+	Gateway             string
40
+	GlobalIPv6Address   string
41
+	GlobalIPv6PrefixLen int
42
+	IPAddress           string
43
+	IPPrefixLen         int
44
+	IPv6Gateway         string
45
+	MacAddress          string
46
+}
... ...
@@ -332,10 +332,6 @@ func (streamConfig *streamConfig) StderrPipe() io.ReadCloser {
332 332
 	return ioutils.NewBufReader(reader)
333 333
 }
334 334
 
335
-func (container *Container) isNetworkAllocated() bool {
336
-	return container.NetworkSettings.IPAddress != ""
337
-}
338
-
339 335
 // cleanup releases any network resources allocated to the container along with any rules
340 336
 // around how containers are linked together.  It also unmounts the container's root filesystem.
341 337
 func (container *Container) cleanup() {
... ...
@@ -88,15 +88,25 @@ func (container *Container) setupLinkedContainers() ([]string, error) {
88 88
 		return nil, err
89 89
 	}
90 90
 
91
+	bridgeSettings := container.NetworkSettings.Networks["bridge"]
92
+	if bridgeSettings == nil {
93
+		return nil, nil
94
+	}
95
+
91 96
 	if len(children) > 0 {
92 97
 		for linkAlias, child := range children {
93 98
 			if !child.IsRunning() {
94 99
 				return nil, derr.ErrorCodeLinkNotRunning.WithArgs(child.Name, linkAlias)
95 100
 			}
96 101
 
102
+			childBridgeSettings := child.NetworkSettings.Networks["bridge"]
103
+			if childBridgeSettings == nil {
104
+				return nil, fmt.Errorf("container %d not attached to default bridge network", child.ID)
105
+			}
106
+
97 107
 			link := links.NewLink(
98
-				container.NetworkSettings.IPAddress,
99
-				child.NetworkSettings.IPAddress,
108
+				bridgeSettings.IPAddress,
109
+				childBridgeSettings.IPAddress,
100 110
 				linkAlias,
101 111
 				child.Config.Env,
102 112
 				child.Config.ExposedPorts,
... ...
@@ -542,13 +552,14 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw
542 542
 		if alias != child.Name[1:] {
543 543
 			aliasList = aliasList + " " + child.Name[1:]
544 544
 		}
545
-		sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost(aliasList, child.NetworkSettings.IPAddress))
545
+		sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost(aliasList, child.NetworkSettings.Networks["bridge"].IPAddress))
546 546
 		cEndpoint, _ := child.getEndpointInNetwork(n)
547 547
 		if cEndpoint != nil && cEndpoint.ID() != "" {
548 548
 			childEndpoints = append(childEndpoints, cEndpoint.ID())
549 549
 		}
550 550
 	}
551 551
 
552
+	bridgeSettings := container.NetworkSettings.Networks["bridge"]
552 553
 	refs := container.daemon.containerGraph().RefPaths(container.ID)
553 554
 	for _, ref := range refs {
554 555
 		if ref.ParentID == "0" {
... ...
@@ -561,8 +572,8 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw
561 561
 		}
562 562
 
563 563
 		if c != nil && !container.daemon.configStore.DisableBridge && container.hostConfig.NetworkMode.IsPrivate() {
564
-			logrus.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, container.NetworkSettings.IPAddress)
565
-			sboxOptions = append(sboxOptions, libnetwork.OptionParentUpdate(c.ID, ref.Name, container.NetworkSettings.IPAddress))
564
+			logrus.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, bridgeSettings.IPAddress)
565
+			sboxOptions = append(sboxOptions, libnetwork.OptionParentUpdate(c.ID, ref.Name, bridgeSettings.IPAddress))
566 566
 			if ep.ID() != "" {
567 567
 				parentEndpoints = append(parentEndpoints, ep.ID())
568 568
 			}
... ...
@@ -583,12 +594,8 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw
583 583
 
584 584
 func isLinkable(child *Container) bool {
585 585
 	// A container is linkable only if it belongs to the default network
586
-	for _, nw := range child.NetworkSettings.Networks {
587
-		if nw == "bridge" {
588
-			return true
589
-		}
590
-	}
591
-	return false
586
+	_, ok := child.NetworkSettings.Networks["bridge"]
587
+	return ok
592 588
 }
593 589
 
594 590
 func (container *Container) getEndpointInNetwork(n libnetwork.Network) (libnetwork.Endpoint, error) {
... ...
@@ -663,6 +670,9 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
663 663
 		return networkSettings, nil
664 664
 	}
665 665
 
666
+	if _, ok := networkSettings.Networks[n.Name()]; !ok {
667
+		networkSettings.Networks[n.Name()] = new(network.EndpointSettings)
668
+	}
666 669
 	networkSettings.Networks[n.Name()].EndpointID = ep.ID()
667 670
 
668 671
 	iface := epInfo.Iface()
... ...
@@ -670,25 +680,14 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
670 670
 		return networkSettings, nil
671 671
 	}
672 672
 
673
-	if networkSettings.EndpointID == "" {
674
-		networkSettings.EndpointID = ep.ID()
675
-	}
676 673
 	if iface.Address() != nil {
677 674
 		ones, _ := iface.Address().Mask.Size()
678
-		if networkSettings.IPAddress == "" || networkSettings.IPPrefixLen == 0 {
679
-			networkSettings.IPAddress = iface.Address().IP.String()
680
-			networkSettings.IPPrefixLen = ones
681
-		}
682 675
 		networkSettings.Networks[n.Name()].IPAddress = iface.Address().IP.String()
683 676
 		networkSettings.Networks[n.Name()].IPPrefixLen = ones
684 677
 	}
685 678
 
686 679
 	if iface.AddressIPv6() != nil && iface.AddressIPv6().IP.To16() != nil {
687 680
 		onesv6, _ := iface.AddressIPv6().Mask.Size()
688
-		if networkSettings.GlobalIPv6Address == "" || networkSettings.GlobalIPv6PrefixLen == 0 {
689
-			networkSettings.GlobalIPv6Address = iface.AddressIPv6().IP.String()
690
-			networkSettings.GlobalIPv6PrefixLen = onesv6
691
-		}
692 681
 		networkSettings.Networks[n.Name()].GlobalIPv6Address = iface.AddressIPv6().IP.String()
693 682
 		networkSettings.Networks[n.Name()].GlobalIPv6PrefixLen = onesv6
694 683
 	}
... ...
@@ -703,9 +702,6 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
703 703
 		return networkSettings, nil
704 704
 	}
705 705
 	if mac, ok := driverInfo[netlabel.MacAddress]; ok {
706
-		if networkSettings.MacAddress == "" {
707
-			networkSettings.MacAddress = mac.(net.HardwareAddr).String()
708
-		}
709 706
 		networkSettings.Networks[n.Name()].MacAddress = mac.(net.HardwareAddr).String()
710 707
 	}
711 708
 
... ...
@@ -718,14 +714,8 @@ func (container *Container) updateJoinInfo(n libnetwork.Network, ep libnetwork.E
718 718
 		// It is not an error to get an empty endpoint info
719 719
 		return nil
720 720
 	}
721
-	if container.NetworkSettings.Gateway == "" {
722
-		container.NetworkSettings.Gateway = epInfo.Gateway().String()
723
-	}
724 721
 	container.NetworkSettings.Networks[n.Name()].Gateway = epInfo.Gateway().String()
725 722
 	if epInfo.GatewayIPv6().To16() != nil {
726
-		if container.NetworkSettings.IPv6Gateway == "" {
727
-			container.NetworkSettings.IPv6Gateway = epInfo.GatewayIPv6().String()
728
-		}
729 723
 		container.NetworkSettings.Networks[n.Name()].IPv6Gateway = epInfo.GatewayIPv6().String()
730 724
 	}
731 725
 
... ...
@@ -1231,17 +1221,6 @@ func (container *Container) disconnectFromNetwork(n libnetwork.Network) error {
1231 1231
 		return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err)
1232 1232
 	}
1233 1233
 
1234
-	if container.NetworkSettings.EndpointID == container.NetworkSettings.Networks[n.Name()].EndpointID {
1235
-		container.NetworkSettings.EndpointID = ""
1236
-		container.NetworkSettings.Gateway = ""
1237
-		container.NetworkSettings.GlobalIPv6Address = ""
1238
-		container.NetworkSettings.GlobalIPv6PrefixLen = 0
1239
-		container.NetworkSettings.IPAddress = ""
1240
-		container.NetworkSettings.IPPrefixLen = 0
1241
-		container.NetworkSettings.IPv6Gateway = ""
1242
-		container.NetworkSettings.MacAddress = ""
1243
-
1244
-	}
1245 1234
 	delete(container.NetworkSettings.Networks, n.Name())
1246 1235
 	return nil
1247 1236
 }
... ...
@@ -6,6 +6,7 @@ import (
6 6
 
7 7
 	"github.com/docker/docker/api/types"
8 8
 	"github.com/docker/docker/api/types/versions/v1p20"
9
+	"github.com/docker/docker/daemon/network"
9 10
 )
10 11
 
11 12
 // ContainerInspect returns low-level information about a
... ...
@@ -26,8 +27,22 @@ func (daemon *Daemon) ContainerInspect(name string, size bool) (*types.Container
26 26
 	}
27 27
 
28 28
 	mountPoints := addMountPoints(container)
29
+	networkSettings := &types.NetworkSettings{
30
+		types.NetworkSettingsBase{
31
+			Bridge:                 container.NetworkSettings.Bridge,
32
+			SandboxID:              container.NetworkSettings.SandboxID,
33
+			HairpinMode:            container.NetworkSettings.HairpinMode,
34
+			LinkLocalIPv6Address:   container.NetworkSettings.LinkLocalIPv6Address,
35
+			LinkLocalIPv6PrefixLen: container.NetworkSettings.LinkLocalIPv6PrefixLen,
36
+			Ports:                  container.NetworkSettings.Ports,
37
+			SandboxKey:             container.NetworkSettings.SandboxKey,
38
+			SecondaryIPAddresses:   container.NetworkSettings.SecondaryIPAddresses,
39
+			SecondaryIPv6Addresses: container.NetworkSettings.SecondaryIPv6Addresses,
40
+		},
41
+		container.NetworkSettings.Networks,
42
+	}
29 43
 
30
-	return &types.ContainerJSON{base, mountPoints, container.Config}, nil
44
+	return &types.ContainerJSON{base, mountPoints, container.Config, networkSettings}, nil
31 45
 }
32 46
 
33 47
 // ContainerInspect120 serializes the master version of a container into a json type.
... ...
@@ -53,8 +68,9 @@ func (daemon *Daemon) ContainerInspect120(name string) (*v1p20.ContainerJSON, er
53 53
 		container.Config.ExposedPorts,
54 54
 		container.hostConfig.VolumeDriver,
55 55
 	}
56
+	networkSettings := getBackwardsCompatibleNetworkSettings(container.NetworkSettings)
56 57
 
57
-	return &v1p20.ContainerJSON{base, mountPoints, config}, nil
58
+	return &v1p20.ContainerJSON{base, mountPoints, config, networkSettings}, nil
58 59
 }
59 60
 
60 61
 func (daemon *Daemon) getInspectData(container *Container, size bool) (*types.ContainerJSONBase, error) {
... ...
@@ -91,22 +107,21 @@ func (daemon *Daemon) getInspectData(container *Container, size bool) (*types.Co
91 91
 	}
92 92
 
93 93
 	contJSONBase := &types.ContainerJSONBase{
94
-		ID:              container.ID,
95
-		Created:         container.Created.Format(time.RFC3339Nano),
96
-		Path:            container.Path,
97
-		Args:            container.Args,
98
-		State:           containerState,
99
-		Image:           container.ImageID,
100
-		NetworkSettings: container.NetworkSettings,
101
-		LogPath:         container.LogPath,
102
-		Name:            container.Name,
103
-		RestartCount:    container.RestartCount,
104
-		Driver:          container.Driver,
105
-		ExecDriver:      container.ExecDriver,
106
-		MountLabel:      container.MountLabel,
107
-		ProcessLabel:    container.ProcessLabel,
108
-		ExecIDs:         container.getExecIDs(),
109
-		HostConfig:      &hostConfig,
94
+		ID:           container.ID,
95
+		Created:      container.Created.Format(time.RFC3339Nano),
96
+		Path:         container.Path,
97
+		Args:         container.Args,
98
+		State:        containerState,
99
+		Image:        container.ImageID,
100
+		LogPath:      container.LogPath,
101
+		Name:         container.Name,
102
+		RestartCount: container.RestartCount,
103
+		Driver:       container.Driver,
104
+		ExecDriver:   container.ExecDriver,
105
+		MountLabel:   container.MountLabel,
106
+		ProcessLabel: container.ProcessLabel,
107
+		ExecIDs:      container.getExecIDs(),
108
+		HostConfig:   &hostConfig,
110 109
 	}
111 110
 
112 111
 	var (
... ...
@@ -151,3 +166,30 @@ func (daemon *Daemon) VolumeInspect(name string) (*types.Volume, error) {
151 151
 	}
152 152
 	return volumeToAPIType(v), nil
153 153
 }
154
+
155
+func getBackwardsCompatibleNetworkSettings(settings *network.Settings) *v1p20.NetworkSettings {
156
+	result := &v1p20.NetworkSettings{
157
+		NetworkSettingsBase: types.NetworkSettingsBase{
158
+			Bridge:                 settings.Bridge,
159
+			SandboxID:              settings.SandboxID,
160
+			HairpinMode:            settings.HairpinMode,
161
+			LinkLocalIPv6Address:   settings.LinkLocalIPv6Address,
162
+			LinkLocalIPv6PrefixLen: settings.LinkLocalIPv6PrefixLen,
163
+			Ports:                  settings.Ports,
164
+			SandboxKey:             settings.SandboxKey,
165
+			SecondaryIPAddresses:   settings.SecondaryIPAddresses,
166
+			SecondaryIPv6Addresses: settings.SecondaryIPv6Addresses,
167
+		},
168
+	}
169
+	if bridgeSettings := settings.Networks["bridge"]; bridgeSettings != nil {
170
+		result.EndpointID = bridgeSettings.EndpointID
171
+		result.Gateway = bridgeSettings.Gateway
172
+		result.GlobalIPv6Address = bridgeSettings.GlobalIPv6Address
173
+		result.GlobalIPv6PrefixLen = bridgeSettings.GlobalIPv6PrefixLen
174
+		result.IPAddress = bridgeSettings.IPAddress
175
+		result.IPPrefixLen = bridgeSettings.IPPrefixLen
176
+		result.IPv6Gateway = bridgeSettings.IPv6Gateway
177
+		result.MacAddress = bridgeSettings.MacAddress
178
+	}
179
+	return result
180
+}
... ...
@@ -50,8 +50,9 @@ func (daemon *Daemon) ContainerInspectPre120(name string) (*v1p19.ContainerJSON,
50 50
 		container.hostConfig.CPUShares,
51 51
 		container.hostConfig.CpusetCpus,
52 52
 	}
53
+	networkSettings := getBackwardsCompatibleNetworkSettings(container.NetworkSettings)
53 54
 
54
-	return &v1p19.ContainerJSON{base, volumes, volumesRW, config}, nil
55
+	return &v1p19.ContainerJSON{base, volumes, volumesRW, config, networkSettings}, nil
55 56
 }
56 57
 
57 58
 func addMountPoints(container *Container) []types.MountPoint {
... ...
@@ -26,18 +26,10 @@ type IPAMConfig struct {
26 26
 // TODO Windows. Many of these fields can be factored out.,
27 27
 type Settings struct {
28 28
 	Bridge                 string
29
-	EndpointID             string // this is for backward compatibility
30 29
 	SandboxID              string
31
-	Gateway                string // this is for backward compatibility
32
-	GlobalIPv6Address      string // this is for backward compatibility
33
-	GlobalIPv6PrefixLen    int    // this is for backward compatibility
34 30
 	HairpinMode            bool
35
-	IPAddress              string // this is for backward compatibility
36
-	IPPrefixLen            int    // this is for backward compatibility
37
-	IPv6Gateway            string // this is for backward compatibility
38 31
 	LinkLocalIPv6Address   string
39 32
 	LinkLocalIPv6PrefixLen int
40
-	MacAddress             string // this is for backward compatibility
41 33
 	Networks               map[string]*EndpointSettings
42 34
 	Ports                  nat.PortMap
43 35
 	SandboxKey             string
... ...
@@ -303,7 +303,7 @@ func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) {
303 303
 		c.Fatalf("Could not run container: %s, %v", out, err)
304 304
 	}
305 305
 
306
-	out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.LinkLocalIPv6Address}}'", "ipv6test")
306
+	out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'", "ipv6test")
307 307
 	out = strings.Trim(out, " \r\n'")
308 308
 
309 309
 	if err != nil {
... ...
@@ -314,7 +314,7 @@ func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) {
314 314
 		c.Fatalf("Container should have a link-local IPv6 address")
315 315
 	}
316 316
 
317
-	out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.GlobalIPv6Address}}'", "ipv6test")
317
+	out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test")
318 318
 	out = strings.Trim(out, " \r\n'")
319 319
 
320 320
 	if err != nil {
... ...
@@ -351,7 +351,7 @@ func (s *DockerSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
351 351
 		c.Fatalf("Could not run container: %s, %v", out, err)
352 352
 	}
353 353
 
354
-	out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.LinkLocalIPv6Address}}'", "ipv6test")
354
+	out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'", "ipv6test")
355 355
 	out = strings.Trim(out, " \r\n'")
356 356
 
357 357
 	if err != nil {
... ...
@@ -362,7 +362,7 @@ func (s *DockerSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
362 362
 		c.Fatalf("Container should have a link-local IPv6 address")
363 363
 	}
364 364
 
365
-	out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.GlobalIPv6Address}}'", "ipv6test")
365
+	out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test")
366 366
 	out = strings.Trim(out, " \r\n'")
367 367
 
368 368
 	if err != nil {
... ...
@@ -135,7 +135,7 @@ func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) {
135 135
 	out, _ := dockerCmd(c, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top")
136 136
 	id := strings.TrimSpace(string(out))
137 137
 
138
-	realIP, err := inspectField("one", "NetworkSettings.IPAddress")
138
+	realIP, err := inspectField("one", "NetworkSettings.Networks.bridge.IPAddress")
139 139
 	if err != nil {
140 140
 		c.Fatal(err)
141 141
 	}
... ...
@@ -156,7 +156,7 @@ func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) {
156 156
 	c.Assert(ip, checker.Equals, realIP)
157 157
 
158 158
 	dockerCmd(c, "restart", "one")
159
-	realIP, err = inspectField("one", "NetworkSettings.IPAddress")
159
+	realIP, err = inspectField("one", "NetworkSettings.Networks.bridge.IPAddress")
160 160
 	c.Assert(err, checker.IsNil)
161 161
 
162 162
 	content, err = readContainerFileWithExec(id, "/etc/hosts")
... ...
@@ -184,7 +184,7 @@ func (s *DockerSuite) TestRunLinksContainerWithContainerName(c *check.C) {
184 184
 	testRequires(c, DaemonIsLinux)
185 185
 	dockerCmd(c, "run", "-i", "-t", "-d", "--name", "parent", "busybox")
186 186
 
187
-	ip, err := inspectField("parent", "NetworkSettings.IPAddress")
187
+	ip, err := inspectField("parent", "NetworkSettings.Networks.bridge.IPAddress")
188 188
 	c.Assert(err, check.IsNil)
189 189
 
190 190
 	out, _ := dockerCmd(c, "run", "--link", "parent:test", "busybox", "/bin/cat", "/etc/hosts")
... ...
@@ -201,7 +201,7 @@ func (s *DockerSuite) TestRunLinksContainerWithContainerId(c *check.C) {
201 201
 	cID, _ := dockerCmd(c, "run", "-i", "-t", "-d", "busybox")
202 202
 
203 203
 	cID = strings.TrimSpace(cID)
204
-	ip, err := inspectField(cID, "NetworkSettings.IPAddress")
204
+	ip, err := inspectField(cID, "NetworkSettings.Networks.bridge.IPAddress")
205 205
 	c.Assert(err, check.IsNil)
206 206
 
207 207
 	out, _ := dockerCmd(c, "run", "--link", cID+":test", "busybox", "/bin/cat", "/etc/hosts")
... ...
@@ -1833,7 +1833,7 @@ func (s *DockerSuite) TestRunInspectMacAddress(c *check.C) {
1833 1833
 	out, _ := dockerCmd(c, "run", "-d", "--mac-address="+mac, "busybox", "top")
1834 1834
 
1835 1835
 	id := strings.TrimSpace(out)
1836
-	inspectedMac, err := inspectField(id, "NetworkSettings.MacAddress")
1836
+	inspectedMac, err := inspectField(id, "NetworkSettings.Networks.bridge.MacAddress")
1837 1837
 	c.Assert(err, check.IsNil)
1838 1838
 	if inspectedMac != mac {
1839 1839
 		c.Fatalf("docker inspect outputs wrong MAC address: %q, should be: %q", inspectedMac, mac)
... ...
@@ -1856,7 +1856,7 @@ func (s *DockerSuite) TestRunDeallocatePortOnMissingIptablesRule(c *check.C) {
1856 1856
 	out, _ := dockerCmd(c, "run", "-d", "-p", "23:23", "busybox", "top")
1857 1857
 
1858 1858
 	id := strings.TrimSpace(out)
1859
-	ip, err := inspectField(id, "NetworkSettings.IPAddress")
1859
+	ip, err := inspectField(id, "NetworkSettings.Networks.bridge.IPAddress")
1860 1860
 	c.Assert(err, check.IsNil)
1861 1861
 	iptCmd := exec.Command("iptables", "-D", "DOCKER", "-d", fmt.Sprintf("%s/32", ip),
1862 1862
 		"!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT")
... ...
@@ -3403,7 +3403,7 @@ func (s *DockerSuite) TestRunNetworkNotInitializedNoneMode(c *check.C) {
3403 3403
 	testRequires(c, DaemonIsLinux)
3404 3404
 	out, _ := dockerCmd(c, "run", "-d", "--net=none", "busybox", "top")
3405 3405
 	id := strings.TrimSpace(out)
3406
-	res, err := inspectField(id, "NetworkSettings.IPAddress")
3406
+	res, err := inspectField(id, "NetworkSettings.Networks.none.IPAddress")
3407 3407
 	c.Assert(err, check.IsNil)
3408 3408
 	if res != "" {
3409 3409
 		c.Fatalf("For 'none' mode network must not be initialized, but container got IP: %s", res)
... ...
@@ -788,7 +788,11 @@ func findContainerIP(c *check.C, id string, network string) string {
788 788
 }
789 789
 
790 790
 func (d *Daemon) findContainerIP(id string) string {
791
-	return findContainerIP(d.c, id, "--host")
791
+	out, err := d.Cmd("inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.bridge.IPAddress }}'"), id)
792
+	if err != nil {
793
+		d.c.Log(err)
794
+	}
795
+	return strings.Trim(out, " \r\n'")
792 796
 }
793 797
 
794 798
 func getContainerCount() (int, error) {