inspect.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package daemon
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/docker/docker/api/types"
  6. "github.com/docker/docker/api/types/versions/v1p20"
  7. "github.com/docker/docker/daemon/network"
  8. )
  9. // ContainerInspect returns low-level information about a
  10. // container. Returns an error if the container cannot be found, or if
  11. // there is an error getting the data.
  12. func (daemon *Daemon) ContainerInspect(name string, size bool) (*types.ContainerJSON, error) {
  13. container, err := daemon.Get(name)
  14. if err != nil {
  15. return nil, err
  16. }
  17. container.Lock()
  18. defer container.Unlock()
  19. base, err := daemon.getInspectData(container, size)
  20. if err != nil {
  21. return nil, err
  22. }
  23. mountPoints := addMountPoints(container)
  24. networkSettings := &types.NetworkSettings{
  25. NetworkSettingsBase: types.NetworkSettingsBase{
  26. Bridge: container.NetworkSettings.Bridge,
  27. SandboxID: container.NetworkSettings.SandboxID,
  28. HairpinMode: container.NetworkSettings.HairpinMode,
  29. LinkLocalIPv6Address: container.NetworkSettings.LinkLocalIPv6Address,
  30. LinkLocalIPv6PrefixLen: container.NetworkSettings.LinkLocalIPv6PrefixLen,
  31. Ports: container.NetworkSettings.Ports,
  32. SandboxKey: container.NetworkSettings.SandboxKey,
  33. SecondaryIPAddresses: container.NetworkSettings.SecondaryIPAddresses,
  34. SecondaryIPv6Addresses: container.NetworkSettings.SecondaryIPv6Addresses,
  35. },
  36. DefaultNetworkSettings: daemon.getDefaultNetworkSettings(container.NetworkSettings.Networks),
  37. Networks: container.NetworkSettings.Networks,
  38. }
  39. return &types.ContainerJSON{
  40. ContainerJSONBase: base,
  41. Mounts: mountPoints,
  42. Config: container.Config,
  43. NetworkSettings: networkSettings,
  44. }, nil
  45. }
  46. // ContainerInspect120 serializes the master version of a container into a json type.
  47. func (daemon *Daemon) ContainerInspect120(name string) (*v1p20.ContainerJSON, error) {
  48. container, err := daemon.Get(name)
  49. if err != nil {
  50. return nil, err
  51. }
  52. container.Lock()
  53. defer container.Unlock()
  54. base, err := daemon.getInspectData(container, false)
  55. if err != nil {
  56. return nil, err
  57. }
  58. mountPoints := addMountPoints(container)
  59. config := &v1p20.ContainerConfig{
  60. Config: container.Config,
  61. MacAddress: container.Config.MacAddress,
  62. NetworkDisabled: container.Config.NetworkDisabled,
  63. ExposedPorts: container.Config.ExposedPorts,
  64. VolumeDriver: container.hostConfig.VolumeDriver,
  65. }
  66. networkSettings := daemon.getBackwardsCompatibleNetworkSettings(container.NetworkSettings)
  67. return &v1p20.ContainerJSON{
  68. ContainerJSONBase: base,
  69. Mounts: mountPoints,
  70. Config: config,
  71. NetworkSettings: networkSettings,
  72. }, nil
  73. }
  74. func (daemon *Daemon) getInspectData(container *Container, size bool) (*types.ContainerJSONBase, error) {
  75. // make a copy to play with
  76. hostConfig := *container.hostConfig
  77. if children, err := daemon.children(container.Name); err == nil {
  78. for linkAlias, child := range children {
  79. hostConfig.Links = append(hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
  80. }
  81. }
  82. // we need this trick to preserve empty log driver, so
  83. // container will use daemon defaults even if daemon change them
  84. if hostConfig.LogConfig.Type == "" {
  85. hostConfig.LogConfig.Type = daemon.defaultLogConfig.Type
  86. }
  87. if len(hostConfig.LogConfig.Config) == 0 {
  88. hostConfig.LogConfig.Config = daemon.defaultLogConfig.Config
  89. }
  90. containerState := &types.ContainerState{
  91. Status: container.State.StateString(),
  92. Running: container.State.Running,
  93. Paused: container.State.Paused,
  94. Restarting: container.State.Restarting,
  95. OOMKilled: container.State.OOMKilled,
  96. Dead: container.State.Dead,
  97. Pid: container.State.Pid,
  98. ExitCode: container.State.ExitCode,
  99. Error: container.State.Error,
  100. StartedAt: container.State.StartedAt.Format(time.RFC3339Nano),
  101. FinishedAt: container.State.FinishedAt.Format(time.RFC3339Nano),
  102. }
  103. contJSONBase := &types.ContainerJSONBase{
  104. ID: container.ID,
  105. Created: container.Created.Format(time.RFC3339Nano),
  106. Path: container.Path,
  107. Args: container.Args,
  108. State: containerState,
  109. Image: container.ImageID,
  110. LogPath: container.LogPath,
  111. Name: container.Name,
  112. RestartCount: container.RestartCount,
  113. Driver: container.Driver,
  114. MountLabel: container.MountLabel,
  115. ProcessLabel: container.ProcessLabel,
  116. ExecIDs: container.getExecIDs(),
  117. HostConfig: &hostConfig,
  118. }
  119. var (
  120. sizeRw int64
  121. sizeRootFs int64
  122. )
  123. if size {
  124. sizeRw, sizeRootFs = daemon.getSize(container)
  125. contJSONBase.SizeRw = &sizeRw
  126. contJSONBase.SizeRootFs = &sizeRootFs
  127. }
  128. // Now set any platform-specific fields
  129. contJSONBase = setPlatformSpecificContainerFields(container, contJSONBase)
  130. contJSONBase.GraphDriver.Name = container.Driver
  131. graphDriverData, err := daemon.driver.GetMetadata(container.ID)
  132. if err != nil {
  133. return nil, err
  134. }
  135. contJSONBase.GraphDriver.Data = graphDriverData
  136. return contJSONBase, nil
  137. }
  138. // ContainerExecInspect returns low-level information about the exec
  139. // command. An error is returned if the exec cannot be found.
  140. func (daemon *Daemon) ContainerExecInspect(id string) (*ExecConfig, error) {
  141. eConfig, err := daemon.getExecConfig(id)
  142. if err != nil {
  143. return nil, err
  144. }
  145. return eConfig, nil
  146. }
  147. // VolumeInspect looks up a volume by name. An error is returned if
  148. // the volume cannot be found.
  149. func (daemon *Daemon) VolumeInspect(name string) (*types.Volume, error) {
  150. v, err := daemon.volumes.Get(name)
  151. if err != nil {
  152. return nil, err
  153. }
  154. return volumeToAPIType(v), nil
  155. }
  156. func (daemon *Daemon) getBackwardsCompatibleNetworkSettings(settings *network.Settings) *v1p20.NetworkSettings {
  157. result := &v1p20.NetworkSettings{
  158. NetworkSettingsBase: types.NetworkSettingsBase{
  159. Bridge: settings.Bridge,
  160. SandboxID: settings.SandboxID,
  161. HairpinMode: settings.HairpinMode,
  162. LinkLocalIPv6Address: settings.LinkLocalIPv6Address,
  163. LinkLocalIPv6PrefixLen: settings.LinkLocalIPv6PrefixLen,
  164. Ports: settings.Ports,
  165. SandboxKey: settings.SandboxKey,
  166. SecondaryIPAddresses: settings.SecondaryIPAddresses,
  167. SecondaryIPv6Addresses: settings.SecondaryIPv6Addresses,
  168. },
  169. DefaultNetworkSettings: daemon.getDefaultNetworkSettings(settings.Networks),
  170. }
  171. return result
  172. }
  173. // getDefaultNetworkSettings creates the deprecated structure that holds the information
  174. // about the bridge network for a container.
  175. func (daemon *Daemon) getDefaultNetworkSettings(networks map[string]*network.EndpointSettings) types.DefaultNetworkSettings {
  176. var settings types.DefaultNetworkSettings
  177. if defaultNetwork, ok := networks["bridge"]; ok {
  178. settings.EndpointID = defaultNetwork.EndpointID
  179. settings.Gateway = defaultNetwork.Gateway
  180. settings.GlobalIPv6Address = defaultNetwork.GlobalIPv6Address
  181. settings.GlobalIPv6PrefixLen = defaultNetwork.GlobalIPv6PrefixLen
  182. settings.IPAddress = defaultNetwork.IPAddress
  183. settings.IPPrefixLen = defaultNetwork.IPPrefixLen
  184. settings.IPv6Gateway = defaultNetwork.IPv6Gateway
  185. settings.MacAddress = defaultNetwork.MacAddress
  186. }
  187. return settings
  188. }