inspect.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package daemon
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/docker/docker/api/types"
  6. "github.com/docker/docker/context"
  7. )
  8. // ContainerInspect returns low-level information about a
  9. // container. Returns an error if the container cannot be found, or if
  10. // there is an error getting the data.
  11. func (daemon *Daemon) ContainerInspect(ctx context.Context, name string) (*types.ContainerJSON, error) {
  12. container, err := daemon.Get(ctx, name)
  13. if err != nil {
  14. return nil, err
  15. }
  16. container.Lock()
  17. defer container.Unlock()
  18. base, err := daemon.getInspectData(ctx, container)
  19. if err != nil {
  20. return nil, err
  21. }
  22. mountPoints := addMountPoints(container)
  23. return &types.ContainerJSON{base, mountPoints, container.Config}, nil
  24. }
  25. // ContainerInspect120 serializes the master version of a container into a json type.
  26. func (daemon *Daemon) ContainerInspect120(ctx context.Context, name string) (*types.ContainerJSON120, error) {
  27. container, err := daemon.Get(ctx, name)
  28. if err != nil {
  29. return nil, err
  30. }
  31. container.Lock()
  32. defer container.Unlock()
  33. base, err := daemon.getInspectData(ctx, container)
  34. if err != nil {
  35. return nil, err
  36. }
  37. mountPoints := addMountPoints(container)
  38. config := &types.ContainerConfig120{
  39. container.Config,
  40. container.hostConfig.VolumeDriver,
  41. }
  42. return &types.ContainerJSON120{base, mountPoints, config}, nil
  43. }
  44. func (daemon *Daemon) getInspectData(ctx context.Context, container *Container) (*types.ContainerJSONBase, error) {
  45. // make a copy to play with
  46. hostConfig := *container.hostConfig
  47. if children, err := daemon.children(ctx, container.Name); err == nil {
  48. for linkAlias, child := range children {
  49. hostConfig.Links = append(hostConfig.Links, fmt.Sprintf("%s:%s", child.Name, linkAlias))
  50. }
  51. }
  52. // we need this trick to preserve empty log driver, so
  53. // container will use daemon defaults even if daemon change them
  54. if hostConfig.LogConfig.Type == "" {
  55. hostConfig.LogConfig.Type = daemon.defaultLogConfig.Type
  56. }
  57. if len(hostConfig.LogConfig.Config) == 0 {
  58. hostConfig.LogConfig.Config = daemon.defaultLogConfig.Config
  59. }
  60. containerState := &types.ContainerState{
  61. Status: container.State.StateString(),
  62. Running: container.State.Running,
  63. Paused: container.State.Paused,
  64. Restarting: container.State.Restarting,
  65. OOMKilled: container.State.OOMKilled,
  66. Dead: container.State.Dead,
  67. Pid: container.State.Pid,
  68. ExitCode: container.State.ExitCode,
  69. Error: container.State.Error,
  70. StartedAt: container.State.StartedAt.Format(time.RFC3339Nano),
  71. FinishedAt: container.State.FinishedAt.Format(time.RFC3339Nano),
  72. }
  73. contJSONBase := &types.ContainerJSONBase{
  74. ID: container.ID,
  75. Created: container.Created.Format(time.RFC3339Nano),
  76. Path: container.Path,
  77. Args: container.Args,
  78. State: containerState,
  79. Image: container.ImageID,
  80. NetworkSettings: container.NetworkSettings,
  81. LogPath: container.LogPath,
  82. Name: container.Name,
  83. RestartCount: container.RestartCount,
  84. Driver: container.Driver,
  85. ExecDriver: container.ExecDriver,
  86. MountLabel: container.MountLabel,
  87. ProcessLabel: container.ProcessLabel,
  88. ExecIDs: container.getExecIDs(),
  89. HostConfig: &hostConfig,
  90. }
  91. // Now set any platform-specific fields
  92. contJSONBase = setPlatformSpecificContainerFields(container, contJSONBase)
  93. contJSONBase.GraphDriver.Name = container.Driver
  94. graphDriverData, err := daemon.driver.GetMetadata(container.ID)
  95. if err != nil {
  96. return nil, err
  97. }
  98. contJSONBase.GraphDriver.Data = graphDriverData
  99. return contJSONBase, nil
  100. }
  101. // ContainerExecInspect returns low-level information about the exec
  102. // command. An error is returned if the exec cannot be found.
  103. func (daemon *Daemon) ContainerExecInspect(ctx context.Context, id string) (*ExecConfig, error) {
  104. eConfig, err := daemon.getExecConfig(id)
  105. if err != nil {
  106. return nil, err
  107. }
  108. return eConfig, nil
  109. }
  110. // VolumeInspect looks up a volume by name. An error is returned if
  111. // the volume cannot be found.
  112. func (daemon *Daemon) VolumeInspect(ctx context.Context, name string) (*types.Volume, error) {
  113. v, err := daemon.volumes.Get(name)
  114. if err != nil {
  115. return nil, err
  116. }
  117. return volumeToAPIType(v), nil
  118. }