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