Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carry Fix docker inspect container only reports last assigned information #17393

Merged
merged 2 commits into from
Oct 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 23 additions & 3 deletions api/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -255,7 +256,6 @@ type ContainerJSONBase struct {
Args []string
State *ContainerState
Image string
NetworkSettings *network.Settings
ResolvConfPath string
HostnamePath string
HostsPath string
Expand All @@ -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.
Expand Down
8 changes: 5 additions & 3 deletions api/types/versions/v1p19/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand All @@ -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.
Expand Down
18 changes: 16 additions & 2 deletions api/types/versions/v1p20/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
4 changes: 0 additions & 4 deletions daemon/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
106 changes: 58 additions & 48 deletions daemon/container_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,25 @@ func (container *Container) setupLinkedContainers() ([]string, error) {
return nil, err
}

bridgeSettings := container.NetworkSettings.Networks["bridge"]
if bridgeSettings == nil {
return nil, nil
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@calavera @mavenugo this is the line i just changed, it doesnt error out now.

}

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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here, we do, because child has to be attached to bridge network. Not even sure how this would be possible, but if it is, we should error out.

}

link := links.NewLink(
container.NetworkSettings.IPAddress,
child.NetworkSettings.IPAddress,
bridgeSettings.IPAddress,
childBridgeSettings.IPAddress,
linkAlias,
child.Config.Env,
child.Config.ExposedPorts,
Expand Down Expand Up @@ -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" {
Expand All @@ -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())
}
Expand All @@ -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"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrjana this is my change after rebasing on top of #17230

return ok
}

func (container *Container) getEndpointInNetwork(n libnetwork.Network) (libnetwork.Endpoint, error) {
Expand All @@ -615,10 +622,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 {
Expand Down Expand Up @@ -652,7 +655,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
}
Expand All @@ -667,48 +670,64 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet
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()
if iface == nil {
return networkSettings, nil
}

if iface.Address() != nil {
ones, _ := iface.Address().Mask.Size()
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
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 {
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()
container.NetworkSettings.Networks[n.Name()].Gateway = epInfo.Gateway().String()
if epInfo.GatewayIPv6().To16() != nil {
container.NetworkSettings.IPv6Gateway = epInfo.GatewayIPv6().String()
container.NetworkSettings.Networks[n.Name()].IPv6Gateway = epInfo.GatewayIPv6().String()
}

return nil
}

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
Expand All @@ -727,7 +746,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
}
Expand All @@ -738,7 +757,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
}
Expand Down Expand Up @@ -769,7 +788,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
Expand Down Expand Up @@ -899,9 +918,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() {
Expand All @@ -912,11 +930,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
}
Expand Down Expand Up @@ -1015,7 +1034,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)
}

Expand Down Expand Up @@ -1142,6 +1161,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}

Expand Down Expand Up @@ -1199,19 +1221,7 @@ 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
}
}

delete(container.NetworkSettings.Networks, n.Name())
return nil
}

Expand Down