github.com/tompao/docker@v1.9.1/daemon/inspect.go (about)

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