1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

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>
This commit is contained in:
David Calavera 2015-10-26 22:35:49 -04:00 committed by Tibor Vass
parent 1b9a08e719
commit 25682577c9
12 changed files with 143 additions and 93 deletions

View file

@ -5,6 +5,7 @@ import (
"time"
"github.com/docker/docker/daemon/network"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/registry"
"github.com/docker/docker/runconfig"
@ -255,7 +256,6 @@ type ContainerJSONBase struct {
Args []string
State *ContainerState
Image string
NetworkSettings *network.Settings
ResolvConfPath string
HostnamePath string
HostsPath string
@ -277,8 +277,28 @@ type ContainerJSONBase struct {
// ContainerJSON is newly used struct along with MountPoint
type ContainerJSON struct {
*ContainerJSONBase
Mounts []MountPoint
Config *runconfig.Config
Mounts []MountPoint
Config *runconfig.Config
NetworkSettings *NetworkSettings
}
// NetworkSettings exposes the network settings in the api
type NetworkSettings struct {
NetworkSettingsBase
Networks map[string]*network.EndpointSettings
}
// NetworkSettingsBase holds basic information about networks
type NetworkSettingsBase struct {
Bridge string
SandboxID string
HairpinMode bool
LinkLocalIPv6Address string
LinkLocalIPv6PrefixLen int
Ports nat.PortMap
SandboxKey string
SecondaryIPAddresses []network.Address
SecondaryIPv6Addresses []network.Address
}
// MountPoint represents a mount point configuration inside the container.

View file

@ -3,6 +3,7 @@ package v1p19
import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions/v1p20"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/runconfig"
)
@ -11,9 +12,10 @@ import (
// Note this is not used by the Windows daemon.
type ContainerJSON struct {
*types.ContainerJSONBase
Volumes map[string]string
VolumesRW map[string]bool
Config *ContainerConfig
Volumes map[string]string
VolumesRW map[string]bool
Config *ContainerConfig
NetworkSettings *v1p20.NetworkSettings
}
// ContainerConfig is a backcompatibility struct for APIs prior to 1.20.

View file

@ -10,8 +10,9 @@ import (
// ContainerJSON is a backcompatibility struct for the API 1.20
type ContainerJSON struct {
*types.ContainerJSONBase
Mounts []types.MountPoint
Config *ContainerConfig
Mounts []types.MountPoint
Config *ContainerConfig
NetworkSettings *NetworkSettings
}
// ContainerConfig is a backcompatibility struct used in ContainerJSON for the API 1.20
@ -31,3 +32,16 @@ type StatsJSON struct {
types.Stats
Network types.NetworkStats `json:"network,omitempty"`
}
// NetworkSettings is a backward compatible struct for APIs prior to 1.21
type NetworkSettings struct {
types.NetworkSettingsBase
EndpointID string
Gateway string
GlobalIPv6Address string
GlobalIPv6PrefixLen int
IPAddress string
IPPrefixLen int
IPv6Gateway string
MacAddress string
}

View file

@ -332,10 +332,6 @@ func (streamConfig *streamConfig) StderrPipe() io.ReadCloser {
return ioutils.NewBufReader(reader)
}
func (container *Container) isNetworkAllocated() bool {
return container.NetworkSettings.IPAddress != ""
}
// cleanup releases any network resources allocated to the container along with any rules
// around how containers are linked together. It also unmounts the container's root filesystem.
func (container *Container) cleanup() {

View file

@ -88,15 +88,25 @@ func (container *Container) setupLinkedContainers() ([]string, error) {
return nil, err
}
bridgeSettings := container.NetworkSettings.Networks["bridge"]
if bridgeSettings == nil {
return nil, nil
}
if len(children) > 0 {
for linkAlias, child := range children {
if !child.IsRunning() {
return nil, derr.ErrorCodeLinkNotRunning.WithArgs(child.Name, linkAlias)
}
childBridgeSettings := child.NetworkSettings.Networks["bridge"]
if childBridgeSettings == nil {
return nil, fmt.Errorf("container %d not attached to default bridge network", child.ID)
}
link := links.NewLink(
container.NetworkSettings.IPAddress,
child.NetworkSettings.IPAddress,
bridgeSettings.IPAddress,
childBridgeSettings.IPAddress,
linkAlias,
child.Config.Env,
child.Config.ExposedPorts,
@ -542,13 +552,14 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw
if alias != child.Name[1:] {
aliasList = aliasList + " " + child.Name[1:]
}
sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost(aliasList, child.NetworkSettings.IPAddress))
sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost(aliasList, child.NetworkSettings.Networks["bridge"].IPAddress))
cEndpoint, _ := child.getEndpointInNetwork(n)
if cEndpoint != nil && cEndpoint.ID() != "" {
childEndpoints = append(childEndpoints, cEndpoint.ID())
}
}
bridgeSettings := container.NetworkSettings.Networks["bridge"]
refs := container.daemon.containerGraph().RefPaths(container.ID)
for _, ref := range refs {
if ref.ParentID == "0" {
@ -561,8 +572,8 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw
}
if c != nil && !container.daemon.configStore.DisableBridge && container.hostConfig.NetworkMode.IsPrivate() {
logrus.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, container.NetworkSettings.IPAddress)
sboxOptions = append(sboxOptions, libnetwork.OptionParentUpdate(c.ID, ref.Name, container.NetworkSettings.IPAddress))
logrus.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, bridgeSettings.IPAddress)
sboxOptions = append(sboxOptions, libnetwork.OptionParentUpdate(c.ID, ref.Name, bridgeSettings.IPAddress))
if ep.ID() != "" {
parentEndpoints = append(parentEndpoints, ep.ID())
}
@ -583,12 +594,8 @@ func (container *Container) buildSandboxOptions(n libnetwork.Network) ([]libnetw
func isLinkable(child *Container) bool {
// A container is linkable only if it belongs to the default network
for _, nw := range child.NetworkSettings.Networks {
if nw == "bridge" {
return true
}
}
return false
_, ok := child.NetworkSettings.Networks["bridge"]
return ok
}
func (container *Container) getEndpointInNetwork(n libnetwork.Network) (libnetwork.Endpoint, error) {
@ -663,6 +670,9 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
return networkSettings, nil
}
if _, ok := networkSettings.Networks[n.Name()]; !ok {
networkSettings.Networks[n.Name()] = new(network.EndpointSettings)
}
networkSettings.Networks[n.Name()].EndpointID = ep.ID()
iface := epInfo.Iface()
@ -670,25 +680,14 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
return networkSettings, nil
}
if networkSettings.EndpointID == "" {
networkSettings.EndpointID = ep.ID()
}
if iface.Address() != nil {
ones, _ := iface.Address().Mask.Size()
if networkSettings.IPAddress == "" || networkSettings.IPPrefixLen == 0 {
networkSettings.IPAddress = iface.Address().IP.String()
networkSettings.IPPrefixLen = ones
}
networkSettings.Networks[n.Name()].IPAddress = iface.Address().IP.String()
networkSettings.Networks[n.Name()].IPPrefixLen = ones
}
if iface.AddressIPv6() != nil && iface.AddressIPv6().IP.To16() != nil {
onesv6, _ := iface.AddressIPv6().Mask.Size()
if networkSettings.GlobalIPv6Address == "" || networkSettings.GlobalIPv6PrefixLen == 0 {
networkSettings.GlobalIPv6Address = iface.AddressIPv6().IP.String()
networkSettings.GlobalIPv6PrefixLen = onesv6
}
networkSettings.Networks[n.Name()].GlobalIPv6Address = iface.AddressIPv6().IP.String()
networkSettings.Networks[n.Name()].GlobalIPv6PrefixLen = onesv6
}
@ -703,9 +702,6 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
return networkSettings, nil
}
if mac, ok := driverInfo[netlabel.MacAddress]; ok {
if networkSettings.MacAddress == "" {
networkSettings.MacAddress = mac.(net.HardwareAddr).String()
}
networkSettings.Networks[n.Name()].MacAddress = mac.(net.HardwareAddr).String()
}
@ -718,14 +714,8 @@ func (container *Container) updateJoinInfo(n libnetwork.Network, ep libnetwork.E
// It is not an error to get an empty endpoint info
return nil
}
if container.NetworkSettings.Gateway == "" {
container.NetworkSettings.Gateway = epInfo.Gateway().String()
}
container.NetworkSettings.Networks[n.Name()].Gateway = epInfo.Gateway().String()
if epInfo.GatewayIPv6().To16() != nil {
if container.NetworkSettings.IPv6Gateway == "" {
container.NetworkSettings.IPv6Gateway = epInfo.GatewayIPv6().String()
}
container.NetworkSettings.Networks[n.Name()].IPv6Gateway = epInfo.GatewayIPv6().String()
}
@ -1231,17 +1221,6 @@ func (container *Container) disconnectFromNetwork(n libnetwork.Network) error {
return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err)
}
if container.NetworkSettings.EndpointID == container.NetworkSettings.Networks[n.Name()].EndpointID {
container.NetworkSettings.EndpointID = ""
container.NetworkSettings.Gateway = ""
container.NetworkSettings.GlobalIPv6Address = ""
container.NetworkSettings.GlobalIPv6PrefixLen = 0
container.NetworkSettings.IPAddress = ""
container.NetworkSettings.IPPrefixLen = 0
container.NetworkSettings.IPv6Gateway = ""
container.NetworkSettings.MacAddress = ""
}
delete(container.NetworkSettings.Networks, n.Name())
return nil
}

View file

@ -6,6 +6,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions/v1p20"
"github.com/docker/docker/daemon/network"
)
// ContainerInspect returns low-level information about a
@ -26,8 +27,22 @@ func (daemon *Daemon) ContainerInspect(name string, size bool) (*types.Container
}
mountPoints := addMountPoints(container)
networkSettings := &types.NetworkSettings{
types.NetworkSettingsBase{
Bridge: container.NetworkSettings.Bridge,
SandboxID: container.NetworkSettings.SandboxID,
HairpinMode: container.NetworkSettings.HairpinMode,
LinkLocalIPv6Address: container.NetworkSettings.LinkLocalIPv6Address,
LinkLocalIPv6PrefixLen: container.NetworkSettings.LinkLocalIPv6PrefixLen,
Ports: container.NetworkSettings.Ports,
SandboxKey: container.NetworkSettings.SandboxKey,
SecondaryIPAddresses: container.NetworkSettings.SecondaryIPAddresses,
SecondaryIPv6Addresses: container.NetworkSettings.SecondaryIPv6Addresses,
},
container.NetworkSettings.Networks,
}
return &types.ContainerJSON{base, mountPoints, container.Config}, nil
return &types.ContainerJSON{base, mountPoints, container.Config, networkSettings}, nil
}
// 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
container.Config.ExposedPorts,
container.hostConfig.VolumeDriver,
}
networkSettings := getBackwardsCompatibleNetworkSettings(container.NetworkSettings)
return &v1p20.ContainerJSON{base, mountPoints, config}, nil
return &v1p20.ContainerJSON{base, mountPoints, config, networkSettings}, nil
}
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
}
contJSONBase := &types.ContainerJSONBase{
ID: container.ID,
Created: container.Created.Format(time.RFC3339Nano),
Path: container.Path,
Args: container.Args,
State: containerState,
Image: container.ImageID,
NetworkSettings: container.NetworkSettings,
LogPath: container.LogPath,
Name: container.Name,
RestartCount: container.RestartCount,
Driver: container.Driver,
ExecDriver: container.ExecDriver,
MountLabel: container.MountLabel,
ProcessLabel: container.ProcessLabel,
ExecIDs: container.getExecIDs(),
HostConfig: &hostConfig,
ID: container.ID,
Created: container.Created.Format(time.RFC3339Nano),
Path: container.Path,
Args: container.Args,
State: containerState,
Image: container.ImageID,
LogPath: container.LogPath,
Name: container.Name,
RestartCount: container.RestartCount,
Driver: container.Driver,
ExecDriver: container.ExecDriver,
MountLabel: container.MountLabel,
ProcessLabel: container.ProcessLabel,
ExecIDs: container.getExecIDs(),
HostConfig: &hostConfig,
}
var (
@ -151,3 +166,30 @@ func (daemon *Daemon) VolumeInspect(name string) (*types.Volume, error) {
}
return volumeToAPIType(v), nil
}
func getBackwardsCompatibleNetworkSettings(settings *network.Settings) *v1p20.NetworkSettings {
result := &v1p20.NetworkSettings{
NetworkSettingsBase: types.NetworkSettingsBase{
Bridge: settings.Bridge,
SandboxID: settings.SandboxID,
HairpinMode: settings.HairpinMode,
LinkLocalIPv6Address: settings.LinkLocalIPv6Address,
LinkLocalIPv6PrefixLen: settings.LinkLocalIPv6PrefixLen,
Ports: settings.Ports,
SandboxKey: settings.SandboxKey,
SecondaryIPAddresses: settings.SecondaryIPAddresses,
SecondaryIPv6Addresses: settings.SecondaryIPv6Addresses,
},
}
if bridgeSettings := settings.Networks["bridge"]; bridgeSettings != nil {
result.EndpointID = bridgeSettings.EndpointID
result.Gateway = bridgeSettings.Gateway
result.GlobalIPv6Address = bridgeSettings.GlobalIPv6Address
result.GlobalIPv6PrefixLen = bridgeSettings.GlobalIPv6PrefixLen
result.IPAddress = bridgeSettings.IPAddress
result.IPPrefixLen = bridgeSettings.IPPrefixLen
result.IPv6Gateway = bridgeSettings.IPv6Gateway
result.MacAddress = bridgeSettings.MacAddress
}
return result
}

View file

@ -50,8 +50,9 @@ func (daemon *Daemon) ContainerInspectPre120(name string) (*v1p19.ContainerJSON,
container.hostConfig.CPUShares,
container.hostConfig.CpusetCpus,
}
networkSettings := getBackwardsCompatibleNetworkSettings(container.NetworkSettings)
return &v1p19.ContainerJSON{base, volumes, volumesRW, config}, nil
return &v1p19.ContainerJSON{base, volumes, volumesRW, config, networkSettings}, nil
}
func addMountPoints(container *Container) []types.MountPoint {

View file

@ -26,18 +26,10 @@ type IPAMConfig struct {
// TODO Windows. Many of these fields can be factored out.,
type Settings struct {
Bridge string
EndpointID string // this is for backward compatibility
SandboxID string
Gateway string // this is for backward compatibility
GlobalIPv6Address string // this is for backward compatibility
GlobalIPv6PrefixLen int // this is for backward compatibility
HairpinMode bool
IPAddress string // this is for backward compatibility
IPPrefixLen int // this is for backward compatibility
IPv6Gateway string // this is for backward compatibility
LinkLocalIPv6Address string
LinkLocalIPv6PrefixLen int
MacAddress string // this is for backward compatibility
Networks map[string]*EndpointSettings
Ports nat.PortMap
SandboxKey string

View file

@ -303,7 +303,7 @@ func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) {
c.Fatalf("Could not run container: %s, %v", out, err)
}
out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.LinkLocalIPv6Address}}'", "ipv6test")
out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'", "ipv6test")
out = strings.Trim(out, " \r\n'")
if err != nil {
@ -314,7 +314,7 @@ func (s *DockerSuite) TestDaemonIPv6Enabled(c *check.C) {
c.Fatalf("Container should have a link-local IPv6 address")
}
out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.GlobalIPv6Address}}'", "ipv6test")
out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test")
out = strings.Trim(out, " \r\n'")
if err != nil {
@ -351,7 +351,7 @@ func (s *DockerSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
c.Fatalf("Could not run container: %s, %v", out, err)
}
out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.LinkLocalIPv6Address}}'", "ipv6test")
out, err := d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'", "ipv6test")
out = strings.Trim(out, " \r\n'")
if err != nil {
@ -362,7 +362,7 @@ func (s *DockerSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
c.Fatalf("Container should have a link-local IPv6 address")
}
out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.GlobalIPv6Address}}'", "ipv6test")
out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test")
out = strings.Trim(out, " \r\n'")
if err != nil {

View file

@ -135,7 +135,7 @@ func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) {
out, _ := dockerCmd(c, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top")
id := strings.TrimSpace(string(out))
realIP, err := inspectField("one", "NetworkSettings.IPAddress")
realIP, err := inspectField("one", "NetworkSettings.Networks.bridge.IPAddress")
if err != nil {
c.Fatal(err)
}
@ -156,7 +156,7 @@ func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) {
c.Assert(ip, checker.Equals, realIP)
dockerCmd(c, "restart", "one")
realIP, err = inspectField("one", "NetworkSettings.IPAddress")
realIP, err = inspectField("one", "NetworkSettings.Networks.bridge.IPAddress")
c.Assert(err, checker.IsNil)
content, err = readContainerFileWithExec(id, "/etc/hosts")

View file

@ -184,7 +184,7 @@ func (s *DockerSuite) TestRunLinksContainerWithContainerName(c *check.C) {
testRequires(c, DaemonIsLinux)
dockerCmd(c, "run", "-i", "-t", "-d", "--name", "parent", "busybox")
ip, err := inspectField("parent", "NetworkSettings.IPAddress")
ip, err := inspectField("parent", "NetworkSettings.Networks.bridge.IPAddress")
c.Assert(err, check.IsNil)
out, _ := dockerCmd(c, "run", "--link", "parent:test", "busybox", "/bin/cat", "/etc/hosts")
@ -201,7 +201,7 @@ func (s *DockerSuite) TestRunLinksContainerWithContainerId(c *check.C) {
cID, _ := dockerCmd(c, "run", "-i", "-t", "-d", "busybox")
cID = strings.TrimSpace(cID)
ip, err := inspectField(cID, "NetworkSettings.IPAddress")
ip, err := inspectField(cID, "NetworkSettings.Networks.bridge.IPAddress")
c.Assert(err, check.IsNil)
out, _ := dockerCmd(c, "run", "--link", cID+":test", "busybox", "/bin/cat", "/etc/hosts")
@ -1833,7 +1833,7 @@ func (s *DockerSuite) TestRunInspectMacAddress(c *check.C) {
out, _ := dockerCmd(c, "run", "-d", "--mac-address="+mac, "busybox", "top")
id := strings.TrimSpace(out)
inspectedMac, err := inspectField(id, "NetworkSettings.MacAddress")
inspectedMac, err := inspectField(id, "NetworkSettings.Networks.bridge.MacAddress")
c.Assert(err, check.IsNil)
if inspectedMac != mac {
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) {
out, _ := dockerCmd(c, "run", "-d", "-p", "23:23", "busybox", "top")
id := strings.TrimSpace(out)
ip, err := inspectField(id, "NetworkSettings.IPAddress")
ip, err := inspectField(id, "NetworkSettings.Networks.bridge.IPAddress")
c.Assert(err, check.IsNil)
iptCmd := exec.Command("iptables", "-D", "DOCKER", "-d", fmt.Sprintf("%s/32", ip),
"!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT")
@ -3403,7 +3403,7 @@ func (s *DockerSuite) TestRunNetworkNotInitializedNoneMode(c *check.C) {
testRequires(c, DaemonIsLinux)
out, _ := dockerCmd(c, "run", "-d", "--net=none", "busybox", "top")
id := strings.TrimSpace(out)
res, err := inspectField(id, "NetworkSettings.IPAddress")
res, err := inspectField(id, "NetworkSettings.Networks.none.IPAddress")
c.Assert(err, check.IsNil)
if res != "" {
c.Fatalf("For 'none' mode network must not be initialized, but container got IP: %s", res)

View file

@ -788,7 +788,11 @@ func findContainerIP(c *check.C, id string, network string) string {
}
func (d *Daemon) findContainerIP(id string) string {
return findContainerIP(d.c, id, "--host")
out, err := d.Cmd("inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.bridge.IPAddress }}'"), id)
if err != nil {
d.c.Log(err)
}
return strings.Trim(out, " \r\n'")
}
func getContainerCount() (int, error) {