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