container_windows.go 6.6 KB

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