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