github.com/uppal0016/docker_new@v0.0.0-20240123060250-1c98be13ac2c/daemon/inspect.go (about)

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