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