container_windows.go 6.0 KB

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