Fix docker inspect container only reports last assigned information

Signed-off-by: Lei Jitang <leijitang@huawei.com>
This commit is contained in:
Lei Jitang 2015-10-26 08:00:49 -04:00 committed by Tibor Vass
parent bf9f2691ca
commit 1b9a08e719
6 changed files with 95 additions and 52 deletions

View file

@ -615,10 +615,6 @@ func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint, networkSett
return networkSettings, nil
}
if mac, ok := driverInfo[netlabel.MacAddress]; ok {
networkSettings.MacAddress = mac.(net.HardwareAddr).String()
}
networkSettings.Ports = nat.PortMap{}
if expData, ok := driverInfo[netlabel.ExposedPorts]; ok {
@ -652,7 +648,7 @@ func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint, networkSett
return networkSettings, nil
}
func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSettings *network.Settings) (*network.Settings, error) {
func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwork.Endpoint, networkSettings *network.Settings) (*network.Settings, error) {
if ep == nil {
return nil, derr.ErrorCodeEmptyEndpoint
}
@ -667,36 +663,70 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet
return networkSettings, nil
}
networkSettings.Networks[n.Name()].EndpointID = ep.ID()
iface := epInfo.Iface()
if iface == nil {
return networkSettings, nil
}
if networkSettings.EndpointID == "" {
networkSettings.EndpointID = ep.ID()
}
if iface.Address() != nil {
ones, _ := iface.Address().Mask.Size()
networkSettings.IPAddress = iface.Address().IP.String()
networkSettings.IPPrefixLen = ones
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()
networkSettings.GlobalIPv6Address = iface.AddressIPv6().IP.String()
networkSettings.GlobalIPv6PrefixLen = onesv6
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
}
driverInfo, err := ep.DriverInfo()
if err != nil {
return nil, err
}
if driverInfo == nil {
// It is not an error for epInfo to be nil
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()
}
return networkSettings, nil
}
func (container *Container) updateJoinInfo(ep libnetwork.Endpoint) error {
func (container *Container) updateJoinInfo(n libnetwork.Network, ep libnetwork.Endpoint) error {
epInfo := ep.Info()
if epInfo == nil {
// It is not an error to get an empty endpoint info
return nil
}
container.NetworkSettings.Gateway = epInfo.Gateway().String()
if container.NetworkSettings.Gateway == "" {
container.NetworkSettings.Gateway = epInfo.Gateway().String()
}
container.NetworkSettings.Networks[n.Name()].Gateway = epInfo.Gateway().String()
if epInfo.GatewayIPv6().To16() != nil {
container.NetworkSettings.IPv6Gateway = epInfo.GatewayIPv6().String()
if container.NetworkSettings.IPv6Gateway == "" {
container.NetworkSettings.IPv6Gateway = epInfo.GatewayIPv6().String()
}
container.NetworkSettings.Networks[n.Name()].IPv6Gateway = epInfo.GatewayIPv6().String()
}
return nil
@ -704,11 +734,10 @@ func (container *Container) updateJoinInfo(ep libnetwork.Endpoint) error {
func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
if container.NetworkSettings == nil {
container.NetworkSettings = &network.Settings{Networks: []string{}}
container.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)}
}
settings := container.NetworkSettings
for _, s := range settings.Networks {
for s := range container.NetworkSettings.Networks {
sn, err := container.daemon.FindNetwork(s)
if err != nil {
continue
@ -727,7 +756,7 @@ func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
return runconfig.ErrConflictNoNetwork
}
}
settings.Networks = append(settings.Networks, n.Name())
container.NetworkSettings.Networks[n.Name()] = new(network.EndpointSettings)
return nil
}
@ -738,7 +767,7 @@ func (container *Container) updateEndpointNetworkSettings(n libnetwork.Network,
return err
}
networkSettings, err = container.buildEndpointInfo(ep, networkSettings)
networkSettings, err = container.buildEndpointInfo(n, ep, networkSettings)
if err != nil {
return err
}
@ -769,7 +798,7 @@ func (container *Container) updateNetwork() error {
// Find if container is connected to the default bridge network
var n libnetwork.Network
for _, name := range container.NetworkSettings.Networks {
for name := range container.NetworkSettings.Networks {
sn, err := container.daemon.FindNetwork(name)
if err != nil {
continue
@ -899,9 +928,8 @@ func createNetwork(controller libnetwork.NetworkController, dnet string, driver
}
func (container *Container) allocateNetwork() error {
settings := container.NetworkSettings.Networks
updateSettings := false
if settings == nil {
if len(container.NetworkSettings.Networks) == 0 {
mode := container.hostConfig.NetworkMode
controller := container.daemon.netController
if container.Config.NetworkDisabled || mode.IsContainer() {
@ -912,11 +940,12 @@ func (container *Container) allocateNetwork() error {
if mode.IsDefault() {
networkName = controller.Config().Daemon.DefaultNetwork
}
settings = []string{networkName}
container.NetworkSettings.Networks = make(map[string]*network.EndpointSettings)
container.NetworkSettings.Networks[networkName] = new(network.EndpointSettings)
updateSettings = true
}
for _, n := range settings {
for n := range container.NetworkSettings.Networks {
if err := container.connectToNetwork(n, updateSettings); err != nil {
return err
}
@ -1015,7 +1044,7 @@ func (container *Container) connectToNetwork(idOrName string, updateSettings boo
return err
}
if err := container.updateJoinInfo(ep); err != nil {
if err := container.updateJoinInfo(n, ep); err != nil {
return derr.ErrorCodeJoinInfo.WithArgs(err)
}
@ -1142,6 +1171,9 @@ func (container *Container) releaseNetwork() {
sid := container.NetworkSettings.SandboxID
networks := container.NetworkSettings.Networks
for n := range networks {
networks[n] = &network.EndpointSettings{}
}
container.NetworkSettings = &network.Settings{Networks: networks}
@ -1199,19 +1231,18 @@ 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)
}
networks := container.NetworkSettings.Networks
for i, s := range networks {
sn, err := container.daemon.FindNetwork(s)
if err != nil {
continue
}
if sn.Name() == n.Name() {
networks = append(networks[:i], networks[i+1:]...)
container.NetworkSettings.Networks = networks
break
}
}
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

@ -26,22 +26,34 @@ type IPAMConfig struct {
// TODO Windows. Many of these fields can be factored out.,
type Settings struct {
Bridge string
EndpointID string
EndpointID string // this is for backward compatibility
SandboxID string
Gateway string
GlobalIPv6Address string
GlobalIPv6PrefixLen int
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
IPPrefixLen int
IPv6Gateway string
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
Networks []string
MacAddress string // this is for backward compatibility
Networks map[string]*EndpointSettings
Ports nat.PortMap
SandboxKey string
SecondaryIPAddresses []Address
SecondaryIPv6Addresses []Address
IsAnonymousEndpoint bool
}
// EndpointSettings stores the network endpoint details
type EndpointSettings struct {
EndpointID string
Gateway string
IPAddress string
IPPrefixLen int
IPv6Gateway string
GlobalIPv6Address string
GlobalIPv6PrefixLen int
MacAddress string
}

View file

@ -54,7 +54,7 @@ func (s *DockerSuite) TestApiNetworkInspect(c *check.C) {
// run a container and attach it to the default bridge network
out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
containerID := strings.TrimSpace(out)
containerIP := findContainerIP(c, "test")
containerIP := findContainerIP(c, "test", "bridge")
// inspect default bridge network again and make sure the container is connected
nr = getNetworkResource(c, nr.ID)
@ -122,7 +122,7 @@ func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) {
// check if container IP matches network inspect
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
c.Assert(err, checker.IsNil)
containerIP := findContainerIP(c, "test")
containerIP := findContainerIP(c, "test", "testnetwork")
c.Assert(ip.String(), checker.Equals, containerIP)
// disconnect container from the network

View file

@ -85,7 +85,7 @@ func (s *DockerSuite) TestApiStatsNetworkStats(c *check.C) {
c.Assert(waitRun(id), checker.IsNil)
// Retrieve the container address
contIP := findContainerIP(c, id)
contIP := findContainerIP(c, id, "bridge")
numPings := 10
var preRxPackets uint64

View file

@ -284,7 +284,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnect(c *check.C) {
// check if container IP matches network inspect
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
c.Assert(err, check.IsNil)
containerIP := findContainerIP(c, "test")
containerIP := findContainerIP(c, "test", "test")
c.Assert(ip.String(), checker.Equals, containerIP)
// disconnect container from the network

View file

@ -782,13 +782,13 @@ func dockerCmdInDirWithTimeout(timeout time.Duration, path string, args ...strin
return integration.DockerCmdInDirWithTimeout(dockerBinary, timeout, path, args...)
}
func findContainerIP(c *check.C, id string, vargs ...string) string {
out, _ := dockerCmd(c, "inspect", "--format='{{ .NetworkSettings.IPAddress }}'", id)
func findContainerIP(c *check.C, id string, network string) string {
out, _ := dockerCmd(c, "inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.%s.IPAddress }}'", network), id)
return strings.Trim(out, " \r\n'")
}
func (d *Daemon) findContainerIP(id string) string {
return findContainerIP(d.c, id, "--host", d.sock())
return findContainerIP(d.c, id, "--host")
}
func getContainerCount() (int, error) {