Fix docker inspect container only reports last assigned information
Signed-off-by: Lei Jitang <leijitang@huawei.com>
This commit is contained in:
parent
bf9f2691ca
commit
1b9a08e719
|
@ -615,10 +615,6 @@ func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint, networkSett
|
||||||
return networkSettings, nil
|
return networkSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if mac, ok := driverInfo[netlabel.MacAddress]; ok {
|
|
||||||
networkSettings.MacAddress = mac.(net.HardwareAddr).String()
|
|
||||||
}
|
|
||||||
|
|
||||||
networkSettings.Ports = nat.PortMap{}
|
networkSettings.Ports = nat.PortMap{}
|
||||||
|
|
||||||
if expData, ok := driverInfo[netlabel.ExposedPorts]; ok {
|
if expData, ok := driverInfo[netlabel.ExposedPorts]; ok {
|
||||||
|
@ -652,7 +648,7 @@ func (container *Container) buildPortMapInfo(ep libnetwork.Endpoint, networkSett
|
||||||
return networkSettings, nil
|
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 {
|
if ep == nil {
|
||||||
return nil, derr.ErrorCodeEmptyEndpoint
|
return nil, derr.ErrorCodeEmptyEndpoint
|
||||||
}
|
}
|
||||||
|
@ -667,36 +663,70 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet
|
||||||
return networkSettings, nil
|
return networkSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
networkSettings.Networks[n.Name()].EndpointID = ep.ID()
|
||||||
|
|
||||||
iface := epInfo.Iface()
|
iface := epInfo.Iface()
|
||||||
if iface == nil {
|
if iface == nil {
|
||||||
return networkSettings, nil
|
return networkSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if networkSettings.EndpointID == "" {
|
||||||
|
networkSettings.EndpointID = ep.ID()
|
||||||
|
}
|
||||||
if iface.Address() != nil {
|
if iface.Address() != nil {
|
||||||
ones, _ := iface.Address().Mask.Size()
|
ones, _ := iface.Address().Mask.Size()
|
||||||
networkSettings.IPAddress = iface.Address().IP.String()
|
if networkSettings.IPAddress == "" || networkSettings.IPPrefixLen == 0 {
|
||||||
networkSettings.IPPrefixLen = ones
|
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 {
|
if iface.AddressIPv6() != nil && iface.AddressIPv6().IP.To16() != nil {
|
||||||
onesv6, _ := iface.AddressIPv6().Mask.Size()
|
onesv6, _ := iface.AddressIPv6().Mask.Size()
|
||||||
networkSettings.GlobalIPv6Address = iface.AddressIPv6().IP.String()
|
if networkSettings.GlobalIPv6Address == "" || networkSettings.GlobalIPv6PrefixLen == 0 {
|
||||||
networkSettings.GlobalIPv6PrefixLen = onesv6
|
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
|
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()
|
epInfo := ep.Info()
|
||||||
if epInfo == nil {
|
if epInfo == nil {
|
||||||
// It is not an error to get an empty endpoint info
|
// It is not an error to get an empty endpoint info
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if container.NetworkSettings.Gateway == "" {
|
||||||
container.NetworkSettings.Gateway = epInfo.Gateway().String()
|
container.NetworkSettings.Gateway = epInfo.Gateway().String()
|
||||||
|
}
|
||||||
|
container.NetworkSettings.Networks[n.Name()].Gateway = epInfo.Gateway().String()
|
||||||
if epInfo.GatewayIPv6().To16() != nil {
|
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
|
return nil
|
||||||
|
@ -704,11 +734,10 @@ func (container *Container) updateJoinInfo(ep libnetwork.Endpoint) error {
|
||||||
|
|
||||||
func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
|
func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
|
||||||
if container.NetworkSettings == nil {
|
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)
|
sn, err := container.daemon.FindNetwork(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -727,7 +756,7 @@ func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
|
||||||
return runconfig.ErrConflictNoNetwork
|
return runconfig.ErrConflictNoNetwork
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings.Networks = append(settings.Networks, n.Name())
|
container.NetworkSettings.Networks[n.Name()] = new(network.EndpointSettings)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -738,7 +767,7 @@ func (container *Container) updateEndpointNetworkSettings(n libnetwork.Network,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
networkSettings, err = container.buildEndpointInfo(ep, networkSettings)
|
networkSettings, err = container.buildEndpointInfo(n, ep, networkSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -769,7 +798,7 @@ func (container *Container) updateNetwork() error {
|
||||||
|
|
||||||
// Find if container is connected to the default bridge network
|
// Find if container is connected to the default bridge network
|
||||||
var n libnetwork.Network
|
var n libnetwork.Network
|
||||||
for _, name := range container.NetworkSettings.Networks {
|
for name := range container.NetworkSettings.Networks {
|
||||||
sn, err := container.daemon.FindNetwork(name)
|
sn, err := container.daemon.FindNetwork(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -899,9 +928,8 @@ func createNetwork(controller libnetwork.NetworkController, dnet string, driver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (container *Container) allocateNetwork() error {
|
func (container *Container) allocateNetwork() error {
|
||||||
settings := container.NetworkSettings.Networks
|
|
||||||
updateSettings := false
|
updateSettings := false
|
||||||
if settings == nil {
|
if len(container.NetworkSettings.Networks) == 0 {
|
||||||
mode := container.hostConfig.NetworkMode
|
mode := container.hostConfig.NetworkMode
|
||||||
controller := container.daemon.netController
|
controller := container.daemon.netController
|
||||||
if container.Config.NetworkDisabled || mode.IsContainer() {
|
if container.Config.NetworkDisabled || mode.IsContainer() {
|
||||||
|
@ -912,11 +940,12 @@ func (container *Container) allocateNetwork() error {
|
||||||
if mode.IsDefault() {
|
if mode.IsDefault() {
|
||||||
networkName = controller.Config().Daemon.DefaultNetwork
|
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
|
updateSettings = true
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range settings {
|
for n := range container.NetworkSettings.Networks {
|
||||||
if err := container.connectToNetwork(n, updateSettings); err != nil {
|
if err := container.connectToNetwork(n, updateSettings); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1044,7 @@ func (container *Container) connectToNetwork(idOrName string, updateSettings boo
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := container.updateJoinInfo(ep); err != nil {
|
if err := container.updateJoinInfo(n, ep); err != nil {
|
||||||
return derr.ErrorCodeJoinInfo.WithArgs(err)
|
return derr.ErrorCodeJoinInfo.WithArgs(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,6 +1171,9 @@ func (container *Container) releaseNetwork() {
|
||||||
|
|
||||||
sid := container.NetworkSettings.SandboxID
|
sid := container.NetworkSettings.SandboxID
|
||||||
networks := container.NetworkSettings.Networks
|
networks := container.NetworkSettings.Networks
|
||||||
|
for n := range networks {
|
||||||
|
networks[n] = &network.EndpointSettings{}
|
||||||
|
}
|
||||||
|
|
||||||
container.NetworkSettings = &network.Settings{Networks: networks}
|
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)
|
return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
networks := container.NetworkSettings.Networks
|
if container.NetworkSettings.EndpointID == container.NetworkSettings.Networks[n.Name()].EndpointID {
|
||||||
for i, s := range networks {
|
container.NetworkSettings.EndpointID = ""
|
||||||
sn, err := container.daemon.FindNetwork(s)
|
container.NetworkSettings.Gateway = ""
|
||||||
if err != nil {
|
container.NetworkSettings.GlobalIPv6Address = ""
|
||||||
continue
|
container.NetworkSettings.GlobalIPv6PrefixLen = 0
|
||||||
}
|
container.NetworkSettings.IPAddress = ""
|
||||||
if sn.Name() == n.Name() {
|
container.NetworkSettings.IPPrefixLen = 0
|
||||||
networks = append(networks[:i], networks[i+1:]...)
|
container.NetworkSettings.IPv6Gateway = ""
|
||||||
container.NetworkSettings.Networks = networks
|
container.NetworkSettings.MacAddress = ""
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
delete(container.NetworkSettings.Networks, n.Name())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,22 +26,34 @@ type IPAMConfig struct {
|
||||||
// TODO Windows. Many of these fields can be factored out.,
|
// TODO Windows. Many of these fields can be factored out.,
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Bridge string
|
Bridge string
|
||||||
EndpointID string
|
EndpointID string // this is for backward compatibility
|
||||||
SandboxID string
|
SandboxID string
|
||||||
Gateway string
|
Gateway string // this is for backward compatibility
|
||||||
GlobalIPv6Address string
|
GlobalIPv6Address string // this is for backward compatibility
|
||||||
GlobalIPv6PrefixLen int
|
GlobalIPv6PrefixLen int // this is for backward compatibility
|
||||||
HairpinMode bool
|
HairpinMode bool
|
||||||
IPAddress string
|
IPAddress string // this is for backward compatibility
|
||||||
IPPrefixLen int
|
IPPrefixLen int // this is for backward compatibility
|
||||||
IPv6Gateway string
|
IPv6Gateway string // this is for backward compatibility
|
||||||
LinkLocalIPv6Address string
|
LinkLocalIPv6Address string
|
||||||
LinkLocalIPv6PrefixLen int
|
LinkLocalIPv6PrefixLen int
|
||||||
MacAddress string
|
MacAddress string // this is for backward compatibility
|
||||||
Networks []string
|
Networks map[string]*EndpointSettings
|
||||||
Ports nat.PortMap
|
Ports nat.PortMap
|
||||||
SandboxKey string
|
SandboxKey string
|
||||||
SecondaryIPAddresses []Address
|
SecondaryIPAddresses []Address
|
||||||
SecondaryIPv6Addresses []Address
|
SecondaryIPv6Addresses []Address
|
||||||
IsAnonymousEndpoint bool
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (s *DockerSuite) TestApiNetworkInspect(c *check.C) {
|
||||||
// run a container and attach it to the default bridge network
|
// run a container and attach it to the default bridge network
|
||||||
out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
|
out, _ := dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top")
|
||||||
containerID := strings.TrimSpace(out)
|
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
|
// inspect default bridge network again and make sure the container is connected
|
||||||
nr = getNetworkResource(c, nr.ID)
|
nr = getNetworkResource(c, nr.ID)
|
||||||
|
@ -122,7 +122,7 @@ func (s *DockerSuite) TestApiNetworkConnectDisconnect(c *check.C) {
|
||||||
// check if container IP matches network inspect
|
// check if container IP matches network inspect
|
||||||
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
|
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
containerIP := findContainerIP(c, "test")
|
containerIP := findContainerIP(c, "test", "testnetwork")
|
||||||
c.Assert(ip.String(), checker.Equals, containerIP)
|
c.Assert(ip.String(), checker.Equals, containerIP)
|
||||||
|
|
||||||
// disconnect container from the network
|
// disconnect container from the network
|
||||||
|
|
|
@ -85,7 +85,7 @@ func (s *DockerSuite) TestApiStatsNetworkStats(c *check.C) {
|
||||||
c.Assert(waitRun(id), checker.IsNil)
|
c.Assert(waitRun(id), checker.IsNil)
|
||||||
|
|
||||||
// Retrieve the container address
|
// Retrieve the container address
|
||||||
contIP := findContainerIP(c, id)
|
contIP := findContainerIP(c, id, "bridge")
|
||||||
numPings := 10
|
numPings := 10
|
||||||
|
|
||||||
var preRxPackets uint64
|
var preRxPackets uint64
|
||||||
|
|
|
@ -284,7 +284,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnect(c *check.C) {
|
||||||
// check if container IP matches network inspect
|
// check if container IP matches network inspect
|
||||||
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
|
ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
containerIP := findContainerIP(c, "test")
|
containerIP := findContainerIP(c, "test", "test")
|
||||||
c.Assert(ip.String(), checker.Equals, containerIP)
|
c.Assert(ip.String(), checker.Equals, containerIP)
|
||||||
|
|
||||||
// disconnect container from the network
|
// disconnect container from the network
|
||||||
|
|
|
@ -782,13 +782,13 @@ func dockerCmdInDirWithTimeout(timeout time.Duration, path string, args ...strin
|
||||||
return integration.DockerCmdInDirWithTimeout(dockerBinary, timeout, path, args...)
|
return integration.DockerCmdInDirWithTimeout(dockerBinary, timeout, path, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func findContainerIP(c *check.C, id string, vargs ...string) string {
|
func findContainerIP(c *check.C, id string, network string) string {
|
||||||
out, _ := dockerCmd(c, "inspect", "--format='{{ .NetworkSettings.IPAddress }}'", id)
|
out, _ := dockerCmd(c, "inspect", fmt.Sprintf("--format='{{ .NetworkSettings.Networks.%s.IPAddress }}'", network), id)
|
||||||
return strings.Trim(out, " \r\n'")
|
return strings.Trim(out, " \r\n'")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Daemon) findContainerIP(id string) string {
|
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) {
|
func getContainerCount() (int, error) {
|
||||||
|
|
Loading…
Reference in New Issue