container_windows.go 6.6 KB

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