github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/container/container_windows.go (about)

     1  package container // import "github.com/docker/docker/container"
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/docker/docker/api/types"
     9  	containertypes "github.com/docker/docker/api/types/container"
    10  	swarmtypes "github.com/docker/docker/api/types/swarm"
    11  	"github.com/docker/docker/pkg/system"
    12  )
    13  
    14  const (
    15  	containerSecretMountPath         = `C:\ProgramData\Docker\secrets`
    16  	containerInternalSecretMountPath = `C:\ProgramData\Docker\internal\secrets`
    17  	containerInternalConfigsDirPath  = `C:\ProgramData\Docker\internal\configs`
    18  
    19  	// DefaultStopTimeout is the timeout (in seconds) for the shutdown call on a container
    20  	DefaultStopTimeout = 30
    21  )
    22  
    23  // UnmountIpcMount unmounts Ipc related mounts.
    24  // This is a NOOP on windows.
    25  func (container *Container) UnmountIpcMount() error {
    26  	return nil
    27  }
    28  
    29  // IpcMounts returns the list of Ipc related mounts.
    30  func (container *Container) IpcMounts() []Mount {
    31  	return nil
    32  }
    33  
    34  // CreateSecretSymlinks creates symlinks to files in the secret mount.
    35  func (container *Container) CreateSecretSymlinks() error {
    36  	for _, r := range container.SecretReferences {
    37  		if r.File == nil {
    38  			continue
    39  		}
    40  		resolvedPath, _, err := container.ResolvePath(getSecretTargetPath(r))
    41  		if err != nil {
    42  			return err
    43  		}
    44  		if err := system.MkdirAll(filepath.Dir(resolvedPath), 0); err != nil {
    45  			return err
    46  		}
    47  		if err := os.Symlink(filepath.Join(containerInternalSecretMountPath, r.SecretID), resolvedPath); err != nil {
    48  			return err
    49  		}
    50  	}
    51  
    52  	return nil
    53  }
    54  
    55  // SecretMounts returns the mount for the secret path.
    56  // All secrets are stored in a single mount on Windows. Target symlinks are
    57  // created for each secret, pointing to the files in this mount.
    58  func (container *Container) SecretMounts() ([]Mount, error) {
    59  	var mounts []Mount
    60  	if len(container.SecretReferences) > 0 {
    61  		src, err := container.SecretMountPath()
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  		mounts = append(mounts, Mount{
    66  			Source:      src,
    67  			Destination: containerInternalSecretMountPath,
    68  			Writable:    false,
    69  		})
    70  	}
    71  
    72  	return mounts, nil
    73  }
    74  
    75  // UnmountSecrets unmounts the fs for secrets
    76  func (container *Container) UnmountSecrets() error {
    77  	p, err := container.SecretMountPath()
    78  	if err != nil {
    79  		return err
    80  	}
    81  	return os.RemoveAll(p)
    82  }
    83  
    84  // CreateConfigSymlinks creates symlinks to files in the config mount.
    85  func (container *Container) CreateConfigSymlinks() error {
    86  	for _, configRef := range container.ConfigReferences {
    87  		if configRef.File == nil {
    88  			continue
    89  		}
    90  		resolvedPath, _, err := container.ResolvePath(configRef.File.Name)
    91  		if err != nil {
    92  			return err
    93  		}
    94  		if err := system.MkdirAll(filepath.Dir(resolvedPath), 0); err != nil {
    95  			return err
    96  		}
    97  		if err := os.Symlink(filepath.Join(containerInternalConfigsDirPath, configRef.ConfigID), resolvedPath); err != nil {
    98  			return err
    99  		}
   100  	}
   101  
   102  	return nil
   103  }
   104  
   105  // ConfigMounts returns the mount for configs.
   106  // TODO: Right now Windows doesn't really have a "secure" storage for secrets,
   107  // however some configs may contain secrets. Once secure storage is worked out,
   108  // configs and secret handling should be merged.
   109  func (container *Container) ConfigMounts() []Mount {
   110  	var mounts []Mount
   111  	if len(container.ConfigReferences) > 0 {
   112  		mounts = append(mounts, Mount{
   113  			Source:      container.ConfigsDirPath(),
   114  			Destination: containerInternalConfigsDirPath,
   115  			Writable:    false,
   116  		})
   117  	}
   118  
   119  	return mounts
   120  }
   121  
   122  // DetachAndUnmount unmounts all volumes.
   123  // On Windows it only delegates to `UnmountVolumes` since there is nothing to
   124  // force unmount.
   125  func (container *Container) DetachAndUnmount(volumeEventLog func(name, action string, attributes map[string]string)) error {
   126  	return container.UnmountVolumes(volumeEventLog)
   127  }
   128  
   129  // TmpfsMounts returns the list of tmpfs mounts
   130  func (container *Container) TmpfsMounts() ([]Mount, error) {
   131  	var mounts []Mount
   132  	return mounts, nil
   133  }
   134  
   135  // UpdateContainer updates configuration of a container. Callers must hold a Lock on the Container.
   136  func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error {
   137  	resources := hostConfig.Resources
   138  	if resources.CPUShares != 0 ||
   139  		resources.Memory != 0 ||
   140  		resources.NanoCPUs != 0 ||
   141  		resources.CgroupParent != "" ||
   142  		resources.BlkioWeight != 0 ||
   143  		len(resources.BlkioWeightDevice) != 0 ||
   144  		len(resources.BlkioDeviceReadBps) != 0 ||
   145  		len(resources.BlkioDeviceWriteBps) != 0 ||
   146  		len(resources.BlkioDeviceReadIOps) != 0 ||
   147  		len(resources.BlkioDeviceWriteIOps) != 0 ||
   148  		resources.CPUPeriod != 0 ||
   149  		resources.CPUQuota != 0 ||
   150  		resources.CPURealtimePeriod != 0 ||
   151  		resources.CPURealtimeRuntime != 0 ||
   152  		resources.CpusetCpus != "" ||
   153  		resources.CpusetMems != "" ||
   154  		len(resources.Devices) != 0 ||
   155  		len(resources.DeviceCgroupRules) != 0 ||
   156  		resources.KernelMemory != 0 ||
   157  		resources.MemoryReservation != 0 ||
   158  		resources.MemorySwap != 0 ||
   159  		resources.MemorySwappiness != nil ||
   160  		resources.OomKillDisable != nil ||
   161  		(resources.PidsLimit != nil && *resources.PidsLimit != 0) ||
   162  		len(resources.Ulimits) != 0 ||
   163  		resources.CPUCount != 0 ||
   164  		resources.CPUPercent != 0 ||
   165  		resources.IOMaximumIOps != 0 ||
   166  		resources.IOMaximumBandwidth != 0 {
   167  		return fmt.Errorf("resource updating isn't supported on Windows")
   168  	}
   169  	// update HostConfig of container
   170  	if hostConfig.RestartPolicy.Name != "" {
   171  		if container.HostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
   172  			return fmt.Errorf("Restart policy cannot be updated because AutoRemove is enabled for the container")
   173  		}
   174  		container.HostConfig.RestartPolicy = hostConfig.RestartPolicy
   175  	}
   176  	return nil
   177  }
   178  
   179  // BuildHostnameFile writes the container's hostname file.
   180  func (container *Container) BuildHostnameFile() error {
   181  	return nil
   182  }
   183  
   184  // GetMountPoints gives a platform specific transformation to types.MountPoint. Callers must hold a Container lock.
   185  func (container *Container) GetMountPoints() []types.MountPoint {
   186  	mountPoints := make([]types.MountPoint, 0, len(container.MountPoints))
   187  	for _, m := range container.MountPoints {
   188  		mountPoints = append(mountPoints, types.MountPoint{
   189  			Type:        m.Type,
   190  			Name:        m.Name,
   191  			Source:      m.Path(),
   192  			Destination: m.Destination,
   193  			Driver:      m.Driver,
   194  			RW:          m.RW,
   195  		})
   196  	}
   197  	return mountPoints
   198  }
   199  
   200  func (container *Container) ConfigsDirPath() string {
   201  	return filepath.Join(container.Root, "configs")
   202  }
   203  
   204  // ConfigFilePath returns the path to the on-disk location of a config.
   205  func (container *Container) ConfigFilePath(configRef swarmtypes.ConfigReference) (string, error) {
   206  	return filepath.Join(container.ConfigsDirPath(), configRef.ConfigID), nil
   207  }