10 "github.com/docker/docker/api/types"
11 containertypes "github.com/docker/docker/api/types/container"
12 "github.com/docker/docker/pkg/system"
16 containerSecretMountPath = `C:\ProgramData\Docker\secrets`
17 containerInternalSecretMountPath = `C:\ProgramData\Docker\internal\secrets`
18 containerInternalConfigsDirPath = `C:\ProgramData\Docker\internal\configs`
21 // ExitStatus provides exit reasons for a container.
22 type ExitStatus struct {
23 // The exit code with which the container exited.
27 // UnmountIpcMounts unmounts Ipc related mounts.
28 // This is a NOOP on windows.
29 func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
32 // IpcMounts returns the list of Ipc related mounts.
33 func (container *Container) IpcMounts() []Mount {
37 // CreateSecretSymlinks creates symlinks to files in the secret mount.
38 func (container *Container) CreateSecretSymlinks() error {
39 for _, r := range container.SecretReferences {
43 resolvedPath, _, err := container.ResolvePath(getSecretTargetPath(r))
47 if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
50 if err := os.Symlink(filepath.Join(containerInternalSecretMountPath, r.SecretID), resolvedPath); err != nil {
58 // SecretMounts returns the mount for the secret path.
59 // All secrets are stored in a single mount on Windows. Target symlinks are
60 // created for each secret, pointing to the files in this mount.
61 func (container *Container) SecretMounts() []Mount {
63 if len(container.SecretReferences) > 0 {
64 mounts = append(mounts, Mount{
65 Source: container.SecretMountPath(),
66 Destination: containerInternalSecretMountPath,
74 // UnmountSecrets unmounts the fs for secrets
75 func (container *Container) UnmountSecrets() error {
76 return os.RemoveAll(container.SecretMountPath())
79 // CreateConfigSymlinks creates symlinks to files in the config mount.
80 func (container *Container) CreateConfigSymlinks() error {
81 for _, configRef := range container.ConfigReferences {
82 if configRef.File == nil {
85 resolvedPath, _, err := container.ResolvePath(configRef.File.Name)
89 if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
92 if err := os.Symlink(filepath.Join(containerInternalConfigsDirPath, configRef.ConfigID), resolvedPath); err != nil {
100 // ConfigMounts returns the mount for configs.
101 // All configs are stored in a single mount on Windows. Target symlinks are
102 // created for each config, pointing to the files in this mount.
103 func (container *Container) ConfigMounts() []Mount {
105 if len(container.ConfigReferences) > 0 {
106 mounts = append(mounts, Mount{
107 Source: container.ConfigsDirPath(),
108 Destination: containerInternalConfigsDirPath,
116 // DetachAndUnmount unmounts all volumes.
117 // On Windows it only delegates to `UnmountVolumes` since there is nothing to
119 func (container *Container) DetachAndUnmount(volumeEventLog func(name, action string, attributes map[string]string)) error {
120 return container.UnmountVolumes(volumeEventLog)
123 // TmpfsMounts returns the list of tmpfs mounts
124 func (container *Container) TmpfsMounts() ([]Mount, error) {
129 // UpdateContainer updates configuration of a container. Callers must hold a Lock on the Container.
130 func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error {
131 resources := hostConfig.Resources
132 if resources.CPUShares != 0 ||
133 resources.Memory != 0 ||
134 resources.NanoCPUs != 0 ||
135 resources.CgroupParent != "" ||
136 resources.BlkioWeight != 0 ||
137 len(resources.BlkioWeightDevice) != 0 ||
138 len(resources.BlkioDeviceReadBps) != 0 ||
139 len(resources.BlkioDeviceWriteBps) != 0 ||
140 len(resources.BlkioDeviceReadIOps) != 0 ||
141 len(resources.BlkioDeviceWriteIOps) != 0 ||
142 resources.CPUPeriod != 0 ||
143 resources.CPUQuota != 0 ||
144 resources.CPURealtimePeriod != 0 ||
145 resources.CPURealtimeRuntime != 0 ||
146 resources.CpusetCpus != "" ||
147 resources.CpusetMems != "" ||
148 len(resources.Devices) != 0 ||
149 len(resources.DeviceCgroupRules) != 0 ||
150 resources.DiskQuota != 0 ||
151 resources.KernelMemory != 0 ||
152 resources.MemoryReservation != 0 ||
153 resources.MemorySwap != 0 ||
154 resources.MemorySwappiness != nil ||
155 resources.OomKillDisable != nil ||
156 resources.PidsLimit != 0 ||
157 len(resources.Ulimits) != 0 ||
158 resources.CPUCount != 0 ||
159 resources.CPUPercent != 0 ||
160 resources.IOMaximumIOps != 0 ||
161 resources.IOMaximumBandwidth != 0 {
162 return fmt.Errorf("resource updating isn't supported on Windows")
164 // update HostConfig of container
165 if hostConfig.RestartPolicy.Name != "" {
166 if container.HostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
167 return fmt.Errorf("Restart policy cannot be updated because AutoRemove is enabled for the container")
169 container.HostConfig.RestartPolicy = hostConfig.RestartPolicy
174 // cleanResourcePath cleans a resource path by removing C:\ syntax, and prepares
175 // to combine with a volume path
176 func cleanResourcePath(path string) string {
179 if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
183 return filepath.Join(string(os.PathSeparator), path)
186 // BuildHostnameFile writes the container's hostname file.
187 func (container *Container) BuildHostnameFile() error {
191 // EnableServiceDiscoveryOnDefaultNetwork Enable service discovery on default network
192 func (container *Container) EnableServiceDiscoveryOnDefaultNetwork() bool {
196 // GetMountPoints gives a platform specific transformation to types.MountPoint. Callers must hold a Container lock.
197 func (container *Container) GetMountPoints() []types.MountPoint {
198 mountPoints := make([]types.MountPoint, 0, len(container.MountPoints))
199 for _, m := range container.MountPoints {
200 mountPoints = append(mountPoints, types.MountPoint{
204 Destination: m.Destination,