github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/daemon/daemon.go (about) 1 // Package daemon exposes the functions that occur on the host server 2 // that the Docker daemon is running. 3 // 4 // In implementing the various functions of the daemon, there is often 5 // a method-specific struct for configuring the runtime behavior. 6 package daemon // import "github.com/docker/docker/daemon" 7 8 import ( 9 "context" 10 "fmt" 11 "io/ioutil" 12 "net" 13 "net/url" 14 "os" 15 "path" 16 "path/filepath" 17 "runtime" 18 "strings" 19 "sync" 20 "time" 21 22 "github.com/docker/docker/pkg/fileutils" 23 "google.golang.org/grpc" 24 "google.golang.org/grpc/backoff" 25 26 "github.com/containerd/containerd" 27 "github.com/containerd/containerd/defaults" 28 "github.com/containerd/containerd/pkg/dialer" 29 "github.com/containerd/containerd/remotes/docker" 30 "github.com/docker/docker/api/types" 31 containertypes "github.com/docker/docker/api/types/container" 32 "github.com/docker/docker/api/types/swarm" 33 "github.com/docker/docker/builder" 34 "github.com/docker/docker/container" 35 "github.com/docker/docker/daemon/config" 36 "github.com/docker/docker/daemon/discovery" 37 "github.com/docker/docker/daemon/events" 38 "github.com/docker/docker/daemon/exec" 39 "github.com/docker/docker/daemon/images" 40 "github.com/docker/docker/daemon/logger" 41 "github.com/docker/docker/daemon/network" 42 "github.com/docker/docker/errdefs" 43 bkconfig "github.com/moby/buildkit/cmd/buildkitd/config" 44 "github.com/moby/buildkit/util/resolver" 45 rsystem "github.com/opencontainers/runc/libcontainer/system" 46 "github.com/sirupsen/logrus" 47 48 // register graph drivers 49 _ "github.com/docker/docker/daemon/graphdriver/register" 50 "github.com/docker/docker/daemon/stats" 51 dmetadata "github.com/docker/docker/distribution/metadata" 52 "github.com/docker/docker/dockerversion" 53 "github.com/docker/docker/image" 54 "github.com/docker/docker/layer" 55 "github.com/docker/docker/libcontainerd" 56 libcontainerdtypes "github.com/docker/docker/libcontainerd/types" 57 "github.com/docker/docker/pkg/idtools" 58 "github.com/docker/docker/pkg/locker" 59 "github.com/docker/docker/pkg/plugingetter" 60 "github.com/docker/docker/pkg/system" 61 "github.com/docker/docker/pkg/truncindex" 62 "github.com/docker/docker/plugin" 63 pluginexec "github.com/docker/docker/plugin/executor/containerd" 64 refstore "github.com/docker/docker/reference" 65 "github.com/docker/docker/registry" 66 "github.com/docker/docker/runconfig" 67 volumesservice "github.com/docker/docker/volume/service" 68 "github.com/docker/libnetwork" 69 "github.com/docker/libnetwork/cluster" 70 nwconfig "github.com/docker/libnetwork/config" 71 "github.com/pkg/errors" 72 "golang.org/x/sync/semaphore" 73 ) 74 75 // ContainersNamespace is the name of the namespace used for users containers 76 const ( 77 ContainersNamespace = "moby" 78 ) 79 80 var ( 81 errSystemNotSupported = errors.New("the Docker daemon is not supported on this platform") 82 ) 83 84 // Daemon holds information about the Docker daemon. 85 type Daemon struct { 86 ID string 87 repository string 88 containers container.Store 89 containersReplica container.ViewDB 90 execCommands *exec.Store 91 imageService *images.ImageService 92 idIndex *truncindex.TruncIndex 93 configStore *config.Config 94 statsCollector *stats.Collector 95 defaultLogConfig containertypes.LogConfig 96 RegistryService registry.Service 97 EventsService *events.Events 98 netController libnetwork.NetworkController 99 volumes *volumesservice.VolumesService 100 discoveryWatcher discovery.Reloader 101 root string 102 seccompEnabled bool 103 apparmorEnabled bool 104 shutdown bool 105 idMapping *idtools.IdentityMapping 106 // TODO: move graphDrivers field to an InfoService 107 graphDrivers map[string]string // By operating system 108 109 PluginStore *plugin.Store // todo: remove 110 pluginManager *plugin.Manager 111 linkIndex *linkIndex 112 containerdCli *containerd.Client 113 containerd libcontainerdtypes.Client 114 defaultIsolation containertypes.Isolation // Default isolation mode on Windows 115 clusterProvider cluster.Provider 116 cluster Cluster 117 genericResources []swarm.GenericResource 118 metricsPluginListener net.Listener 119 120 machineMemory uint64 121 122 seccompProfile []byte 123 seccompProfilePath string 124 125 diskUsageRunning int32 126 pruneRunning int32 127 hosts map[string]bool // hosts stores the addresses the daemon is listening on 128 startupDone chan struct{} 129 130 attachmentStore network.AttachmentStore 131 attachableNetworkLock *locker.Locker 132 } 133 134 // StoreHosts stores the addresses the daemon is listening on 135 func (daemon *Daemon) StoreHosts(hosts []string) { 136 if daemon.hosts == nil { 137 daemon.hosts = make(map[string]bool) 138 } 139 for _, h := range hosts { 140 daemon.hosts[h] = true 141 } 142 } 143 144 // HasExperimental returns whether the experimental features of the daemon are enabled or not 145 func (daemon *Daemon) HasExperimental() bool { 146 return daemon.configStore != nil && daemon.configStore.Experimental 147 } 148 149 // Features returns the features map from configStore 150 func (daemon *Daemon) Features() *map[string]bool { 151 return &daemon.configStore.Features 152 } 153 154 // RegistryHosts returns registry configuration in containerd resolvers format 155 func (daemon *Daemon) RegistryHosts() docker.RegistryHosts { 156 var ( 157 registryKey = "docker.io" 158 mirrors = make([]string, len(daemon.configStore.Mirrors)) 159 m = map[string]bkconfig.RegistryConfig{} 160 ) 161 // must trim "https://" or "http://" prefix 162 for i, v := range daemon.configStore.Mirrors { 163 if uri, err := url.Parse(v); err == nil { 164 v = uri.Host 165 } 166 mirrors[i] = v 167 } 168 // set mirrors for default registry 169 m[registryKey] = bkconfig.RegistryConfig{Mirrors: mirrors} 170 171 for _, v := range daemon.configStore.InsecureRegistries { 172 u, err := url.Parse(v) 173 c := bkconfig.RegistryConfig{} 174 if err == nil { 175 v = u.Host 176 t := true 177 if u.Scheme == "http" { 178 c.PlainHTTP = &t 179 } else { 180 c.Insecure = &t 181 } 182 } 183 m[v] = c 184 } 185 186 for k, v := range m { 187 if d, err := registry.HostCertsDir(k); err == nil { 188 v.TLSConfigDir = []string{d} 189 m[k] = v 190 } 191 } 192 193 certsDir := registry.CertsDir() 194 if fis, err := ioutil.ReadDir(certsDir); err == nil { 195 for _, fi := range fis { 196 if _, ok := m[fi.Name()]; !ok { 197 m[fi.Name()] = bkconfig.RegistryConfig{ 198 TLSConfigDir: []string{filepath.Join(certsDir, fi.Name())}, 199 } 200 } 201 } 202 } 203 204 return resolver.NewRegistryConfig(m) 205 } 206 207 func (daemon *Daemon) restore() error { 208 var mapLock sync.Mutex 209 containers := make(map[string]*container.Container) 210 211 logrus.Info("Loading containers: start.") 212 213 dir, err := ioutil.ReadDir(daemon.repository) 214 if err != nil { 215 return err 216 } 217 218 // parallelLimit is the maximum number of parallel startup jobs that we 219 // allow (this is the limited used for all startup semaphores). The multipler 220 // (128) was chosen after some fairly significant benchmarking -- don't change 221 // it unless you've tested it significantly (this value is adjusted if 222 // RLIMIT_NOFILE is small to avoid EMFILE). 223 parallelLimit := adjustParallelLimit(len(dir), 128*runtime.NumCPU()) 224 225 // Re-used for all parallel startup jobs. 226 var group sync.WaitGroup 227 sem := semaphore.NewWeighted(int64(parallelLimit)) 228 229 for _, v := range dir { 230 group.Add(1) 231 go func(id string) { 232 defer group.Done() 233 _ = sem.Acquire(context.Background(), 1) 234 defer sem.Release(1) 235 236 container, err := daemon.load(id) 237 if err != nil { 238 logrus.Errorf("Failed to load container %v: %v", id, err) 239 return 240 } 241 if !system.IsOSSupported(container.OS) { 242 logrus.Errorf("Failed to load container %v: %s (%q)", id, system.ErrNotSupportedOperatingSystem, container.OS) 243 return 244 } 245 // Ignore the container if it does not support the current driver being used by the graph 246 currentDriverForContainerOS := daemon.graphDrivers[container.OS] 247 if (container.Driver == "" && currentDriverForContainerOS == "aufs") || container.Driver == currentDriverForContainerOS { 248 rwlayer, err := daemon.imageService.GetLayerByID(container.ID, container.OS) 249 if err != nil { 250 logrus.Errorf("Failed to load container mount %v: %v", id, err) 251 return 252 } 253 container.RWLayer = rwlayer 254 logrus.Debugf("Loaded container %v, isRunning: %v", container.ID, container.IsRunning()) 255 256 mapLock.Lock() 257 containers[container.ID] = container 258 mapLock.Unlock() 259 } else { 260 logrus.Debugf("Cannot load container %s because it was created with another graph driver.", container.ID) 261 } 262 }(v.Name()) 263 } 264 group.Wait() 265 266 removeContainers := make(map[string]*container.Container) 267 restartContainers := make(map[*container.Container]chan struct{}) 268 activeSandboxes := make(map[string]interface{}) 269 270 for _, c := range containers { 271 group.Add(1) 272 go func(c *container.Container) { 273 defer group.Done() 274 _ = sem.Acquire(context.Background(), 1) 275 defer sem.Release(1) 276 277 if err := daemon.registerName(c); err != nil { 278 logrus.Errorf("Failed to register container name %s: %s", c.ID, err) 279 mapLock.Lock() 280 delete(containers, c.ID) 281 mapLock.Unlock() 282 return 283 } 284 if err := daemon.Register(c); err != nil { 285 logrus.Errorf("Failed to register container %s: %s", c.ID, err) 286 mapLock.Lock() 287 delete(containers, c.ID) 288 mapLock.Unlock() 289 return 290 } 291 292 // The LogConfig.Type is empty if the container was created before docker 1.12 with default log driver. 293 // We should rewrite it to use the daemon defaults. 294 // Fixes https://github.com/docker/docker/issues/22536 295 if c.HostConfig.LogConfig.Type == "" { 296 if err := daemon.mergeAndVerifyLogConfig(&c.HostConfig.LogConfig); err != nil { 297 logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err) 298 } 299 } 300 }(c) 301 } 302 group.Wait() 303 304 for _, c := range containers { 305 group.Add(1) 306 go func(c *container.Container) { 307 defer group.Done() 308 _ = sem.Acquire(context.Background(), 1) 309 defer sem.Release(1) 310 311 daemon.backportMountSpec(c) 312 if err := daemon.checkpointAndSave(c); err != nil { 313 logrus.WithError(err).WithField("container", c.ID).Error("error saving backported mountspec to disk") 314 } 315 316 daemon.setStateCounter(c) 317 318 logrus.WithFields(logrus.Fields{ 319 "container": c.ID, 320 "running": c.IsRunning(), 321 "paused": c.IsPaused(), 322 }).Debug("restoring container") 323 324 var ( 325 err error 326 alive bool 327 ec uint32 328 exitedAt time.Time 329 process libcontainerdtypes.Process 330 ) 331 332 alive, _, process, err = daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio) 333 if err != nil && !errdefs.IsNotFound(err) { 334 logrus.Errorf("Failed to restore container %s with containerd: %s", c.ID, err) 335 return 336 } 337 if !alive && process != nil { 338 ec, exitedAt, err = process.Delete(context.Background()) 339 if err != nil && !errdefs.IsNotFound(err) { 340 logrus.WithError(err).Errorf("Failed to delete container %s from containerd", c.ID) 341 return 342 } 343 } else if !daemon.configStore.LiveRestoreEnabled { 344 if err := daemon.shutdownContainer(c); err != nil && !errdefs.IsNotFound(err) { 345 logrus.WithError(err).WithField("container", c.ID).Error("error shutting down container") 346 return 347 } 348 c.ResetRestartManager(false) 349 } 350 351 if c.IsRunning() || c.IsPaused() { 352 c.RestartManager().Cancel() // manually start containers because some need to wait for swarm networking 353 354 if c.IsPaused() && alive { 355 s, err := daemon.containerd.Status(context.Background(), c.ID) 356 if err != nil { 357 logrus.WithError(err).WithField("container", c.ID). 358 Errorf("Failed to get container status") 359 } else { 360 logrus.WithField("container", c.ID).WithField("state", s). 361 Info("restored container paused") 362 switch s { 363 case containerd.Paused, containerd.Pausing: 364 // nothing to do 365 case containerd.Stopped: 366 alive = false 367 case containerd.Unknown: 368 logrus.WithField("container", c.ID). 369 Error("Unknown status for container during restore") 370 default: 371 // running 372 c.Lock() 373 c.Paused = false 374 daemon.setStateCounter(c) 375 if err := c.CheckpointTo(daemon.containersReplica); err != nil { 376 logrus.WithError(err).WithField("container", c.ID). 377 Error("Failed to update stopped container state") 378 } 379 c.Unlock() 380 } 381 } 382 } 383 384 if !alive { 385 c.Lock() 386 c.SetStopped(&container.ExitStatus{ExitCode: int(ec), ExitedAt: exitedAt}) 387 daemon.Cleanup(c) 388 if err := c.CheckpointTo(daemon.containersReplica); err != nil { 389 logrus.Errorf("Failed to update stopped container %s state: %v", c.ID, err) 390 } 391 c.Unlock() 392 } 393 394 // we call Mount and then Unmount to get BaseFs of the container 395 if err := daemon.Mount(c); err != nil { 396 // The mount is unlikely to fail. However, in case mount fails 397 // the container should be allowed to restore here. Some functionalities 398 // (like docker exec -u user) might be missing but container is able to be 399 // stopped/restarted/removed. 400 // See #29365 for related information. 401 // The error is only logged here. 402 logrus.Warnf("Failed to mount container on getting BaseFs path %v: %v", c.ID, err) 403 } else { 404 if err := daemon.Unmount(c); err != nil { 405 logrus.Warnf("Failed to umount container on getting BaseFs path %v: %v", c.ID, err) 406 } 407 } 408 409 c.ResetRestartManager(false) 410 if !c.HostConfig.NetworkMode.IsContainer() && c.IsRunning() { 411 options, err := daemon.buildSandboxOptions(c) 412 if err != nil { 413 logrus.Warnf("Failed build sandbox option to restore container %s: %v", c.ID, err) 414 } 415 mapLock.Lock() 416 activeSandboxes[c.NetworkSettings.SandboxID] = options 417 mapLock.Unlock() 418 } 419 } 420 421 // get list of containers we need to restart 422 423 // Do not autostart containers which 424 // has endpoints in a swarm scope 425 // network yet since the cluster is 426 // not initialized yet. We will start 427 // it after the cluster is 428 // initialized. 429 if daemon.configStore.AutoRestart && c.ShouldRestart() && !c.NetworkSettings.HasSwarmEndpoint && c.HasBeenStartedBefore { 430 mapLock.Lock() 431 restartContainers[c] = make(chan struct{}) 432 mapLock.Unlock() 433 } else if c.HostConfig != nil && c.HostConfig.AutoRemove { 434 mapLock.Lock() 435 removeContainers[c.ID] = c 436 mapLock.Unlock() 437 } 438 439 c.Lock() 440 if c.RemovalInProgress { 441 // We probably crashed in the middle of a removal, reset 442 // the flag. 443 // 444 // We DO NOT remove the container here as we do not 445 // know if the user had requested for either the 446 // associated volumes, network links or both to also 447 // be removed. So we put the container in the "dead" 448 // state and leave further processing up to them. 449 logrus.Debugf("Resetting RemovalInProgress flag from %v", c.ID) 450 c.RemovalInProgress = false 451 c.Dead = true 452 if err := c.CheckpointTo(daemon.containersReplica); err != nil { 453 logrus.Errorf("Failed to update RemovalInProgress container %s state: %v", c.ID, err) 454 } 455 } 456 c.Unlock() 457 }(c) 458 } 459 group.Wait() 460 461 daemon.netController, err = daemon.initNetworkController(daemon.configStore, activeSandboxes) 462 if err != nil { 463 return fmt.Errorf("Error initializing network controller: %v", err) 464 } 465 466 // Now that all the containers are registered, register the links 467 for _, c := range containers { 468 group.Add(1) 469 go func(c *container.Container) { 470 _ = sem.Acquire(context.Background(), 1) 471 472 if err := daemon.registerLinks(c, c.HostConfig); err != nil { 473 logrus.Errorf("failed to register link for container %s: %v", c.ID, err) 474 } 475 476 sem.Release(1) 477 group.Done() 478 }(c) 479 } 480 group.Wait() 481 482 for c, notifier := range restartContainers { 483 group.Add(1) 484 go func(c *container.Container, chNotify chan struct{}) { 485 _ = sem.Acquire(context.Background(), 1) 486 logrus.Debugf("Starting container %s", c.ID) 487 488 // ignore errors here as this is a best effort to wait for children to be 489 // running before we try to start the container 490 children := daemon.children(c) 491 timeout := time.NewTimer(5 * time.Second) 492 defer timeout.Stop() 493 494 for _, child := range children { 495 if notifier, exists := restartContainers[child]; exists { 496 select { 497 case <-notifier: 498 case <-timeout.C: 499 } 500 } 501 } 502 503 // Make sure networks are available before starting 504 daemon.waitForNetworks(c) 505 if err := daemon.containerStart(c, "", "", true); err != nil { 506 logrus.Errorf("Failed to start container %s: %s", c.ID, err) 507 } 508 close(chNotify) 509 510 sem.Release(1) 511 group.Done() 512 }(c, notifier) 513 } 514 group.Wait() 515 516 for id := range removeContainers { 517 group.Add(1) 518 go func(cid string) { 519 _ = sem.Acquire(context.Background(), 1) 520 521 if err := daemon.ContainerRm(cid, &types.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil { 522 logrus.Errorf("Failed to remove container %s: %s", cid, err) 523 } 524 525 sem.Release(1) 526 group.Done() 527 }(id) 528 } 529 group.Wait() 530 531 // any containers that were started above would already have had this done, 532 // however we need to now prepare the mountpoints for the rest of the containers as well. 533 // This shouldn't cause any issue running on the containers that already had this run. 534 // This must be run after any containers with a restart policy so that containerized plugins 535 // can have a chance to be running before we try to initialize them. 536 for _, c := range containers { 537 // if the container has restart policy, do not 538 // prepare the mountpoints since it has been done on restarting. 539 // This is to speed up the daemon start when a restart container 540 // has a volume and the volume driver is not available. 541 if _, ok := restartContainers[c]; ok { 542 continue 543 } else if _, ok := removeContainers[c.ID]; ok { 544 // container is automatically removed, skip it. 545 continue 546 } 547 548 group.Add(1) 549 go func(c *container.Container) { 550 _ = sem.Acquire(context.Background(), 1) 551 552 if err := daemon.prepareMountPoints(c); err != nil { 553 logrus.Error(err) 554 } 555 556 sem.Release(1) 557 group.Done() 558 }(c) 559 } 560 group.Wait() 561 562 logrus.Info("Loading containers: done.") 563 564 return nil 565 } 566 567 // RestartSwarmContainers restarts any autostart container which has a 568 // swarm endpoint. 569 func (daemon *Daemon) RestartSwarmContainers() { 570 ctx := context.Background() 571 572 // parallelLimit is the maximum number of parallel startup jobs that we 573 // allow (this is the limited used for all startup semaphores). The multipler 574 // (128) was chosen after some fairly significant benchmarking -- don't change 575 // it unless you've tested it significantly (this value is adjusted if 576 // RLIMIT_NOFILE is small to avoid EMFILE). 577 parallelLimit := adjustParallelLimit(len(daemon.List()), 128*runtime.NumCPU()) 578 579 var group sync.WaitGroup 580 sem := semaphore.NewWeighted(int64(parallelLimit)) 581 582 for _, c := range daemon.List() { 583 if !c.IsRunning() && !c.IsPaused() { 584 // Autostart all the containers which has a 585 // swarm endpoint now that the cluster is 586 // initialized. 587 if daemon.configStore.AutoRestart && c.ShouldRestart() && c.NetworkSettings.HasSwarmEndpoint && c.HasBeenStartedBefore { 588 group.Add(1) 589 go func(c *container.Container) { 590 if err := sem.Acquire(ctx, 1); err != nil { 591 // ctx is done. 592 group.Done() 593 return 594 } 595 596 if err := daemon.containerStart(c, "", "", true); err != nil { 597 logrus.Error(err) 598 } 599 600 sem.Release(1) 601 group.Done() 602 }(c) 603 } 604 } 605 } 606 group.Wait() 607 } 608 609 // waitForNetworks is used during daemon initialization when starting up containers 610 // It ensures that all of a container's networks are available before the daemon tries to start the container. 611 // In practice it just makes sure the discovery service is available for containers which use a network that require discovery. 612 func (daemon *Daemon) waitForNetworks(c *container.Container) { 613 if daemon.discoveryWatcher == nil { 614 return 615 } 616 617 // Make sure if the container has a network that requires discovery that the discovery service is available before starting 618 for netName := range c.NetworkSettings.Networks { 619 // If we get `ErrNoSuchNetwork` here, we can assume that it is due to discovery not being ready 620 // Most likely this is because the K/V store used for discovery is in a container and needs to be started 621 if _, err := daemon.netController.NetworkByName(netName); err != nil { 622 if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok { 623 continue 624 } 625 626 // use a longish timeout here due to some slowdowns in libnetwork if the k/v store is on anything other than --net=host 627 // FIXME: why is this slow??? 628 dur := 60 * time.Second 629 timer := time.NewTimer(dur) 630 631 logrus.Debugf("Container %s waiting for network to be ready", c.Name) 632 select { 633 case <-daemon.discoveryWatcher.ReadyCh(): 634 case <-timer.C: 635 } 636 timer.Stop() 637 638 return 639 } 640 } 641 } 642 643 func (daemon *Daemon) children(c *container.Container) map[string]*container.Container { 644 return daemon.linkIndex.children(c) 645 } 646 647 // parents returns the names of the parent containers of the container 648 // with the given name. 649 func (daemon *Daemon) parents(c *container.Container) map[string]*container.Container { 650 return daemon.linkIndex.parents(c) 651 } 652 653 func (daemon *Daemon) registerLink(parent, child *container.Container, alias string) error { 654 fullName := path.Join(parent.Name, alias) 655 if err := daemon.containersReplica.ReserveName(fullName, child.ID); err != nil { 656 if err == container.ErrNameReserved { 657 logrus.Warnf("error registering link for %s, to %s, as alias %s, ignoring: %v", parent.ID, child.ID, alias, err) 658 return nil 659 } 660 return err 661 } 662 daemon.linkIndex.link(parent, child, fullName) 663 return nil 664 } 665 666 // DaemonJoinsCluster informs the daemon has joined the cluster and provides 667 // the handler to query the cluster component 668 func (daemon *Daemon) DaemonJoinsCluster(clusterProvider cluster.Provider) { 669 daemon.setClusterProvider(clusterProvider) 670 } 671 672 // DaemonLeavesCluster informs the daemon has left the cluster 673 func (daemon *Daemon) DaemonLeavesCluster() { 674 // Daemon is in charge of removing the attachable networks with 675 // connected containers when the node leaves the swarm 676 daemon.clearAttachableNetworks() 677 // We no longer need the cluster provider, stop it now so that 678 // the network agent will stop listening to cluster events. 679 daemon.setClusterProvider(nil) 680 // Wait for the networking cluster agent to stop 681 daemon.netController.AgentStopWait() 682 // Daemon is in charge of removing the ingress network when the 683 // node leaves the swarm. Wait for job to be done or timeout. 684 // This is called also on graceful daemon shutdown. We need to 685 // wait, because the ingress release has to happen before the 686 // network controller is stopped. 687 688 if done, err := daemon.ReleaseIngress(); err == nil { 689 timeout := time.NewTimer(5 * time.Second) 690 defer timeout.Stop() 691 692 select { 693 case <-done: 694 case <-timeout.C: 695 logrus.Warn("timeout while waiting for ingress network removal") 696 } 697 } else { 698 logrus.Warnf("failed to initiate ingress network removal: %v", err) 699 } 700 701 daemon.attachmentStore.ClearAttachments() 702 } 703 704 // setClusterProvider sets a component for querying the current cluster state. 705 func (daemon *Daemon) setClusterProvider(clusterProvider cluster.Provider) { 706 daemon.clusterProvider = clusterProvider 707 daemon.netController.SetClusterProvider(clusterProvider) 708 daemon.attachableNetworkLock = locker.New() 709 } 710 711 // IsSwarmCompatible verifies if the current daemon 712 // configuration is compatible with the swarm mode 713 func (daemon *Daemon) IsSwarmCompatible() error { 714 if daemon.configStore == nil { 715 return nil 716 } 717 return daemon.configStore.IsSwarmCompatible() 718 } 719 720 // NewDaemon sets up everything for the daemon to be able to service 721 // requests from the webserver. 722 func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.Store) (daemon *Daemon, err error) { 723 setDefaultMtu(config) 724 725 registryService, err := registry.NewService(config.ServiceOptions) 726 if err != nil { 727 return nil, err 728 } 729 730 // Ensure that we have a correct root key limit for launching containers. 731 if err := ModifyRootKeyLimit(); err != nil { 732 logrus.Warnf("unable to modify root key limit, number of containers could be limited by this quota: %v", err) 733 } 734 735 // Ensure we have compatible and valid configuration options 736 if err := verifyDaemonSettings(config); err != nil { 737 return nil, err 738 } 739 740 // Do we have a disabled network? 741 config.DisableBridge = isBridgeNetworkDisabled(config) 742 743 // Setup the resolv.conf 744 setupResolvConf(config) 745 746 // Verify the platform is supported as a daemon 747 if !platformSupported { 748 return nil, errSystemNotSupported 749 } 750 751 // Validate platform-specific requirements 752 if err := checkSystem(); err != nil { 753 return nil, err 754 } 755 756 idMapping, err := setupRemappedRoot(config) 757 if err != nil { 758 return nil, err 759 } 760 rootIDs := idMapping.RootPair() 761 if err := setupDaemonProcess(config); err != nil { 762 return nil, err 763 } 764 765 // set up the tmpDir to use a canonical path 766 tmp, err := prepareTempDir(config.Root, rootIDs) 767 if err != nil { 768 return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err) 769 } 770 realTmp, err := fileutils.ReadSymlinkedDirectory(tmp) 771 if err != nil { 772 return nil, fmt.Errorf("Unable to get the full path to the TempDir (%s): %s", tmp, err) 773 } 774 if isWindows { 775 if _, err := os.Stat(realTmp); err != nil && os.IsNotExist(err) { 776 if err := system.MkdirAll(realTmp, 0700); err != nil { 777 return nil, fmt.Errorf("Unable to create the TempDir (%s): %s", realTmp, err) 778 } 779 } 780 os.Setenv("TEMP", realTmp) 781 os.Setenv("TMP", realTmp) 782 } else { 783 os.Setenv("TMPDIR", realTmp) 784 } 785 786 d := &Daemon{ 787 configStore: config, 788 PluginStore: pluginStore, 789 startupDone: make(chan struct{}), 790 } 791 792 // Ensure the daemon is properly shutdown if there is a failure during 793 // initialization 794 defer func() { 795 if err != nil { 796 if err := d.Shutdown(); err != nil { 797 logrus.Error(err) 798 } 799 } 800 }() 801 802 if err := d.setGenericResources(config); err != nil { 803 return nil, err 804 } 805 // set up SIGUSR1 handler on Unix-like systems, or a Win32 global event 806 // on Windows to dump Go routine stacks 807 stackDumpDir := config.Root 808 if execRoot := config.GetExecRoot(); execRoot != "" { 809 stackDumpDir = execRoot 810 } 811 d.setupDumpStackTrap(stackDumpDir) 812 813 if err := d.setupSeccompProfile(); err != nil { 814 return nil, err 815 } 816 817 // Set the default isolation mode (only applicable on Windows) 818 if err := d.setDefaultIsolation(); err != nil { 819 return nil, fmt.Errorf("error setting default isolation mode: %v", err) 820 } 821 822 if err := configureMaxThreads(config); err != nil { 823 logrus.Warnf("Failed to configure golang's threads limit: %v", err) 824 } 825 826 // ensureDefaultAppArmorProfile does nothing if apparmor is disabled 827 if err := ensureDefaultAppArmorProfile(); err != nil { 828 logrus.Errorf(err.Error()) 829 } 830 831 daemonRepo := filepath.Join(config.Root, "containers") 832 if err := idtools.MkdirAllAndChown(daemonRepo, 0700, rootIDs); err != nil { 833 return nil, err 834 } 835 836 // Create the directory where we'll store the runtime scripts (i.e. in 837 // order to support runtimeArgs) 838 daemonRuntimes := filepath.Join(config.Root, "runtimes") 839 if err := system.MkdirAll(daemonRuntimes, 0700); err != nil { 840 return nil, err 841 } 842 if err := d.loadRuntimes(); err != nil { 843 return nil, err 844 } 845 846 if isWindows { 847 if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0); err != nil { 848 return nil, err 849 } 850 } 851 852 // On Windows we don't support the environment variable, or a user supplied graphdriver 853 // as Windows has no choice in terms of which graphdrivers to use. It's a case of 854 // running Windows containers on Windows - windowsfilter, running Linux containers on Windows, 855 // lcow. Unix platforms however run a single graphdriver for all containers, and it can 856 // be set through an environment variable, a daemon start parameter, or chosen through 857 // initialization of the layerstore through driver priority order for example. 858 d.graphDrivers = make(map[string]string) 859 layerStores := make(map[string]layer.Store) 860 if isWindows { 861 d.graphDrivers[runtime.GOOS] = "windowsfilter" 862 if system.LCOWSupported() { 863 d.graphDrivers["linux"] = "lcow" 864 } 865 } else { 866 driverName := os.Getenv("DOCKER_DRIVER") 867 if driverName == "" { 868 driverName = config.GraphDriver 869 } else { 870 logrus.Infof("Setting the storage driver from the $DOCKER_DRIVER environment variable (%s)", driverName) 871 } 872 d.graphDrivers[runtime.GOOS] = driverName // May still be empty. Layerstore init determines instead. 873 } 874 875 d.RegistryService = registryService 876 logger.RegisterPluginGetter(d.PluginStore) 877 878 metricsSockPath, err := d.listenMetricsSock() 879 if err != nil { 880 return nil, err 881 } 882 registerMetricsPluginCallback(d.PluginStore, metricsSockPath) 883 884 backoffConfig := backoff.DefaultConfig 885 backoffConfig.MaxDelay = 3 * time.Second 886 connParams := grpc.ConnectParams{ 887 Backoff: backoffConfig, 888 } 889 gopts := []grpc.DialOption{ 890 // WithBlock makes sure that the following containerd request 891 // is reliable. 892 // 893 // NOTE: In one edge case with high load pressure, kernel kills 894 // dockerd, containerd and containerd-shims caused by OOM. 895 // When both dockerd and containerd restart, but containerd 896 // will take time to recover all the existing containers. Before 897 // containerd serving, dockerd will failed with gRPC error. 898 // That bad thing is that restore action will still ignore the 899 // any non-NotFound errors and returns running state for 900 // already stopped container. It is unexpected behavior. And 901 // we need to restart dockerd to make sure that anything is OK. 902 // 903 // It is painful. Add WithBlock can prevent the edge case. And 904 // n common case, the containerd will be serving in shortly. 905 // It is not harm to add WithBlock for containerd connection. 906 grpc.WithBlock(), 907 908 grpc.WithInsecure(), 909 grpc.WithConnectParams(connParams), 910 grpc.WithContextDialer(dialer.ContextDialer), 911 912 // TODO(stevvooe): We may need to allow configuration of this on the client. 913 grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)), 914 grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), 915 } 916 if config.ContainerdAddr != "" { 917 d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) 918 if err != nil { 919 return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr) 920 } 921 } 922 923 createPluginExec := func(m *plugin.Manager) (plugin.Executor, error) { 924 var pluginCli *containerd.Client 925 926 // Windows is not currently using containerd, keep the 927 // client as nil 928 if config.ContainerdAddr != "" { 929 pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) 930 if err != nil { 931 return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr) 932 } 933 } 934 935 return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, config.ContainerdPluginNamespace, m, d.useShimV2()) 936 } 937 938 // Plugin system initialization should happen before restore. Do not change order. 939 d.pluginManager, err = plugin.NewManager(plugin.ManagerConfig{ 940 Root: filepath.Join(config.Root, "plugins"), 941 ExecRoot: getPluginExecRoot(config.Root), 942 Store: d.PluginStore, 943 CreateExecutor: createPluginExec, 944 RegistryService: registryService, 945 LiveRestoreEnabled: config.LiveRestoreEnabled, 946 LogPluginEvent: d.LogPluginEvent, // todo: make private 947 AuthzMiddleware: config.AuthzMiddleware, 948 }) 949 if err != nil { 950 return nil, errors.Wrap(err, "couldn't create plugin manager") 951 } 952 953 if err := d.setupDefaultLogConfig(); err != nil { 954 return nil, err 955 } 956 957 for operatingSystem, gd := range d.graphDrivers { 958 layerStores[operatingSystem], err = layer.NewStoreFromOptions(layer.StoreOptions{ 959 Root: config.Root, 960 MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"), 961 GraphDriver: gd, 962 GraphDriverOptions: config.GraphOptions, 963 IDMapping: idMapping, 964 PluginGetter: d.PluginStore, 965 ExperimentalEnabled: config.Experimental, 966 OS: operatingSystem, 967 }) 968 if err != nil { 969 return nil, err 970 } 971 972 // As layerstore initialization may set the driver 973 d.graphDrivers[operatingSystem] = layerStores[operatingSystem].DriverName() 974 } 975 976 // Configure and validate the kernels security support. Note this is a Linux/FreeBSD 977 // operation only, so it is safe to pass *just* the runtime OS graphdriver. 978 if err := configureKernelSecuritySupport(config, d.graphDrivers[runtime.GOOS]); err != nil { 979 return nil, err 980 } 981 982 imageRoot := filepath.Join(config.Root, "image", d.graphDrivers[runtime.GOOS]) 983 ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb")) 984 if err != nil { 985 return nil, err 986 } 987 988 lgrMap := make(map[string]image.LayerGetReleaser) 989 for los, ls := range layerStores { 990 lgrMap[los] = ls 991 } 992 imageStore, err := image.NewImageStore(ifs, lgrMap) 993 if err != nil { 994 return nil, err 995 } 996 997 d.volumes, err = volumesservice.NewVolumeService(config.Root, d.PluginStore, rootIDs, d) 998 if err != nil { 999 return nil, err 1000 } 1001 1002 trustKey, err := loadOrCreateTrustKey(config.TrustKeyPath) 1003 if err != nil { 1004 return nil, err 1005 } 1006 1007 trustDir := filepath.Join(config.Root, "trust") 1008 1009 if err := system.MkdirAll(trustDir, 0700); err != nil { 1010 return nil, err 1011 } 1012 1013 // We have a single tag/reference store for the daemon globally. However, it's 1014 // stored under the graphdriver. On host platforms which only support a single 1015 // container OS, but multiple selectable graphdrivers, this means depending on which 1016 // graphdriver is chosen, the global reference store is under there. For 1017 // platforms which support multiple container operating systems, this is slightly 1018 // more problematic as where does the global ref store get located? Fortunately, 1019 // for Windows, which is currently the only daemon supporting multiple container 1020 // operating systems, the list of graphdrivers available isn't user configurable. 1021 // For backwards compatibility, we just put it under the windowsfilter 1022 // directory regardless. 1023 refStoreLocation := filepath.Join(imageRoot, `repositories.json`) 1024 rs, err := refstore.NewReferenceStore(refStoreLocation) 1025 if err != nil { 1026 return nil, fmt.Errorf("Couldn't create reference store repository: %s", err) 1027 } 1028 1029 distributionMetadataStore, err := dmetadata.NewFSMetadataStore(filepath.Join(imageRoot, "distribution")) 1030 if err != nil { 1031 return nil, err 1032 } 1033 1034 // Discovery is only enabled when the daemon is launched with an address to advertise. When 1035 // initialized, the daemon is registered and we can store the discovery backend as it's read-only 1036 if err := d.initDiscovery(config); err != nil { 1037 return nil, err 1038 } 1039 1040 sysInfo := d.RawSysInfo(false) 1041 // Check if Devices cgroup is mounted, it is hard requirement for container security, 1042 // on Linux. 1043 if runtime.GOOS == "linux" && !sysInfo.CgroupDevicesEnabled && !rsystem.RunningInUserNS() { 1044 return nil, errors.New("Devices cgroup isn't mounted") 1045 } 1046 1047 d.ID = trustKey.PublicKey().KeyID() 1048 d.repository = daemonRepo 1049 d.containers = container.NewMemoryStore() 1050 if d.containersReplica, err = container.NewViewDB(); err != nil { 1051 return nil, err 1052 } 1053 d.execCommands = exec.NewStore() 1054 d.idIndex = truncindex.NewTruncIndex([]string{}) 1055 d.statsCollector = d.newStatsCollector(1 * time.Second) 1056 1057 d.EventsService = events.New() 1058 d.root = config.Root 1059 d.idMapping = idMapping 1060 d.seccompEnabled = sysInfo.Seccomp 1061 d.apparmorEnabled = sysInfo.AppArmor 1062 1063 d.linkIndex = newLinkIndex() 1064 1065 // TODO: imageStore, distributionMetadataStore, and ReferenceStore are only 1066 // used above to run migration. They could be initialized in ImageService 1067 // if migration is called from daemon/images. layerStore might move as well. 1068 d.imageService = images.NewImageService(images.ImageServiceConfig{ 1069 ContainerStore: d.containers, 1070 DistributionMetadataStore: distributionMetadataStore, 1071 EventsService: d.EventsService, 1072 ImageStore: imageStore, 1073 LayerStores: layerStores, 1074 MaxConcurrentDownloads: *config.MaxConcurrentDownloads, 1075 MaxConcurrentUploads: *config.MaxConcurrentUploads, 1076 MaxDownloadAttempts: *config.MaxDownloadAttempts, 1077 ReferenceStore: rs, 1078 RegistryService: registryService, 1079 TrustKey: trustKey, 1080 }) 1081 1082 go d.execCommandGC() 1083 1084 d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d, d.useShimV2()) 1085 if err != nil { 1086 return nil, err 1087 } 1088 1089 if err := d.restore(); err != nil { 1090 return nil, err 1091 } 1092 close(d.startupDone) 1093 1094 info := d.SystemInfo() 1095 1096 engineInfo.WithValues( 1097 dockerversion.Version, 1098 dockerversion.GitCommit, 1099 info.Architecture, 1100 info.Driver, 1101 info.KernelVersion, 1102 info.OperatingSystem, 1103 info.OSType, 1104 info.OSVersion, 1105 info.ID, 1106 ).Set(1) 1107 engineCpus.Set(float64(info.NCPU)) 1108 engineMemory.Set(float64(info.MemTotal)) 1109 1110 gd := "" 1111 for os, driver := range d.graphDrivers { 1112 if len(gd) > 0 { 1113 gd += ", " 1114 } 1115 gd += driver 1116 if len(d.graphDrivers) > 1 { 1117 gd = fmt.Sprintf("%s (%s)", gd, os) 1118 } 1119 } 1120 logrus.WithFields(logrus.Fields{ 1121 "version": dockerversion.Version, 1122 "commit": dockerversion.GitCommit, 1123 "graphdriver(s)": gd, 1124 }).Info("Docker daemon") 1125 1126 return d, nil 1127 } 1128 1129 // DistributionServices returns services controlling daemon storage 1130 func (daemon *Daemon) DistributionServices() images.DistributionServices { 1131 return daemon.imageService.DistributionServices() 1132 } 1133 1134 func (daemon *Daemon) waitForStartupDone() { 1135 <-daemon.startupDone 1136 } 1137 1138 func (daemon *Daemon) shutdownContainer(c *container.Container) error { 1139 stopTimeout := c.StopTimeout() 1140 1141 // If container failed to exit in stopTimeout seconds of SIGTERM, then using the force 1142 if err := daemon.containerStop(c, stopTimeout); err != nil { 1143 return fmt.Errorf("Failed to stop container %s with error: %v", c.ID, err) 1144 } 1145 1146 // Wait without timeout for the container to exit. 1147 // Ignore the result. 1148 <-c.Wait(context.Background(), container.WaitConditionNotRunning) 1149 return nil 1150 } 1151 1152 // ShutdownTimeout returns the timeout (in seconds) before containers are forcibly 1153 // killed during shutdown. The default timeout can be configured both on the daemon 1154 // and per container, and the longest timeout will be used. A grace-period of 1155 // 5 seconds is added to the configured timeout. 1156 // 1157 // A negative (-1) timeout means "indefinitely", which means that containers 1158 // are not forcibly killed, and the daemon shuts down after all containers exit. 1159 func (daemon *Daemon) ShutdownTimeout() int { 1160 shutdownTimeout := daemon.configStore.ShutdownTimeout 1161 if shutdownTimeout < 0 { 1162 return -1 1163 } 1164 if daemon.containers == nil { 1165 return shutdownTimeout 1166 } 1167 1168 graceTimeout := 5 1169 for _, c := range daemon.containers.List() { 1170 stopTimeout := c.StopTimeout() 1171 if stopTimeout < 0 { 1172 return -1 1173 } 1174 if stopTimeout+graceTimeout > shutdownTimeout { 1175 shutdownTimeout = stopTimeout + graceTimeout 1176 } 1177 } 1178 return shutdownTimeout 1179 } 1180 1181 // Shutdown stops the daemon. 1182 func (daemon *Daemon) Shutdown() error { 1183 daemon.shutdown = true 1184 // Keep mounts and networking running on daemon shutdown if 1185 // we are to keep containers running and restore them. 1186 1187 if daemon.configStore.LiveRestoreEnabled && daemon.containers != nil { 1188 // check if there are any running containers, if none we should do some cleanup 1189 if ls, err := daemon.Containers(&types.ContainerListOptions{}); len(ls) != 0 || err != nil { 1190 // metrics plugins still need some cleanup 1191 daemon.cleanupMetricsPlugins() 1192 return nil 1193 } 1194 } 1195 1196 if daemon.containers != nil { 1197 logrus.Debugf("daemon configured with a %d seconds minimum shutdown timeout", daemon.configStore.ShutdownTimeout) 1198 logrus.Debugf("start clean shutdown of all containers with a %d seconds timeout...", daemon.ShutdownTimeout()) 1199 daemon.containers.ApplyAll(func(c *container.Container) { 1200 if !c.IsRunning() { 1201 return 1202 } 1203 logrus.Debugf("stopping %s", c.ID) 1204 if err := daemon.shutdownContainer(c); err != nil { 1205 logrus.Errorf("Stop container error: %v", err) 1206 return 1207 } 1208 if mountid, err := daemon.imageService.GetLayerMountID(c.ID, c.OS); err == nil { 1209 daemon.cleanupMountsByID(mountid) 1210 } 1211 logrus.Debugf("container stopped %s", c.ID) 1212 }) 1213 } 1214 1215 if daemon.volumes != nil { 1216 if err := daemon.volumes.Shutdown(); err != nil { 1217 logrus.Errorf("Error shutting down volume store: %v", err) 1218 } 1219 } 1220 1221 if daemon.imageService != nil { 1222 daemon.imageService.Cleanup() 1223 } 1224 1225 // If we are part of a cluster, clean up cluster's stuff 1226 if daemon.clusterProvider != nil { 1227 logrus.Debugf("start clean shutdown of cluster resources...") 1228 daemon.DaemonLeavesCluster() 1229 } 1230 1231 daemon.cleanupMetricsPlugins() 1232 1233 // Shutdown plugins after containers and layerstore. Don't change the order. 1234 daemon.pluginShutdown() 1235 1236 // trigger libnetwork Stop only if it's initialized 1237 if daemon.netController != nil { 1238 daemon.netController.Stop() 1239 } 1240 1241 if daemon.containerdCli != nil { 1242 daemon.containerdCli.Close() 1243 } 1244 1245 return daemon.cleanupMounts() 1246 } 1247 1248 // Mount sets container.BaseFS 1249 // (is it not set coming in? why is it unset?) 1250 func (daemon *Daemon) Mount(container *container.Container) error { 1251 if container.RWLayer == nil { 1252 return errors.New("RWLayer of container " + container.ID + " is unexpectedly nil") 1253 } 1254 dir, err := container.RWLayer.Mount(container.GetMountLabel()) 1255 if err != nil { 1256 return err 1257 } 1258 logrus.Debugf("container mounted via layerStore: %v", dir) 1259 1260 if container.BaseFS != nil && container.BaseFS.Path() != dir.Path() { 1261 // The mount path reported by the graph driver should always be trusted on Windows, since the 1262 // volume path for a given mounted layer may change over time. This should only be an error 1263 // on non-Windows operating systems. 1264 if runtime.GOOS != "windows" { 1265 daemon.Unmount(container) 1266 return fmt.Errorf("Error: driver %s is returning inconsistent paths for container %s ('%s' then '%s')", 1267 daemon.imageService.GraphDriverForOS(container.OS), container.ID, container.BaseFS, dir) 1268 } 1269 } 1270 container.BaseFS = dir // TODO: combine these fields 1271 return nil 1272 } 1273 1274 // Unmount unsets the container base filesystem 1275 func (daemon *Daemon) Unmount(container *container.Container) error { 1276 if container.RWLayer == nil { 1277 return errors.New("RWLayer of container " + container.ID + " is unexpectedly nil") 1278 } 1279 if err := container.RWLayer.Unmount(); err != nil { 1280 logrus.Errorf("Error unmounting container %s: %s", container.ID, err) 1281 return err 1282 } 1283 1284 return nil 1285 } 1286 1287 // Subnets return the IPv4 and IPv6 subnets of networks that are manager by Docker. 1288 func (daemon *Daemon) Subnets() ([]net.IPNet, []net.IPNet) { 1289 var v4Subnets []net.IPNet 1290 var v6Subnets []net.IPNet 1291 1292 managedNetworks := daemon.netController.Networks() 1293 1294 for _, managedNetwork := range managedNetworks { 1295 v4infos, v6infos := managedNetwork.Info().IpamInfo() 1296 for _, info := range v4infos { 1297 if info.IPAMData.Pool != nil { 1298 v4Subnets = append(v4Subnets, *info.IPAMData.Pool) 1299 } 1300 } 1301 for _, info := range v6infos { 1302 if info.IPAMData.Pool != nil { 1303 v6Subnets = append(v6Subnets, *info.IPAMData.Pool) 1304 } 1305 } 1306 } 1307 1308 return v4Subnets, v6Subnets 1309 } 1310 1311 // prepareTempDir prepares and returns the default directory to use 1312 // for temporary files. 1313 // If it doesn't exist, it is created. If it exists, its content is removed. 1314 func prepareTempDir(rootDir string, rootIdentity idtools.Identity) (string, error) { 1315 var tmpDir string 1316 if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" { 1317 tmpDir = filepath.Join(rootDir, "tmp") 1318 newName := tmpDir + "-old" 1319 if err := os.Rename(tmpDir, newName); err == nil { 1320 go func() { 1321 if err := os.RemoveAll(newName); err != nil { 1322 logrus.Warnf("failed to delete old tmp directory: %s", newName) 1323 } 1324 }() 1325 } else if !os.IsNotExist(err) { 1326 logrus.Warnf("failed to rename %s for background deletion: %s. Deleting synchronously", tmpDir, err) 1327 if err := os.RemoveAll(tmpDir); err != nil { 1328 logrus.Warnf("failed to delete old tmp directory: %s", tmpDir) 1329 } 1330 } 1331 } 1332 // We don't remove the content of tmpdir if it's not the default, 1333 // it may hold things that do not belong to us. 1334 return tmpDir, idtools.MkdirAllAndChown(tmpDir, 0700, rootIdentity) 1335 } 1336 1337 func (daemon *Daemon) setGenericResources(conf *config.Config) error { 1338 genericResources, err := config.ParseGenericResources(conf.NodeGenericResources) 1339 if err != nil { 1340 return err 1341 } 1342 1343 daemon.genericResources = genericResources 1344 1345 return nil 1346 } 1347 1348 func setDefaultMtu(conf *config.Config) { 1349 // do nothing if the config does not have the default 0 value. 1350 if conf.Mtu != 0 { 1351 return 1352 } 1353 conf.Mtu = config.DefaultNetworkMtu 1354 } 1355 1356 // IsShuttingDown tells whether the daemon is shutting down or not 1357 func (daemon *Daemon) IsShuttingDown() bool { 1358 return daemon.shutdown 1359 } 1360 1361 // initDiscovery initializes the discovery watcher for this daemon. 1362 func (daemon *Daemon) initDiscovery(conf *config.Config) error { 1363 advertise, err := config.ParseClusterAdvertiseSettings(conf.ClusterStore, conf.ClusterAdvertise) 1364 if err != nil { 1365 if err == discovery.ErrDiscoveryDisabled { 1366 return nil 1367 } 1368 return err 1369 } 1370 1371 conf.ClusterAdvertise = advertise 1372 discoveryWatcher, err := discovery.Init(conf.ClusterStore, conf.ClusterAdvertise, conf.ClusterOpts) 1373 if err != nil { 1374 return fmt.Errorf("discovery initialization failed (%v)", err) 1375 } 1376 1377 daemon.discoveryWatcher = discoveryWatcher 1378 return nil 1379 } 1380 1381 func isBridgeNetworkDisabled(conf *config.Config) bool { 1382 return conf.BridgeConfig.Iface == config.DisableNetworkBridge 1383 } 1384 1385 func (daemon *Daemon) networkOptions(dconfig *config.Config, pg plugingetter.PluginGetter, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error) { 1386 options := []nwconfig.Option{} 1387 if dconfig == nil { 1388 return options, nil 1389 } 1390 1391 options = append(options, nwconfig.OptionExperimental(dconfig.Experimental)) 1392 options = append(options, nwconfig.OptionDataDir(dconfig.Root)) 1393 options = append(options, nwconfig.OptionExecRoot(dconfig.GetExecRoot())) 1394 1395 dd := runconfig.DefaultDaemonNetworkMode() 1396 dn := runconfig.DefaultDaemonNetworkMode().NetworkName() 1397 options = append(options, nwconfig.OptionDefaultDriver(string(dd))) 1398 options = append(options, nwconfig.OptionDefaultNetwork(dn)) 1399 1400 if strings.TrimSpace(dconfig.ClusterStore) != "" { 1401 kv := strings.Split(dconfig.ClusterStore, "://") 1402 if len(kv) != 2 { 1403 return nil, errors.New("kv store daemon config must be of the form KV-PROVIDER://KV-URL") 1404 } 1405 options = append(options, nwconfig.OptionKVProvider(kv[0])) 1406 options = append(options, nwconfig.OptionKVProviderURL(kv[1])) 1407 } 1408 if len(dconfig.ClusterOpts) > 0 { 1409 options = append(options, nwconfig.OptionKVOpts(dconfig.ClusterOpts)) 1410 } 1411 1412 if daemon.discoveryWatcher != nil { 1413 options = append(options, nwconfig.OptionDiscoveryWatcher(daemon.discoveryWatcher)) 1414 } 1415 1416 if dconfig.ClusterAdvertise != "" { 1417 options = append(options, nwconfig.OptionDiscoveryAddress(dconfig.ClusterAdvertise)) 1418 } 1419 1420 options = append(options, nwconfig.OptionLabels(dconfig.Labels)) 1421 options = append(options, driverOptions(dconfig)...) 1422 1423 if len(dconfig.NetworkConfig.DefaultAddressPools.Value()) > 0 { 1424 options = append(options, nwconfig.OptionDefaultAddressPoolConfig(dconfig.NetworkConfig.DefaultAddressPools.Value())) 1425 } 1426 1427 if daemon.configStore != nil && daemon.configStore.LiveRestoreEnabled && len(activeSandboxes) != 0 { 1428 options = append(options, nwconfig.OptionActiveSandboxes(activeSandboxes)) 1429 } 1430 1431 if pg != nil { 1432 options = append(options, nwconfig.OptionPluginGetter(pg)) 1433 } 1434 1435 options = append(options, nwconfig.OptionNetworkControlPlaneMTU(dconfig.NetworkControlPlaneMTU)) 1436 1437 return options, nil 1438 } 1439 1440 // GetCluster returns the cluster 1441 func (daemon *Daemon) GetCluster() Cluster { 1442 return daemon.cluster 1443 } 1444 1445 // SetCluster sets the cluster 1446 func (daemon *Daemon) SetCluster(cluster Cluster) { 1447 daemon.cluster = cluster 1448 } 1449 1450 func (daemon *Daemon) pluginShutdown() { 1451 manager := daemon.pluginManager 1452 // Check for a valid manager object. In error conditions, daemon init can fail 1453 // and shutdown called, before plugin manager is initialized. 1454 if manager != nil { 1455 manager.Shutdown() 1456 } 1457 } 1458 1459 // PluginManager returns current pluginManager associated with the daemon 1460 func (daemon *Daemon) PluginManager() *plugin.Manager { // set up before daemon to avoid this method 1461 return daemon.pluginManager 1462 } 1463 1464 // PluginGetter returns current pluginStore associated with the daemon 1465 func (daemon *Daemon) PluginGetter() *plugin.Store { 1466 return daemon.PluginStore 1467 } 1468 1469 // CreateDaemonRoot creates the root for the daemon 1470 func CreateDaemonRoot(config *config.Config) error { 1471 // get the canonical path to the Docker root directory 1472 var realRoot string 1473 if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) { 1474 realRoot = config.Root 1475 } else { 1476 realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root) 1477 if err != nil { 1478 return fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err) 1479 } 1480 } 1481 1482 idMapping, err := setupRemappedRoot(config) 1483 if err != nil { 1484 return err 1485 } 1486 return setupDaemonRoot(config, realRoot, idMapping.RootPair()) 1487 } 1488 1489 // checkpointAndSave grabs a container lock to safely call container.CheckpointTo 1490 func (daemon *Daemon) checkpointAndSave(container *container.Container) error { 1491 container.Lock() 1492 defer container.Unlock() 1493 if err := container.CheckpointTo(daemon.containersReplica); err != nil { 1494 return fmt.Errorf("Error saving container state: %v", err) 1495 } 1496 return nil 1497 } 1498 1499 // because the CLI sends a -1 when it wants to unset the swappiness value 1500 // we need to clear it on the server side 1501 func fixMemorySwappiness(resources *containertypes.Resources) { 1502 if resources.MemorySwappiness != nil && *resources.MemorySwappiness == -1 { 1503 resources.MemorySwappiness = nil 1504 } 1505 } 1506 1507 // GetAttachmentStore returns current attachment store associated with the daemon 1508 func (daemon *Daemon) GetAttachmentStore() *network.AttachmentStore { 1509 return &daemon.attachmentStore 1510 } 1511 1512 // IdentityMapping returns uid/gid mapping or a SID (in the case of Windows) for the builder 1513 func (daemon *Daemon) IdentityMapping() *idtools.IdentityMapping { 1514 return daemon.idMapping 1515 } 1516 1517 // ImageService returns the Daemon's ImageService 1518 func (daemon *Daemon) ImageService() *images.ImageService { 1519 return daemon.imageService 1520 } 1521 1522 // BuilderBackend returns the backend used by builder 1523 func (daemon *Daemon) BuilderBackend() builder.Backend { 1524 return struct { 1525 *Daemon 1526 *images.ImageService 1527 }{daemon, daemon.imageService} 1528 }