container_windows.go 6.6 KB

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