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