Tizen_4.0 base
[platform/upstream/docker-engine.git] / container / container_windows.go
1 // +build windows
2
3 package container
4
5 import (
6         "fmt"
7         "os"
8         "path/filepath"
9
10         "github.com/docker/docker/api/types"
11         containertypes "github.com/docker/docker/api/types/container"
12         "github.com/docker/docker/pkg/system"
13 )
14
15 const (
16         containerSecretMountPath         = `C:\ProgramData\Docker\secrets`
17         containerInternalSecretMountPath = `C:\ProgramData\Docker\internal\secrets`
18         containerInternalConfigsDirPath  = `C:\ProgramData\Docker\internal\configs`
19 )
20
21 // ExitStatus provides exit reasons for a container.
22 type ExitStatus struct {
23         // The exit code with which the container exited.
24         ExitCode int
25 }
26
27 // UnmountIpcMounts unmounts Ipc related mounts.
28 // This is a NOOP on windows.
29 func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
30 }
31
32 // IpcMounts returns the list of Ipc related mounts.
33 func (container *Container) IpcMounts() []Mount {
34         return nil
35 }
36
37 // CreateSecretSymlinks creates symlinks to files in the secret mount.
38 func (container *Container) CreateSecretSymlinks() error {
39         for _, r := range container.SecretReferences {
40                 if r.File == nil {
41                         continue
42                 }
43                 resolvedPath, _, err := container.ResolvePath(getSecretTargetPath(r))
44                 if err != nil {
45                         return err
46                 }
47                 if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
48                         return err
49                 }
50                 if err := os.Symlink(filepath.Join(containerInternalSecretMountPath, r.SecretID), resolvedPath); err != nil {
51                         return err
52                 }
53         }
54
55         return nil
56 }
57
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 {
62         var mounts []Mount
63         if len(container.SecretReferences) > 0 {
64                 mounts = append(mounts, Mount{
65                         Source:      container.SecretMountPath(),
66                         Destination: containerInternalSecretMountPath,
67                         Writable:    false,
68                 })
69         }
70
71         return mounts
72 }
73
74 // UnmountSecrets unmounts the fs for secrets
75 func (container *Container) UnmountSecrets() error {
76         return os.RemoveAll(container.SecretMountPath())
77 }
78
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 {
83                         continue
84                 }
85                 resolvedPath, _, err := container.ResolvePath(configRef.File.Name)
86                 if err != nil {
87                         return err
88                 }
89                 if err := system.MkdirAll(filepath.Dir(resolvedPath), 0, ""); err != nil {
90                         return err
91                 }
92                 if err := os.Symlink(filepath.Join(containerInternalConfigsDirPath, configRef.ConfigID), resolvedPath); err != nil {
93                         return err
94                 }
95         }
96
97         return nil
98 }
99
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 {
104         var mounts []Mount
105         if len(container.ConfigReferences) > 0 {
106                 mounts = append(mounts, Mount{
107                         Source:      container.ConfigsDirPath(),
108                         Destination: containerInternalConfigsDirPath,
109                         Writable:    false,
110                 })
111         }
112
113         return mounts
114 }
115
116 // DetachAndUnmount unmounts all volumes.
117 // On Windows it only delegates to `UnmountVolumes` since there is nothing to
118 // force unmount.
119 func (container *Container) DetachAndUnmount(volumeEventLog func(name, action string, attributes map[string]string)) error {
120         return container.UnmountVolumes(volumeEventLog)
121 }
122
123 // TmpfsMounts returns the list of tmpfs mounts
124 func (container *Container) TmpfsMounts() ([]Mount, error) {
125         var mounts []Mount
126         return mounts, nil
127 }
128
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")
163         }
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")
168                 }
169                 container.HostConfig.RestartPolicy = hostConfig.RestartPolicy
170         }
171         return nil
172 }
173
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 {
177         if len(path) >= 2 {
178                 c := path[0]
179                 if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
180                         path = path[2:]
181                 }
182         }
183         return filepath.Join(string(os.PathSeparator), path)
184 }
185
186 // BuildHostnameFile writes the container's hostname file.
187 func (container *Container) BuildHostnameFile() error {
188         return nil
189 }
190
191 // EnableServiceDiscoveryOnDefaultNetwork Enable service discovery on default network
192 func (container *Container) EnableServiceDiscoveryOnDefaultNetwork() bool {
193         return true
194 }
195
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{
201                         Type:        m.Type,
202                         Name:        m.Name,
203                         Source:      m.Path(),
204                         Destination: m.Destination,
205                         Driver:      m.Driver,
206                         RW:          m.RW,
207                 })
208         }
209         return mountPoints
210 }