github.com/uppal0016/docker_new@v0.0.0-20240123060250-1c98be13ac2c/daemon/daemon_windows.go (about) 1 package daemon 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "os" 8 "path/filepath" 9 "runtime" 10 "strings" 11 12 "github.com/Microsoft/hcsshim" 13 "github.com/Sirupsen/logrus" 14 "github.com/docker/docker/container" 15 "github.com/docker/docker/daemon/graphdriver" 16 "github.com/docker/docker/dockerversion" 17 "github.com/docker/docker/image" 18 "github.com/docker/docker/layer" 19 "github.com/docker/docker/reference" 20 "github.com/docker/docker/runconfig" 21 // register the windows graph driver 22 "github.com/docker/docker/daemon/graphdriver/windows" 23 "github.com/docker/docker/pkg/idtools" 24 "github.com/docker/docker/pkg/parsers" 25 "github.com/docker/docker/pkg/system" 26 "github.com/docker/engine-api/types" 27 containertypes "github.com/docker/engine-api/types/container" 28 "github.com/docker/libnetwork" 29 nwconfig "github.com/docker/libnetwork/config" 30 winlibnetwork "github.com/docker/libnetwork/drivers/windows" 31 "github.com/docker/libnetwork/netlabel" 32 "github.com/docker/libnetwork/options" 33 blkiodev "github.com/opencontainers/runc/libcontainer/configs" 34 ) 35 36 const ( 37 defaultNetworkSpace = "172.16.0.0/12" 38 platformSupported = true 39 windowsMinCPUShares = 1 40 windowsMaxCPUShares = 10000 41 ) 42 43 func getBlkioWeightDevices(config *containertypes.HostConfig) ([]blkiodev.WeightDevice, error) { 44 return nil, nil 45 } 46 47 func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error { 48 return nil 49 } 50 51 func getBlkioReadIOpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) { 52 return nil, nil 53 } 54 55 func getBlkioWriteIOpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) { 56 return nil, nil 57 } 58 59 func getBlkioReadBpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) { 60 return nil, nil 61 } 62 63 func getBlkioWriteBpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) { 64 return nil, nil 65 } 66 67 func setupInitLayer(initLayer string, rootUID, rootGID int) error { 68 return nil 69 } 70 71 func checkKernel() error { 72 return nil 73 } 74 75 func (daemon *Daemon) getCgroupDriver() string { 76 return "" 77 } 78 79 // adaptContainerSettings is called during container creation to modify any 80 // settings necessary in the HostConfig structure. 81 func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConfig, adjustCPUShares bool) error { 82 if hostConfig == nil { 83 return nil 84 } 85 86 if hostConfig.CPUShares < 0 { 87 logrus.Warnf("Changing requested CPUShares of %d to minimum allowed of %d", hostConfig.CPUShares, windowsMinCPUShares) 88 hostConfig.CPUShares = windowsMinCPUShares 89 } else if hostConfig.CPUShares > windowsMaxCPUShares { 90 logrus.Warnf("Changing requested CPUShares of %d to maximum allowed of %d", hostConfig.CPUShares, windowsMaxCPUShares) 91 hostConfig.CPUShares = windowsMaxCPUShares 92 } 93 94 return nil 95 } 96 97 // verifyPlatformContainerSettings performs platform-specific validation of the 98 // hostconfig and config structures. 99 func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { 100 return nil, nil 101 } 102 103 // verifyDaemonSettings performs validation of daemon config struct 104 func verifyDaemonSettings(config *Config) error { 105 return nil 106 } 107 108 // checkSystem validates platform-specific requirements 109 func checkSystem() error { 110 // Validate the OS version. Note that docker.exe must be manifested for this 111 // call to return the correct version. 112 osv := system.GetOSVersion() 113 if osv.MajorVersion < 10 { 114 return fmt.Errorf("This version of Windows does not support the docker daemon") 115 } 116 if osv.Build < 14300 { 117 return fmt.Errorf("The Windows daemon requires Windows Server 2016 Technical Preview 5 build 14300 or later") 118 } 119 return nil 120 } 121 122 // configureKernelSecuritySupport configures and validate security support for the kernel 123 func configureKernelSecuritySupport(config *Config, driverName string) error { 124 return nil 125 } 126 127 // configureMaxThreads sets the Go runtime max threads threshold 128 func configureMaxThreads(config *Config) error { 129 return nil 130 } 131 132 func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) { 133 netOptions, err := daemon.networkOptions(config) 134 if err != nil { 135 return nil, err 136 } 137 controller, err := libnetwork.New(netOptions...) 138 if err != nil { 139 return nil, fmt.Errorf("error obtaining controller instance: %v", err) 140 } 141 142 hnsresponse, err := hcsshim.HNSListNetworkRequest("GET", "", "") 143 if err != nil { 144 return nil, err 145 } 146 147 // Remove networks not present in HNS 148 for _, v := range controller.Networks() { 149 options := v.Info().DriverOptions() 150 hnsid := options[winlibnetwork.HNSID] 151 found := false 152 153 for _, v := range hnsresponse { 154 if v.Id == hnsid { 155 found = true 156 break 157 } 158 } 159 160 if !found { 161 err = v.Delete() 162 if err != nil { 163 return nil, err 164 } 165 } 166 } 167 168 _, err = controller.NewNetwork("null", "none", libnetwork.NetworkOptionPersist(false)) 169 if err != nil { 170 return nil, err 171 } 172 173 // discover and add HNS networks to windows 174 // network that exist are removed and added again 175 for _, v := range hnsresponse { 176 var n libnetwork.Network 177 s := func(current libnetwork.Network) bool { 178 options := current.Info().DriverOptions() 179 if options[winlibnetwork.HNSID] == v.Id { 180 n = current 181 return true 182 } 183 return false 184 } 185 186 controller.WalkNetworks(s) 187 if n != nil { 188 v.Name = n.Name() 189 n.Delete() 190 } 191 192 netOption := map[string]string{ 193 winlibnetwork.NetworkName: v.Name, 194 winlibnetwork.HNSID: v.Id, 195 } 196 197 v4Conf := []*libnetwork.IpamConf{} 198 for _, subnet := range v.Subnets { 199 ipamV4Conf := libnetwork.IpamConf{} 200 ipamV4Conf.PreferredPool = subnet.AddressPrefix 201 ipamV4Conf.Gateway = subnet.GatewayAddress 202 v4Conf = append(v4Conf, &ipamV4Conf) 203 } 204 205 name := v.Name 206 // There is only one nat network supported in windows. 207 // If it exists with a different name add it as the default name 208 if runconfig.DefaultDaemonNetworkMode() == containertypes.NetworkMode(strings.ToLower(v.Type)) { 209 name = runconfig.DefaultDaemonNetworkMode().NetworkName() 210 } 211 212 v6Conf := []*libnetwork.IpamConf{} 213 _, err := controller.NewNetwork(strings.ToLower(v.Type), name, 214 libnetwork.NetworkOptionGeneric(options.Generic{ 215 netlabel.GenericData: netOption, 216 }), 217 libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil), 218 ) 219 220 if err != nil { 221 logrus.Errorf("Error occurred when creating network %v", err) 222 } 223 } 224 225 if !config.DisableBridge { 226 // Initialize default driver "bridge" 227 if err := initBridgeDriver(controller, config); err != nil { 228 return nil, err 229 } 230 } 231 232 return controller, nil 233 } 234 235 func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error { 236 if _, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil { 237 return nil 238 } 239 240 netOption := map[string]string{ 241 winlibnetwork.NetworkName: runconfig.DefaultDaemonNetworkMode().NetworkName(), 242 } 243 244 ipamV4Conf := libnetwork.IpamConf{} 245 if config.bridgeConfig.FixedCIDR == "" { 246 ipamV4Conf.PreferredPool = defaultNetworkSpace 247 } else { 248 ipamV4Conf.PreferredPool = config.bridgeConfig.FixedCIDR 249 } 250 251 v4Conf := []*libnetwork.IpamConf{&ipamV4Conf} 252 v6Conf := []*libnetwork.IpamConf{} 253 254 _, err := controller.NewNetwork(string(runconfig.DefaultDaemonNetworkMode()), runconfig.DefaultDaemonNetworkMode().NetworkName(), 255 libnetwork.NetworkOptionGeneric(options.Generic{ 256 netlabel.GenericData: netOption, 257 }), 258 libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil), 259 ) 260 261 if err != nil { 262 return fmt.Errorf("Error creating default network: %v", err) 263 } 264 return nil 265 } 266 267 // registerLinks sets up links between containers and writes the 268 // configuration out for persistence. As of Windows TP4, links are not supported. 269 func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error { 270 return nil 271 } 272 273 func (daemon *Daemon) cleanupMountsByID(in string) error { 274 return nil 275 } 276 277 func (daemon *Daemon) cleanupMounts() error { 278 return nil 279 } 280 281 func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) { 282 return nil, nil, nil 283 } 284 285 func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error { 286 config.Root = rootDir 287 // Create the root directory if it doesn't exists 288 if err := system.MkdirAll(config.Root, 0700); err != nil && !os.IsExist(err) { 289 return err 290 } 291 return nil 292 } 293 294 // runasHyperVContainer returns true if we are going to run as a Hyper-V container 295 func (daemon *Daemon) runAsHyperVContainer(container *container.Container) bool { 296 if container.HostConfig.Isolation.IsDefault() { 297 // Container is set to use the default, so take the default from the daemon configuration 298 return daemon.defaultIsolation.IsHyperV() 299 } 300 301 // Container is requesting an isolation mode. Honour it. 302 return container.HostConfig.Isolation.IsHyperV() 303 304 } 305 306 // conditionalMountOnStart is a platform specific helper function during the 307 // container start to call mount. 308 func (daemon *Daemon) conditionalMountOnStart(container *container.Container) error { 309 // We do not mount if a Hyper-V container 310 if !daemon.runAsHyperVContainer(container) { 311 return daemon.Mount(container) 312 } 313 return nil 314 } 315 316 // conditionalUnmountOnCleanup is a platform specific helper function called 317 // during the cleanup of a container to unmount. 318 func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error { 319 // We do not unmount if a Hyper-V container 320 if !daemon.runAsHyperVContainer(container) { 321 return daemon.Unmount(container) 322 } 323 return nil 324 } 325 326 func restoreCustomImage(is image.Store, ls layer.Store, rs reference.Store) error { 327 type graphDriverStore interface { 328 GraphDriver() graphdriver.Driver 329 } 330 331 gds, ok := ls.(graphDriverStore) 332 if !ok { 333 return nil 334 } 335 336 driver := gds.GraphDriver() 337 wd, ok := driver.(*windows.Driver) 338 if !ok { 339 return nil 340 } 341 342 imageInfos, err := wd.GetCustomImageInfos() 343 if err != nil { 344 return err 345 } 346 347 // Convert imageData to valid image configuration 348 for _, info := range imageInfos { 349 name := strings.ToLower(info.Name) 350 351 type registrar interface { 352 RegisterDiffID(graphID string, size int64) (layer.Layer, error) 353 } 354 r, ok := ls.(registrar) 355 if !ok { 356 return errors.New("Layerstore doesn't support RegisterDiffID") 357 } 358 if _, err := r.RegisterDiffID(info.ID, info.Size); err != nil { 359 return err 360 } 361 // layer is intentionally not released 362 363 rootFS := image.NewRootFSWithBaseLayer(filepath.Base(info.Path)) 364 365 // Create history for base layer 366 config, err := json.Marshal(&image.Image{ 367 V1Image: image.V1Image{ 368 DockerVersion: dockerversion.Version, 369 Architecture: runtime.GOARCH, 370 OS: runtime.GOOS, 371 Created: info.CreatedTime, 372 }, 373 RootFS: rootFS, 374 History: []image.History{}, 375 OSVersion: info.OSVersion, 376 OSFeatures: info.OSFeatures, 377 }) 378 379 named, err := reference.ParseNamed(name) 380 if err != nil { 381 return err 382 } 383 384 ref, err := reference.WithTag(named, info.Version) 385 if err != nil { 386 return err 387 } 388 389 id, err := is.Create(config) 390 if err != nil { 391 logrus.Warnf("Failed to restore custom image %s with error: %s.", name, err) 392 logrus.Warnf("Skipping image %s...", name) 393 continue 394 } 395 396 if err := rs.AddTag(ref, id, true); err != nil { 397 return err 398 } 399 400 logrus.Debugf("Registered base layer %s as %s", ref, id) 401 } 402 return nil 403 } 404 405 func driverOptions(config *Config) []nwconfig.Option { 406 return []nwconfig.Option{} 407 } 408 409 func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) { 410 return nil, nil 411 } 412 413 // setDefaultIsolation determine the default isolation mode for the 414 // daemon to run in. This is only applicable on Windows 415 func (daemon *Daemon) setDefaultIsolation() error { 416 daemon.defaultIsolation = containertypes.Isolation("process") 417 for _, option := range daemon.configStore.ExecOptions { 418 key, val, err := parsers.ParseKeyValueOpt(option) 419 if err != nil { 420 return err 421 } 422 key = strings.ToLower(key) 423 switch key { 424 425 case "isolation": 426 if !containertypes.Isolation(val).IsValid() { 427 return fmt.Errorf("Invalid exec-opt value for 'isolation':'%s'", val) 428 } 429 if containertypes.Isolation(val).IsHyperV() { 430 daemon.defaultIsolation = containertypes.Isolation("hyperv") 431 } 432 default: 433 return fmt.Errorf("Unrecognised exec-opt '%s'\n", key) 434 } 435 } 436 437 logrus.Infof("Windows default isolation mode: %s", daemon.defaultIsolation) 438 return nil 439 } 440 441 func rootFSToAPIType(rootfs *image.RootFS) types.RootFS { 442 var layers []string 443 for _, l := range rootfs.DiffIDs { 444 layers = append(layers, l.String()) 445 } 446 return types.RootFS{ 447 Type: rootfs.Type, 448 Layers: layers, 449 BaseLayer: rootfs.BaseLayer, 450 } 451 }