github.com/dinever/docker@v1.11.1/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
     7  
     8  import (
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"net"
    13  	"os"
    14  	"path"
    15  	"path/filepath"
    16  	"runtime"
    17  	"strings"
    18  	"sync"
    19  	"syscall"
    20  	"time"
    21  
    22  	"github.com/Sirupsen/logrus"
    23  	containerd "github.com/docker/containerd/api/grpc/types"
    24  	"github.com/docker/docker/api"
    25  	"github.com/docker/docker/builder"
    26  	"github.com/docker/docker/container"
    27  	"github.com/docker/docker/daemon/events"
    28  	"github.com/docker/docker/daemon/exec"
    29  	"github.com/docker/docker/errors"
    30  	"github.com/docker/engine-api/types"
    31  	containertypes "github.com/docker/engine-api/types/container"
    32  	eventtypes "github.com/docker/engine-api/types/events"
    33  	"github.com/docker/engine-api/types/filters"
    34  	networktypes "github.com/docker/engine-api/types/network"
    35  	registrytypes "github.com/docker/engine-api/types/registry"
    36  	"github.com/docker/engine-api/types/strslice"
    37  	// register graph drivers
    38  	_ "github.com/docker/docker/daemon/graphdriver/register"
    39  	"github.com/docker/docker/daemon/logger"
    40  	"github.com/docker/docker/daemon/network"
    41  	"github.com/docker/docker/distribution"
    42  	dmetadata "github.com/docker/docker/distribution/metadata"
    43  	"github.com/docker/docker/distribution/xfer"
    44  	"github.com/docker/docker/dockerversion"
    45  	"github.com/docker/docker/image"
    46  	"github.com/docker/docker/image/tarexport"
    47  	"github.com/docker/docker/layer"
    48  	"github.com/docker/docker/libcontainerd"
    49  	"github.com/docker/docker/migrate/v1"
    50  	"github.com/docker/docker/pkg/archive"
    51  	"github.com/docker/docker/pkg/fileutils"
    52  	"github.com/docker/docker/pkg/graphdb"
    53  	"github.com/docker/docker/pkg/idtools"
    54  	"github.com/docker/docker/pkg/namesgenerator"
    55  	"github.com/docker/docker/pkg/progress"
    56  	"github.com/docker/docker/pkg/registrar"
    57  	"github.com/docker/docker/pkg/signal"
    58  	"github.com/docker/docker/pkg/streamformatter"
    59  	"github.com/docker/docker/pkg/stringid"
    60  	"github.com/docker/docker/pkg/sysinfo"
    61  	"github.com/docker/docker/pkg/system"
    62  	"github.com/docker/docker/pkg/truncindex"
    63  	"github.com/docker/docker/reference"
    64  	"github.com/docker/docker/registry"
    65  	"github.com/docker/docker/runconfig"
    66  	"github.com/docker/docker/utils"
    67  	volumedrivers "github.com/docker/docker/volume/drivers"
    68  	"github.com/docker/docker/volume/local"
    69  	"github.com/docker/docker/volume/store"
    70  	"github.com/docker/go-connections/nat"
    71  	"github.com/docker/libnetwork"
    72  	nwconfig "github.com/docker/libnetwork/config"
    73  	"github.com/docker/libtrust"
    74  	"golang.org/x/net/context"
    75  )
    76  
    77  const (
    78  	// maxDownloadConcurrency is the maximum number of downloads that
    79  	// may take place at a time for each pull.
    80  	maxDownloadConcurrency = 3
    81  	// maxUploadConcurrency is the maximum number of uploads that
    82  	// may take place at a time for each push.
    83  	maxUploadConcurrency = 5
    84  )
    85  
    86  var (
    87  	validContainerNameChars   = utils.RestrictedNameChars
    88  	validContainerNamePattern = utils.RestrictedNamePattern
    89  
    90  	errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
    91  )
    92  
    93  // ErrImageDoesNotExist is error returned when no image can be found for a reference.
    94  type ErrImageDoesNotExist struct {
    95  	RefOrID string
    96  }
    97  
    98  func (e ErrImageDoesNotExist) Error() string {
    99  	return fmt.Sprintf("no such id: %s", e.RefOrID)
   100  }
   101  
   102  // Daemon holds information about the Docker daemon.
   103  type Daemon struct {
   104  	ID                        string
   105  	repository                string
   106  	containers                container.Store
   107  	execCommands              *exec.Store
   108  	referenceStore            reference.Store
   109  	downloadManager           *xfer.LayerDownloadManager
   110  	uploadManager             *xfer.LayerUploadManager
   111  	distributionMetadataStore dmetadata.Store
   112  	trustKey                  libtrust.PrivateKey
   113  	idIndex                   *truncindex.TruncIndex
   114  	configStore               *Config
   115  	statsCollector            *statsCollector
   116  	defaultLogConfig          containertypes.LogConfig
   117  	RegistryService           *registry.Service
   118  	EventsService             *events.Events
   119  	netController             libnetwork.NetworkController
   120  	volumes                   *store.VolumeStore
   121  	discoveryWatcher          discoveryReloader
   122  	root                      string
   123  	seccompEnabled            bool
   124  	shutdown                  bool
   125  	uidMaps                   []idtools.IDMap
   126  	gidMaps                   []idtools.IDMap
   127  	layerStore                layer.Store
   128  	imageStore                image.Store
   129  	nameIndex                 *registrar.Registrar
   130  	linkIndex                 *linkIndex
   131  	containerd                libcontainerd.Client
   132  	defaultIsolation          containertypes.Isolation // Default isolation mode on Windows
   133  }
   134  
   135  // GetContainer looks for a container using the provided information, which could be
   136  // one of the following inputs from the caller:
   137  //  - A full container ID, which will exact match a container in daemon's list
   138  //  - A container name, which will only exact match via the GetByName() function
   139  //  - A partial container ID prefix (e.g. short ID) of any length that is
   140  //    unique enough to only return a single container object
   141  //  If none of these searches succeed, an error is returned
   142  func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
   143  	if len(prefixOrName) == 0 {
   144  		return nil, errors.NewBadRequestError(fmt.Errorf("No container name or ID supplied"))
   145  	}
   146  
   147  	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
   148  		// prefix is an exact match to a full container ID
   149  		return containerByID, nil
   150  	}
   151  
   152  	// GetByName will match only an exact name provided; we ignore errors
   153  	if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
   154  		// prefix is an exact match to a full container Name
   155  		return containerByName, nil
   156  	}
   157  
   158  	containerID, indexError := daemon.idIndex.Get(prefixOrName)
   159  	if indexError != nil {
   160  		// When truncindex defines an error type, use that instead
   161  		if indexError == truncindex.ErrNotExist {
   162  			err := fmt.Errorf("No such container: %s", prefixOrName)
   163  			return nil, errors.NewRequestNotFoundError(err)
   164  		}
   165  		return nil, indexError
   166  	}
   167  	return daemon.containers.Get(containerID), nil
   168  }
   169  
   170  // Exists returns a true if a container of the specified ID or name exists,
   171  // false otherwise.
   172  func (daemon *Daemon) Exists(id string) bool {
   173  	c, _ := daemon.GetContainer(id)
   174  	return c != nil
   175  }
   176  
   177  // IsPaused returns a bool indicating if the specified container is paused.
   178  func (daemon *Daemon) IsPaused(id string) bool {
   179  	c, _ := daemon.GetContainer(id)
   180  	return c.State.IsPaused()
   181  }
   182  
   183  func (daemon *Daemon) containerRoot(id string) string {
   184  	return filepath.Join(daemon.repository, id)
   185  }
   186  
   187  // Load reads the contents of a container from disk
   188  // This is typically done at startup.
   189  func (daemon *Daemon) load(id string) (*container.Container, error) {
   190  	container := daemon.newBaseContainer(id)
   191  
   192  	if err := container.FromDisk(); err != nil {
   193  		return nil, err
   194  	}
   195  
   196  	if container.ID != id {
   197  		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
   198  	}
   199  
   200  	return container, nil
   201  }
   202  
   203  func (daemon *Daemon) registerName(container *container.Container) error {
   204  	if daemon.Exists(container.ID) {
   205  		return fmt.Errorf("Container is already loaded")
   206  	}
   207  	if err := validateID(container.ID); err != nil {
   208  		return err
   209  	}
   210  	if container.Name == "" {
   211  		name, err := daemon.generateNewName(container.ID)
   212  		if err != nil {
   213  			return err
   214  		}
   215  		container.Name = name
   216  
   217  		if err := container.ToDiskLocking(); err != nil {
   218  			logrus.Errorf("Error saving container name to disk: %v", err)
   219  		}
   220  	}
   221  	return daemon.nameIndex.Reserve(container.Name, container.ID)
   222  }
   223  
   224  // Register makes a container object usable by the daemon as <container.ID>
   225  func (daemon *Daemon) Register(c *container.Container) error {
   226  	// Attach to stdout and stderr
   227  	if c.Config.OpenStdin {
   228  		c.NewInputPipes()
   229  	} else {
   230  		c.NewNopInputPipe()
   231  	}
   232  
   233  	daemon.containers.Add(c.ID, c)
   234  	daemon.idIndex.Add(c.ID)
   235  
   236  	return nil
   237  }
   238  
   239  func (daemon *Daemon) restore() error {
   240  	var (
   241  		debug         = utils.IsDebugEnabled()
   242  		currentDriver = daemon.GraphDriverName()
   243  		containers    = make(map[string]*container.Container)
   244  	)
   245  
   246  	if !debug {
   247  		logrus.Info("Loading containers: start.")
   248  	}
   249  	dir, err := ioutil.ReadDir(daemon.repository)
   250  	if err != nil {
   251  		return err
   252  	}
   253  
   254  	for _, v := range dir {
   255  		id := v.Name()
   256  		container, err := daemon.load(id)
   257  		if !debug && logrus.GetLevel() == logrus.InfoLevel {
   258  			fmt.Print(".")
   259  		}
   260  		if err != nil {
   261  			logrus.Errorf("Failed to load container %v: %v", id, err)
   262  			continue
   263  		}
   264  
   265  		// Ignore the container if it does not support the current driver being used by the graph
   266  		if (container.Driver == "" && currentDriver == "aufs") || container.Driver == currentDriver {
   267  			rwlayer, err := daemon.layerStore.GetRWLayer(container.ID)
   268  			if err != nil {
   269  				logrus.Errorf("Failed to load container mount %v: %v", id, err)
   270  				continue
   271  			}
   272  			container.RWLayer = rwlayer
   273  			logrus.Debugf("Loaded container %v", container.ID)
   274  
   275  			containers[container.ID] = container
   276  		} else {
   277  			logrus.Debugf("Cannot load container %s because it was created with another graph driver.", container.ID)
   278  		}
   279  	}
   280  
   281  	var migrateLegacyLinks bool
   282  	restartContainers := make(map[*container.Container]chan struct{})
   283  	for _, c := range containers {
   284  		if err := daemon.registerName(c); err != nil {
   285  			logrus.Errorf("Failed to register container %s: %s", c.ID, err)
   286  			continue
   287  		}
   288  		if err := daemon.Register(c); err != nil {
   289  			logrus.Errorf("Failed to register container %s: %s", c.ID, err)
   290  			continue
   291  		}
   292  	}
   293  	var wg sync.WaitGroup
   294  	var mapLock sync.Mutex
   295  	for _, c := range containers {
   296  		wg.Add(1)
   297  		go func(c *container.Container) {
   298  			defer wg.Done()
   299  			if c.IsRunning() || c.IsPaused() {
   300  				// Fix activityCount such that graph mounts can be unmounted later
   301  				if err := daemon.layerStore.ReinitRWLayer(c.RWLayer); err != nil {
   302  					logrus.Errorf("Failed to ReinitRWLayer for %s due to %s", c.ID, err)
   303  					return
   304  				}
   305  				if err := daemon.containerd.Restore(c.ID, libcontainerd.WithRestartManager(c.RestartManager(true))); err != nil {
   306  					logrus.Errorf("Failed to restore with containerd: %q", err)
   307  					return
   308  				}
   309  			}
   310  			// fixme: only if not running
   311  			// get list of containers we need to restart
   312  			if daemon.configStore.AutoRestart && !c.IsRunning() && !c.IsPaused() && c.ShouldRestartOnBoot() {
   313  				mapLock.Lock()
   314  				restartContainers[c] = make(chan struct{})
   315  				mapLock.Unlock()
   316  			}
   317  
   318  			// if c.hostConfig.Links is nil (not just empty), then it is using the old sqlite links and needs to be migrated
   319  			if c.HostConfig != nil && c.HostConfig.Links == nil {
   320  				migrateLegacyLinks = true
   321  			}
   322  		}(c)
   323  	}
   324  	wg.Wait()
   325  
   326  	// migrate any legacy links from sqlite
   327  	linkdbFile := filepath.Join(daemon.root, "linkgraph.db")
   328  	var legacyLinkDB *graphdb.Database
   329  	if migrateLegacyLinks {
   330  		legacyLinkDB, err = graphdb.NewSqliteConn(linkdbFile)
   331  		if err != nil {
   332  			return fmt.Errorf("error connecting to legacy link graph DB %s, container links may be lost: %v", linkdbFile, err)
   333  		}
   334  		defer legacyLinkDB.Close()
   335  	}
   336  
   337  	// Now that all the containers are registered, register the links
   338  	for _, c := range containers {
   339  		if migrateLegacyLinks {
   340  			if err := daemon.migrateLegacySqliteLinks(legacyLinkDB, c); err != nil {
   341  				return err
   342  			}
   343  		}
   344  		if err := daemon.registerLinks(c, c.HostConfig); err != nil {
   345  			logrus.Errorf("failed to register link for container %s: %v", c.ID, err)
   346  		}
   347  	}
   348  
   349  	group := sync.WaitGroup{}
   350  	for c, notifier := range restartContainers {
   351  		group.Add(1)
   352  
   353  		go func(c *container.Container, chNotify chan struct{}) {
   354  			defer group.Done()
   355  
   356  			logrus.Debugf("Starting container %s", c.ID)
   357  
   358  			// ignore errors here as this is a best effort to wait for children to be
   359  			//   running before we try to start the container
   360  			children := daemon.children(c)
   361  			timeout := time.After(5 * time.Second)
   362  			for _, child := range children {
   363  				if notifier, exists := restartContainers[child]; exists {
   364  					select {
   365  					case <-notifier:
   366  					case <-timeout:
   367  					}
   368  				}
   369  			}
   370  			if err := daemon.containerStart(c); err != nil {
   371  				logrus.Errorf("Failed to start container %s: %s", c.ID, err)
   372  			}
   373  			close(chNotify)
   374  		}(c, notifier)
   375  
   376  	}
   377  	group.Wait()
   378  
   379  	// any containers that were started above would already have had this done,
   380  	// however we need to now prepare the mountpoints for the rest of the containers as well.
   381  	// This shouldn't cause any issue running on the containers that already had this run.
   382  	// This must be run after any containers with a restart policy so that containerized plugins
   383  	// can have a chance to be running before we try to initialize them.
   384  	for _, c := range containers {
   385  		// if the container has restart policy, do not
   386  		// prepare the mountpoints since it has been done on restarting.
   387  		// This is to speed up the daemon start when a restart container
   388  		// has a volume and the volume dirver is not available.
   389  		if _, ok := restartContainers[c]; ok {
   390  			continue
   391  		}
   392  		group.Add(1)
   393  		go func(c *container.Container) {
   394  			defer group.Done()
   395  			if err := daemon.prepareMountPoints(c); err != nil {
   396  				logrus.Error(err)
   397  			}
   398  		}(c)
   399  	}
   400  
   401  	group.Wait()
   402  
   403  	if !debug {
   404  		if logrus.GetLevel() == logrus.InfoLevel {
   405  			fmt.Println()
   406  		}
   407  		logrus.Info("Loading containers: done.")
   408  	}
   409  
   410  	return nil
   411  }
   412  
   413  func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *image.Image) error {
   414  	if img != nil && img.Config != nil {
   415  		if err := merge(config, img.Config); err != nil {
   416  			return err
   417  		}
   418  	}
   419  	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
   420  		return fmt.Errorf("No command specified")
   421  	}
   422  	return nil
   423  }
   424  
   425  func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
   426  	var (
   427  		err error
   428  		id  = stringid.GenerateNonCryptoID()
   429  	)
   430  
   431  	if name == "" {
   432  		if name, err = daemon.generateNewName(id); err != nil {
   433  			return "", "", err
   434  		}
   435  		return id, name, nil
   436  	}
   437  
   438  	if name, err = daemon.reserveName(id, name); err != nil {
   439  		return "", "", err
   440  	}
   441  
   442  	return id, name, nil
   443  }
   444  
   445  func (daemon *Daemon) reserveName(id, name string) (string, error) {
   446  	if !validContainerNamePattern.MatchString(name) {
   447  		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
   448  	}
   449  	if name[0] != '/' {
   450  		name = "/" + name
   451  	}
   452  
   453  	if err := daemon.nameIndex.Reserve(name, id); err != nil {
   454  		if err == registrar.ErrNameReserved {
   455  			id, err := daemon.nameIndex.Get(name)
   456  			if err != nil {
   457  				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
   458  				return "", err
   459  			}
   460  			return "", fmt.Errorf("Conflict. The name %q is already in use by container %s. You have to remove (or rename) that container to be able to reuse that name.", name, id)
   461  		}
   462  		return "", fmt.Errorf("error reserving name: %s, error: %v", name, err)
   463  	}
   464  	return name, nil
   465  }
   466  
   467  func (daemon *Daemon) releaseName(name string) {
   468  	daemon.nameIndex.Release(name)
   469  }
   470  
   471  func (daemon *Daemon) generateNewName(id string) (string, error) {
   472  	var name string
   473  	for i := 0; i < 6; i++ {
   474  		name = namesgenerator.GetRandomName(i)
   475  		if name[0] != '/' {
   476  			name = "/" + name
   477  		}
   478  
   479  		if err := daemon.nameIndex.Reserve(name, id); err != nil {
   480  			if err == registrar.ErrNameReserved {
   481  				continue
   482  			}
   483  			return "", err
   484  		}
   485  		return name, nil
   486  	}
   487  
   488  	name = "/" + stringid.TruncateID(id)
   489  	if err := daemon.nameIndex.Reserve(name, id); err != nil {
   490  		return "", err
   491  	}
   492  	return name, nil
   493  }
   494  
   495  func (daemon *Daemon) generateHostname(id string, config *containertypes.Config) {
   496  	// Generate default hostname
   497  	if config.Hostname == "" {
   498  		config.Hostname = id[:12]
   499  	}
   500  }
   501  
   502  func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint strslice.StrSlice, configCmd strslice.StrSlice) (string, []string) {
   503  	if len(configEntrypoint) != 0 {
   504  		return configEntrypoint[0], append(configEntrypoint[1:], configCmd...)
   505  	}
   506  	return configCmd[0], configCmd[1:]
   507  }
   508  
   509  func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) {
   510  	var (
   511  		id             string
   512  		err            error
   513  		noExplicitName = name == ""
   514  	)
   515  	id, name, err = daemon.generateIDAndName(name)
   516  	if err != nil {
   517  		return nil, err
   518  	}
   519  
   520  	daemon.generateHostname(id, config)
   521  	entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
   522  
   523  	base := daemon.newBaseContainer(id)
   524  	base.Created = time.Now().UTC()
   525  	base.Path = entrypoint
   526  	base.Args = args //FIXME: de-duplicate from config
   527  	base.Config = config
   528  	base.HostConfig = &containertypes.HostConfig{}
   529  	base.ImageID = imgID
   530  	base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName}
   531  	base.Name = name
   532  	base.Driver = daemon.GraphDriverName()
   533  
   534  	return base, err
   535  }
   536  
   537  // GetByName returns a container given a name.
   538  func (daemon *Daemon) GetByName(name string) (*container.Container, error) {
   539  	if len(name) == 0 {
   540  		return nil, fmt.Errorf("No container name supplied")
   541  	}
   542  	fullName := name
   543  	if name[0] != '/' {
   544  		fullName = "/" + name
   545  	}
   546  	id, err := daemon.nameIndex.Get(fullName)
   547  	if err != nil {
   548  		return nil, fmt.Errorf("Could not find entity for %s", name)
   549  	}
   550  	e := daemon.containers.Get(id)
   551  	if e == nil {
   552  		return nil, fmt.Errorf("Could not find container for entity id %s", id)
   553  	}
   554  	return e, nil
   555  }
   556  
   557  // SubscribeToEvents returns the currently record of events, a channel to stream new events from, and a function to cancel the stream of events.
   558  func (daemon *Daemon) SubscribeToEvents(since, sinceNano int64, filter filters.Args) ([]eventtypes.Message, chan interface{}) {
   559  	ef := events.NewFilter(filter)
   560  	return daemon.EventsService.SubscribeTopic(since, sinceNano, ef)
   561  }
   562  
   563  // UnsubscribeFromEvents stops the event subscription for a client by closing the
   564  // channel where the daemon sends events to.
   565  func (daemon *Daemon) UnsubscribeFromEvents(listener chan interface{}) {
   566  	daemon.EventsService.Evict(listener)
   567  }
   568  
   569  // GetLabels for a container or image id
   570  func (daemon *Daemon) GetLabels(id string) map[string]string {
   571  	// TODO: TestCase
   572  	container := daemon.containers.Get(id)
   573  	if container != nil {
   574  		return container.Config.Labels
   575  	}
   576  
   577  	img, err := daemon.GetImage(id)
   578  	if err == nil {
   579  		return img.ContainerConfig.Labels
   580  	}
   581  	return nil
   582  }
   583  
   584  func (daemon *Daemon) children(c *container.Container) map[string]*container.Container {
   585  	return daemon.linkIndex.children(c)
   586  }
   587  
   588  // parents returns the names of the parent containers of the container
   589  // with the given name.
   590  func (daemon *Daemon) parents(c *container.Container) map[string]*container.Container {
   591  	return daemon.linkIndex.parents(c)
   592  }
   593  
   594  func (daemon *Daemon) registerLink(parent, child *container.Container, alias string) error {
   595  	fullName := path.Join(parent.Name, alias)
   596  	if err := daemon.nameIndex.Reserve(fullName, child.ID); err != nil {
   597  		if err == registrar.ErrNameReserved {
   598  			logrus.Warnf("error registering link for %s, to %s, as alias %s, ignoring: %v", parent.ID, child.ID, alias, err)
   599  			return nil
   600  		}
   601  		return err
   602  	}
   603  	daemon.linkIndex.link(parent, child, fullName)
   604  	return nil
   605  }
   606  
   607  // NewDaemon sets up everything for the daemon to be able to service
   608  // requests from the webserver.
   609  func NewDaemon(config *Config, registryService *registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) {
   610  	setDefaultMtu(config)
   611  
   612  	// Ensure we have compatible and valid configuration options
   613  	if err := verifyDaemonSettings(config); err != nil {
   614  		return nil, err
   615  	}
   616  
   617  	// Do we have a disabled network?
   618  	config.DisableBridge = isBridgeNetworkDisabled(config)
   619  
   620  	// Verify the platform is supported as a daemon
   621  	if !platformSupported {
   622  		return nil, errSystemNotSupported
   623  	}
   624  
   625  	// Validate platform-specific requirements
   626  	if err := checkSystem(); err != nil {
   627  		return nil, err
   628  	}
   629  
   630  	// set up SIGUSR1 handler on Unix-like systems, or a Win32 global event
   631  	// on Windows to dump Go routine stacks
   632  	setupDumpStackTrap()
   633  
   634  	uidMaps, gidMaps, err := setupRemappedRoot(config)
   635  	if err != nil {
   636  		return nil, err
   637  	}
   638  	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
   639  	if err != nil {
   640  		return nil, err
   641  	}
   642  
   643  	// get the canonical path to the Docker root directory
   644  	var realRoot string
   645  	if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
   646  		realRoot = config.Root
   647  	} else {
   648  		realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root)
   649  		if err != nil {
   650  			return nil, fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)
   651  		}
   652  	}
   653  
   654  	if err = setupDaemonRoot(config, realRoot, rootUID, rootGID); err != nil {
   655  		return nil, err
   656  	}
   657  
   658  	// set up the tmpDir to use a canonical path
   659  	tmp, err := tempDir(config.Root, rootUID, rootGID)
   660  	if err != nil {
   661  		return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err)
   662  	}
   663  	realTmp, err := fileutils.ReadSymlinkedDirectory(tmp)
   664  	if err != nil {
   665  		return nil, fmt.Errorf("Unable to get the full path to the TempDir (%s): %s", tmp, err)
   666  	}
   667  	os.Setenv("TMPDIR", realTmp)
   668  
   669  	d := &Daemon{configStore: config}
   670  	// Ensure the daemon is properly shutdown if there is a failure during
   671  	// initialization
   672  	defer func() {
   673  		if err != nil {
   674  			if err := d.Shutdown(); err != nil {
   675  				logrus.Error(err)
   676  			}
   677  		}
   678  	}()
   679  
   680  	// Set the default isolation mode (only applicable on Windows)
   681  	if err := d.setDefaultIsolation(); err != nil {
   682  		return nil, fmt.Errorf("error setting default isolation mode: %v", err)
   683  	}
   684  
   685  	// Verify logging driver type
   686  	if config.LogConfig.Type != "none" {
   687  		if _, err := logger.GetLogDriver(config.LogConfig.Type); err != nil {
   688  			return nil, fmt.Errorf("error finding the logging driver: %v", err)
   689  		}
   690  	}
   691  	logrus.Debugf("Using default logging driver %s", config.LogConfig.Type)
   692  
   693  	if err := configureMaxThreads(config); err != nil {
   694  		logrus.Warnf("Failed to configure golang's threads limit: %v", err)
   695  	}
   696  
   697  	installDefaultAppArmorProfile()
   698  	daemonRepo := filepath.Join(config.Root, "containers")
   699  	if err := idtools.MkdirAllAs(daemonRepo, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
   700  		return nil, err
   701  	}
   702  
   703  	driverName := os.Getenv("DOCKER_DRIVER")
   704  	if driverName == "" {
   705  		driverName = config.GraphDriver
   706  	}
   707  	d.layerStore, err = layer.NewStoreFromOptions(layer.StoreOptions{
   708  		StorePath:                 config.Root,
   709  		MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
   710  		GraphDriver:               driverName,
   711  		GraphDriverOptions:        config.GraphOptions,
   712  		UIDMaps:                   uidMaps,
   713  		GIDMaps:                   gidMaps,
   714  	})
   715  	if err != nil {
   716  		return nil, err
   717  	}
   718  
   719  	graphDriver := d.layerStore.DriverName()
   720  	imageRoot := filepath.Join(config.Root, "image", graphDriver)
   721  
   722  	// Configure and validate the kernels security support
   723  	if err := configureKernelSecuritySupport(config, graphDriver); err != nil {
   724  		return nil, err
   725  	}
   726  
   727  	d.downloadManager = xfer.NewLayerDownloadManager(d.layerStore, maxDownloadConcurrency)
   728  	d.uploadManager = xfer.NewLayerUploadManager(maxUploadConcurrency)
   729  
   730  	ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))
   731  	if err != nil {
   732  		return nil, err
   733  	}
   734  
   735  	d.imageStore, err = image.NewImageStore(ifs, d.layerStore)
   736  	if err != nil {
   737  		return nil, err
   738  	}
   739  
   740  	// Configure the volumes driver
   741  	volStore, err := configureVolumes(config, rootUID, rootGID)
   742  	if err != nil {
   743  		return nil, err
   744  	}
   745  
   746  	trustKey, err := api.LoadOrCreateTrustKey(config.TrustKeyPath)
   747  	if err != nil {
   748  		return nil, err
   749  	}
   750  
   751  	trustDir := filepath.Join(config.Root, "trust")
   752  
   753  	if err := system.MkdirAll(trustDir, 0700); err != nil {
   754  		return nil, err
   755  	}
   756  
   757  	distributionMetadataStore, err := dmetadata.NewFSMetadataStore(filepath.Join(imageRoot, "distribution"))
   758  	if err != nil {
   759  		return nil, err
   760  	}
   761  
   762  	eventsService := events.New()
   763  
   764  	referenceStore, err := reference.NewReferenceStore(filepath.Join(imageRoot, "repositories.json"))
   765  	if err != nil {
   766  		return nil, fmt.Errorf("Couldn't create Tag store repositories: %s", err)
   767  	}
   768  
   769  	if err := restoreCustomImage(d.imageStore, d.layerStore, referenceStore); err != nil {
   770  		return nil, fmt.Errorf("Couldn't restore custom images: %s", err)
   771  	}
   772  
   773  	migrationStart := time.Now()
   774  	if err := v1.Migrate(config.Root, graphDriver, d.layerStore, d.imageStore, referenceStore, distributionMetadataStore); err != nil {
   775  		logrus.Errorf("Graph migration failed: %q. Your old graph data was found to be too inconsistent for upgrading to content-addressable storage. Some of the old data was probably not upgraded. We recommend starting over with a clean storage directory if possible.", err)
   776  	}
   777  	logrus.Infof("Graph migration to content-addressability took %.2f seconds", time.Since(migrationStart).Seconds())
   778  
   779  	// Discovery is only enabled when the daemon is launched with an address to advertise.  When
   780  	// initialized, the daemon is registered and we can store the discovery backend as its read-only
   781  	if err := d.initDiscovery(config); err != nil {
   782  		return nil, err
   783  	}
   784  
   785  	d.netController, err = d.initNetworkController(config)
   786  	if err != nil {
   787  		return nil, fmt.Errorf("Error initializing network controller: %v", err)
   788  	}
   789  
   790  	sysInfo := sysinfo.New(false)
   791  	// Check if Devices cgroup is mounted, it is hard requirement for container security,
   792  	// on Linux/FreeBSD.
   793  	if runtime.GOOS != "windows" && !sysInfo.CgroupDevicesEnabled {
   794  		return nil, fmt.Errorf("Devices cgroup isn't mounted")
   795  	}
   796  
   797  	d.ID = trustKey.PublicKey().KeyID()
   798  	d.repository = daemonRepo
   799  	d.containers = container.NewMemoryStore()
   800  	d.execCommands = exec.NewStore()
   801  	d.referenceStore = referenceStore
   802  	d.distributionMetadataStore = distributionMetadataStore
   803  	d.trustKey = trustKey
   804  	d.idIndex = truncindex.NewTruncIndex([]string{})
   805  	d.statsCollector = d.newStatsCollector(1 * time.Second)
   806  	d.defaultLogConfig = containertypes.LogConfig{
   807  		Type:   config.LogConfig.Type,
   808  		Config: config.LogConfig.Config,
   809  	}
   810  	d.RegistryService = registryService
   811  	d.EventsService = eventsService
   812  	d.volumes = volStore
   813  	d.root = config.Root
   814  	d.uidMaps = uidMaps
   815  	d.gidMaps = gidMaps
   816  	d.seccompEnabled = sysInfo.Seccomp
   817  
   818  	d.nameIndex = registrar.NewRegistrar()
   819  	d.linkIndex = newLinkIndex()
   820  
   821  	go d.execCommandGC()
   822  
   823  	d.containerd, err = containerdRemote.Client(d)
   824  	if err != nil {
   825  		return nil, err
   826  	}
   827  
   828  	if err := d.restore(); err != nil {
   829  		return nil, err
   830  	}
   831  
   832  	return d, nil
   833  }
   834  
   835  func (daemon *Daemon) shutdownContainer(c *container.Container) error {
   836  	// TODO(windows): Handle docker restart with paused containers
   837  	if c.IsPaused() {
   838  		// To terminate a process in freezer cgroup, we should send
   839  		// SIGTERM to this process then unfreeze it, and the process will
   840  		// force to terminate immediately.
   841  		logrus.Debugf("Found container %s is paused, sending SIGTERM before unpause it", c.ID)
   842  		sig, ok := signal.SignalMap["TERM"]
   843  		if !ok {
   844  			return fmt.Errorf("System doesn not support SIGTERM")
   845  		}
   846  		if err := daemon.kill(c, int(sig)); err != nil {
   847  			return fmt.Errorf("sending SIGTERM to container %s with error: %v", c.ID, err)
   848  		}
   849  		if err := daemon.containerUnpause(c); err != nil {
   850  			return fmt.Errorf("Failed to unpause container %s with error: %v", c.ID, err)
   851  		}
   852  		if _, err := c.WaitStop(10 * time.Second); err != nil {
   853  			logrus.Debugf("container %s failed to exit in 10 second of SIGTERM, sending SIGKILL to force", c.ID)
   854  			sig, ok := signal.SignalMap["KILL"]
   855  			if !ok {
   856  				return fmt.Errorf("System does not support SIGKILL")
   857  			}
   858  			if err := daemon.kill(c, int(sig)); err != nil {
   859  				logrus.Errorf("Failed to SIGKILL container %s", c.ID)
   860  			}
   861  			c.WaitStop(-1 * time.Second)
   862  			return err
   863  		}
   864  	}
   865  	// If container failed to exit in 10 seconds of SIGTERM, then using the force
   866  	if err := daemon.containerStop(c, 10); err != nil {
   867  		return fmt.Errorf("Stop container %s with error: %v", c.ID, err)
   868  	}
   869  
   870  	c.WaitStop(-1 * time.Second)
   871  	return nil
   872  }
   873  
   874  // Shutdown stops the daemon.
   875  func (daemon *Daemon) Shutdown() error {
   876  	daemon.shutdown = true
   877  	if daemon.containers != nil {
   878  		logrus.Debug("starting clean shutdown of all containers...")
   879  		daemon.containers.ApplyAll(func(c *container.Container) {
   880  			if !c.IsRunning() {
   881  				return
   882  			}
   883  			logrus.Debugf("stopping %s", c.ID)
   884  			if err := daemon.shutdownContainer(c); err != nil {
   885  				logrus.Errorf("Stop container error: %v", err)
   886  				return
   887  			}
   888  			if mountid, err := daemon.layerStore.GetMountID(c.ID); err == nil {
   889  				daemon.cleanupMountsByID(mountid)
   890  			}
   891  			logrus.Debugf("container stopped %s", c.ID)
   892  		})
   893  	}
   894  
   895  	// trigger libnetwork Stop only if it's initialized
   896  	if daemon.netController != nil {
   897  		daemon.netController.Stop()
   898  	}
   899  
   900  	if daemon.layerStore != nil {
   901  		if err := daemon.layerStore.Cleanup(); err != nil {
   902  			logrus.Errorf("Error during layer Store.Cleanup(): %v", err)
   903  		}
   904  	}
   905  
   906  	if err := daemon.cleanupMounts(); err != nil {
   907  		return err
   908  	}
   909  
   910  	return nil
   911  }
   912  
   913  // Mount sets container.BaseFS
   914  // (is it not set coming in? why is it unset?)
   915  func (daemon *Daemon) Mount(container *container.Container) error {
   916  	dir, err := container.RWLayer.Mount(container.GetMountLabel())
   917  	if err != nil {
   918  		return err
   919  	}
   920  	logrus.Debugf("container mounted via layerStore: %v", dir)
   921  
   922  	if container.BaseFS != dir {
   923  		// The mount path reported by the graph driver should always be trusted on Windows, since the
   924  		// volume path for a given mounted layer may change over time.  This should only be an error
   925  		// on non-Windows operating systems.
   926  		if container.BaseFS != "" && runtime.GOOS != "windows" {
   927  			daemon.Unmount(container)
   928  			return fmt.Errorf("Error: driver %s is returning inconsistent paths for container %s ('%s' then '%s')",
   929  				daemon.GraphDriverName(), container.ID, container.BaseFS, dir)
   930  		}
   931  	}
   932  	container.BaseFS = dir // TODO: combine these fields
   933  	return nil
   934  }
   935  
   936  // Unmount unsets the container base filesystem
   937  func (daemon *Daemon) Unmount(container *container.Container) error {
   938  	if err := container.RWLayer.Unmount(); err != nil {
   939  		logrus.Errorf("Error unmounting container %s: %s", container.ID, err)
   940  		return err
   941  	}
   942  	return nil
   943  }
   944  
   945  func (daemon *Daemon) kill(c *container.Container, sig int) error {
   946  	return daemon.containerd.Signal(c.ID, sig)
   947  }
   948  
   949  func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
   950  	return daemon.statsCollector.collect(c)
   951  }
   952  
   953  func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
   954  	daemon.statsCollector.unsubscribe(c, ch)
   955  }
   956  
   957  func (daemon *Daemon) changes(container *container.Container) ([]archive.Change, error) {
   958  	return container.RWLayer.Changes()
   959  }
   960  
   961  // TagImage creates the tag specified by newTag, pointing to the image named
   962  // imageName (alternatively, imageName can also be an image ID).
   963  func (daemon *Daemon) TagImage(newTag reference.Named, imageName string) error {
   964  	imageID, err := daemon.GetImageID(imageName)
   965  	if err != nil {
   966  		return err
   967  	}
   968  	if err := daemon.referenceStore.AddTag(newTag, imageID, true); err != nil {
   969  		return err
   970  	}
   971  
   972  	daemon.LogImageEvent(imageID.String(), newTag.String(), "tag")
   973  	return nil
   974  }
   975  
   976  func writeDistributionProgress(cancelFunc func(), outStream io.Writer, progressChan <-chan progress.Progress) {
   977  	progressOutput := streamformatter.NewJSONStreamFormatter().NewProgressOutput(outStream, false)
   978  	operationCancelled := false
   979  
   980  	for prog := range progressChan {
   981  		if err := progressOutput.WriteProgress(prog); err != nil && !operationCancelled {
   982  			// don't log broken pipe errors as this is the normal case when a client aborts
   983  			if isBrokenPipe(err) {
   984  				logrus.Info("Pull session cancelled")
   985  			} else {
   986  				logrus.Errorf("error writing progress to client: %v", err)
   987  			}
   988  			cancelFunc()
   989  			operationCancelled = true
   990  			// Don't return, because we need to continue draining
   991  			// progressChan until it's closed to avoid a deadlock.
   992  		}
   993  	}
   994  }
   995  
   996  func isBrokenPipe(e error) bool {
   997  	if netErr, ok := e.(*net.OpError); ok {
   998  		e = netErr.Err
   999  		if sysErr, ok := netErr.Err.(*os.SyscallError); ok {
  1000  			e = sysErr.Err
  1001  		}
  1002  	}
  1003  	return e == syscall.EPIPE
  1004  }
  1005  
  1006  // PullImage initiates a pull operation. image is the repository name to pull, and
  1007  // tag may be either empty, or indicate a specific tag to pull.
  1008  func (daemon *Daemon) PullImage(ctx context.Context, ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
  1009  	// Include a buffer so that slow client connections don't affect
  1010  	// transfer performance.
  1011  	progressChan := make(chan progress.Progress, 100)
  1012  
  1013  	writesDone := make(chan struct{})
  1014  
  1015  	ctx, cancelFunc := context.WithCancel(ctx)
  1016  
  1017  	go func() {
  1018  		writeDistributionProgress(cancelFunc, outStream, progressChan)
  1019  		close(writesDone)
  1020  	}()
  1021  
  1022  	imagePullConfig := &distribution.ImagePullConfig{
  1023  		MetaHeaders:      metaHeaders,
  1024  		AuthConfig:       authConfig,
  1025  		ProgressOutput:   progress.ChanOutput(progressChan),
  1026  		RegistryService:  daemon.RegistryService,
  1027  		ImageEventLogger: daemon.LogImageEvent,
  1028  		MetadataStore:    daemon.distributionMetadataStore,
  1029  		ImageStore:       daemon.imageStore,
  1030  		ReferenceStore:   daemon.referenceStore,
  1031  		DownloadManager:  daemon.downloadManager,
  1032  	}
  1033  
  1034  	err := distribution.Pull(ctx, ref, imagePullConfig)
  1035  	close(progressChan)
  1036  	<-writesDone
  1037  	return err
  1038  }
  1039  
  1040  // PullOnBuild tells Docker to pull image referenced by `name`.
  1041  func (daemon *Daemon) PullOnBuild(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer) (builder.Image, error) {
  1042  	ref, err := reference.ParseNamed(name)
  1043  	if err != nil {
  1044  		return nil, err
  1045  	}
  1046  	ref = reference.WithDefaultTag(ref)
  1047  
  1048  	pullRegistryAuth := &types.AuthConfig{}
  1049  	if len(authConfigs) > 0 {
  1050  		// The request came with a full auth config file, we prefer to use that
  1051  		repoInfo, err := daemon.RegistryService.ResolveRepository(ref)
  1052  		if err != nil {
  1053  			return nil, err
  1054  		}
  1055  
  1056  		resolvedConfig := registry.ResolveAuthConfig(
  1057  			authConfigs,
  1058  			repoInfo.Index,
  1059  		)
  1060  		pullRegistryAuth = &resolvedConfig
  1061  	}
  1062  
  1063  	if err := daemon.PullImage(ctx, ref, nil, pullRegistryAuth, output); err != nil {
  1064  		return nil, err
  1065  	}
  1066  	return daemon.GetImage(name)
  1067  }
  1068  
  1069  // ExportImage exports a list of images to the given output stream. The
  1070  // exported images are archived into a tar when written to the output
  1071  // stream. All images with the given tag and all versions containing
  1072  // the same tag are exported. names is the set of tags to export, and
  1073  // outStream is the writer which the images are written to.
  1074  func (daemon *Daemon) ExportImage(names []string, outStream io.Writer) error {
  1075  	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore)
  1076  	return imageExporter.Save(names, outStream)
  1077  }
  1078  
  1079  // PushImage initiates a push operation on the repository named localName.
  1080  func (daemon *Daemon) PushImage(ctx context.Context, ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error {
  1081  	// Include a buffer so that slow client connections don't affect
  1082  	// transfer performance.
  1083  	progressChan := make(chan progress.Progress, 100)
  1084  
  1085  	writesDone := make(chan struct{})
  1086  
  1087  	ctx, cancelFunc := context.WithCancel(ctx)
  1088  
  1089  	go func() {
  1090  		writeDistributionProgress(cancelFunc, outStream, progressChan)
  1091  		close(writesDone)
  1092  	}()
  1093  
  1094  	imagePushConfig := &distribution.ImagePushConfig{
  1095  		MetaHeaders:      metaHeaders,
  1096  		AuthConfig:       authConfig,
  1097  		ProgressOutput:   progress.ChanOutput(progressChan),
  1098  		RegistryService:  daemon.RegistryService,
  1099  		ImageEventLogger: daemon.LogImageEvent,
  1100  		MetadataStore:    daemon.distributionMetadataStore,
  1101  		LayerStore:       daemon.layerStore,
  1102  		ImageStore:       daemon.imageStore,
  1103  		ReferenceStore:   daemon.referenceStore,
  1104  		TrustKey:         daemon.trustKey,
  1105  		UploadManager:    daemon.uploadManager,
  1106  	}
  1107  
  1108  	err := distribution.Push(ctx, ref, imagePushConfig)
  1109  	close(progressChan)
  1110  	<-writesDone
  1111  	return err
  1112  }
  1113  
  1114  // LookupImage looks up an image by name and returns it as an ImageInspect
  1115  // structure.
  1116  func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) {
  1117  	img, err := daemon.GetImage(name)
  1118  	if err != nil {
  1119  		return nil, fmt.Errorf("No such image: %s", name)
  1120  	}
  1121  
  1122  	refs := daemon.referenceStore.References(img.ID())
  1123  	repoTags := []string{}
  1124  	repoDigests := []string{}
  1125  	for _, ref := range refs {
  1126  		switch ref.(type) {
  1127  		case reference.NamedTagged:
  1128  			repoTags = append(repoTags, ref.String())
  1129  		case reference.Canonical:
  1130  			repoDigests = append(repoDigests, ref.String())
  1131  		}
  1132  	}
  1133  
  1134  	var size int64
  1135  	var layerMetadata map[string]string
  1136  	layerID := img.RootFS.ChainID()
  1137  	if layerID != "" {
  1138  		l, err := daemon.layerStore.Get(layerID)
  1139  		if err != nil {
  1140  			return nil, err
  1141  		}
  1142  		defer layer.ReleaseAndLog(daemon.layerStore, l)
  1143  		size, err = l.Size()
  1144  		if err != nil {
  1145  			return nil, err
  1146  		}
  1147  
  1148  		layerMetadata, err = l.Metadata()
  1149  		if err != nil {
  1150  			return nil, err
  1151  		}
  1152  	}
  1153  
  1154  	comment := img.Comment
  1155  	if len(comment) == 0 && len(img.History) > 0 {
  1156  		comment = img.History[len(img.History)-1].Comment
  1157  	}
  1158  
  1159  	imageInspect := &types.ImageInspect{
  1160  		ID:              img.ID().String(),
  1161  		RepoTags:        repoTags,
  1162  		RepoDigests:     repoDigests,
  1163  		Parent:          img.Parent.String(),
  1164  		Comment:         comment,
  1165  		Created:         img.Created.Format(time.RFC3339Nano),
  1166  		Container:       img.Container,
  1167  		ContainerConfig: &img.ContainerConfig,
  1168  		DockerVersion:   img.DockerVersion,
  1169  		Author:          img.Author,
  1170  		Config:          img.Config,
  1171  		Architecture:    img.Architecture,
  1172  		Os:              img.OS,
  1173  		Size:            size,
  1174  		VirtualSize:     size, // TODO: field unused, deprecate
  1175  		RootFS:          rootFSToAPIType(img.RootFS),
  1176  	}
  1177  
  1178  	imageInspect.GraphDriver.Name = daemon.GraphDriverName()
  1179  
  1180  	imageInspect.GraphDriver.Data = layerMetadata
  1181  
  1182  	return imageInspect, nil
  1183  }
  1184  
  1185  // LoadImage uploads a set of images into the repository. This is the
  1186  // complement of ImageExport.  The input stream is an uncompressed tar
  1187  // ball containing images and metadata.
  1188  func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
  1189  	imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore)
  1190  	return imageExporter.Load(inTar, outStream, quiet)
  1191  }
  1192  
  1193  // ImageHistory returns a slice of ImageHistory structures for the specified image
  1194  // name by walking the image lineage.
  1195  func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
  1196  	img, err := daemon.GetImage(name)
  1197  	if err != nil {
  1198  		return nil, err
  1199  	}
  1200  
  1201  	history := []*types.ImageHistory{}
  1202  
  1203  	layerCounter := 0
  1204  	rootFS := *img.RootFS
  1205  	rootFS.DiffIDs = nil
  1206  
  1207  	for _, h := range img.History {
  1208  		var layerSize int64
  1209  
  1210  		if !h.EmptyLayer {
  1211  			if len(img.RootFS.DiffIDs) <= layerCounter {
  1212  				return nil, fmt.Errorf("too many non-empty layers in History section")
  1213  			}
  1214  
  1215  			rootFS.Append(img.RootFS.DiffIDs[layerCounter])
  1216  			l, err := daemon.layerStore.Get(rootFS.ChainID())
  1217  			if err != nil {
  1218  				return nil, err
  1219  			}
  1220  			layerSize, err = l.DiffSize()
  1221  			layer.ReleaseAndLog(daemon.layerStore, l)
  1222  			if err != nil {
  1223  				return nil, err
  1224  			}
  1225  
  1226  			layerCounter++
  1227  		}
  1228  
  1229  		history = append([]*types.ImageHistory{{
  1230  			ID:        "<missing>",
  1231  			Created:   h.Created.Unix(),
  1232  			CreatedBy: h.CreatedBy,
  1233  			Comment:   h.Comment,
  1234  			Size:      layerSize,
  1235  		}}, history...)
  1236  	}
  1237  
  1238  	// Fill in image IDs and tags
  1239  	histImg := img
  1240  	id := img.ID()
  1241  	for _, h := range history {
  1242  		h.ID = id.String()
  1243  
  1244  		var tags []string
  1245  		for _, r := range daemon.referenceStore.References(id) {
  1246  			if _, ok := r.(reference.NamedTagged); ok {
  1247  				tags = append(tags, r.String())
  1248  			}
  1249  		}
  1250  
  1251  		h.Tags = tags
  1252  
  1253  		id = histImg.Parent
  1254  		if id == "" {
  1255  			break
  1256  		}
  1257  		histImg, err = daemon.GetImage(id.String())
  1258  		if err != nil {
  1259  			break
  1260  		}
  1261  	}
  1262  
  1263  	return history, nil
  1264  }
  1265  
  1266  // GetImageID returns an image ID corresponding to the image referred to by
  1267  // refOrID.
  1268  func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
  1269  	id, ref, err := reference.ParseIDOrReference(refOrID)
  1270  	if err != nil {
  1271  		return "", err
  1272  	}
  1273  	if id != "" {
  1274  		if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
  1275  			return "", ErrImageDoesNotExist{refOrID}
  1276  		}
  1277  		return image.ID(id), nil
  1278  	}
  1279  
  1280  	if id, err := daemon.referenceStore.Get(ref); err == nil {
  1281  		return id, nil
  1282  	}
  1283  	if tagged, ok := ref.(reference.NamedTagged); ok {
  1284  		if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
  1285  			for _, namedRef := range daemon.referenceStore.References(id) {
  1286  				if namedRef.Name() == ref.Name() {
  1287  					return id, nil
  1288  				}
  1289  			}
  1290  		}
  1291  	}
  1292  
  1293  	// Search based on ID
  1294  	if id, err := daemon.imageStore.Search(refOrID); err == nil {
  1295  		return id, nil
  1296  	}
  1297  
  1298  	return "", ErrImageDoesNotExist{refOrID}
  1299  }
  1300  
  1301  // GetImage returns an image corresponding to the image referred to by refOrID.
  1302  func (daemon *Daemon) GetImage(refOrID string) (*image.Image, error) {
  1303  	imgID, err := daemon.GetImageID(refOrID)
  1304  	if err != nil {
  1305  		return nil, err
  1306  	}
  1307  	return daemon.imageStore.Get(imgID)
  1308  }
  1309  
  1310  // GetImageOnBuild looks up a Docker image referenced by `name`.
  1311  func (daemon *Daemon) GetImageOnBuild(name string) (builder.Image, error) {
  1312  	img, err := daemon.GetImage(name)
  1313  	if err != nil {
  1314  		return nil, err
  1315  	}
  1316  	return img, nil
  1317  }
  1318  
  1319  // GraphDriverName returns the name of the graph driver used by the layer.Store
  1320  func (daemon *Daemon) GraphDriverName() string {
  1321  	return daemon.layerStore.DriverName()
  1322  }
  1323  
  1324  // GetUIDGIDMaps returns the current daemon's user namespace settings
  1325  // for the full uid and gid maps which will be applied to containers
  1326  // started in this instance.
  1327  func (daemon *Daemon) GetUIDGIDMaps() ([]idtools.IDMap, []idtools.IDMap) {
  1328  	return daemon.uidMaps, daemon.gidMaps
  1329  }
  1330  
  1331  // GetRemappedUIDGID returns the current daemon's uid and gid values
  1332  // if user namespaces are in use for this daemon instance.  If not
  1333  // this function will return "real" root values of 0, 0.
  1334  func (daemon *Daemon) GetRemappedUIDGID() (int, int) {
  1335  	uid, gid, _ := idtools.GetRootUIDGID(daemon.uidMaps, daemon.gidMaps)
  1336  	return uid, gid
  1337  }
  1338  
  1339  // GetCachedImage returns the most recent created image that is a child
  1340  // of the image with imgID, that had the same config when it was
  1341  // created. nil is returned if a child cannot be found. An error is
  1342  // returned if the parent image cannot be found.
  1343  func (daemon *Daemon) GetCachedImage(imgID image.ID, config *containertypes.Config) (*image.Image, error) {
  1344  	// Loop on the children of the given image and check the config
  1345  	getMatch := func(siblings []image.ID) (*image.Image, error) {
  1346  		var match *image.Image
  1347  		for _, id := range siblings {
  1348  			img, err := daemon.imageStore.Get(id)
  1349  			if err != nil {
  1350  				return nil, fmt.Errorf("unable to find image %q", id)
  1351  			}
  1352  
  1353  			if runconfig.Compare(&img.ContainerConfig, config) {
  1354  				// check for the most up to date match
  1355  				if match == nil || match.Created.Before(img.Created) {
  1356  					match = img
  1357  				}
  1358  			}
  1359  		}
  1360  		return match, nil
  1361  	}
  1362  
  1363  	// In this case, this is `FROM scratch`, which isn't an actual image.
  1364  	if imgID == "" {
  1365  		images := daemon.imageStore.Map()
  1366  		var siblings []image.ID
  1367  		for id, img := range images {
  1368  			if img.Parent == imgID {
  1369  				siblings = append(siblings, id)
  1370  			}
  1371  		}
  1372  		return getMatch(siblings)
  1373  	}
  1374  
  1375  	// find match from child images
  1376  	siblings := daemon.imageStore.Children(imgID)
  1377  	return getMatch(siblings)
  1378  }
  1379  
  1380  // GetCachedImageOnBuild returns a reference to a cached image whose parent equals `parent`
  1381  // and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error.
  1382  func (daemon *Daemon) GetCachedImageOnBuild(imgID string, cfg *containertypes.Config) (string, error) {
  1383  	cache, err := daemon.GetCachedImage(image.ID(imgID), cfg)
  1384  	if cache == nil || err != nil {
  1385  		return "", err
  1386  	}
  1387  	return cache.ID().String(), nil
  1388  }
  1389  
  1390  // tempDir returns the default directory to use for temporary files.
  1391  func tempDir(rootDir string, rootUID, rootGID int) (string, error) {
  1392  	var tmpDir string
  1393  	if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" {
  1394  		tmpDir = filepath.Join(rootDir, "tmp")
  1395  	}
  1396  	return tmpDir, idtools.MkdirAllAs(tmpDir, 0700, rootUID, rootGID)
  1397  }
  1398  
  1399  func (daemon *Daemon) setSecurityOptions(container *container.Container, hostConfig *containertypes.HostConfig) error {
  1400  	container.Lock()
  1401  	defer container.Unlock()
  1402  	return parseSecurityOpt(container, hostConfig)
  1403  }
  1404  
  1405  func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error {
  1406  	// Do not lock while creating volumes since this could be calling out to external plugins
  1407  	// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
  1408  	if err := daemon.registerMountPoints(container, hostConfig); err != nil {
  1409  		return err
  1410  	}
  1411  
  1412  	container.Lock()
  1413  	defer container.Unlock()
  1414  
  1415  	// Register any links from the host config before starting the container
  1416  	if err := daemon.registerLinks(container, hostConfig); err != nil {
  1417  		return err
  1418  	}
  1419  
  1420  	// make sure links is not nil
  1421  	// this ensures that on the next daemon restart we don't try to migrate from legacy sqlite links
  1422  	if hostConfig.Links == nil {
  1423  		hostConfig.Links = []string{}
  1424  	}
  1425  
  1426  	container.HostConfig = hostConfig
  1427  	return container.ToDisk()
  1428  }
  1429  
  1430  func (daemon *Daemon) setupInitLayer(initPath string) error {
  1431  	rootUID, rootGID := daemon.GetRemappedUIDGID()
  1432  	return setupInitLayer(initPath, rootUID, rootGID)
  1433  }
  1434  
  1435  func setDefaultMtu(config *Config) {
  1436  	// do nothing if the config does not have the default 0 value.
  1437  	if config.Mtu != 0 {
  1438  		return
  1439  	}
  1440  	config.Mtu = defaultNetworkMtu
  1441  }
  1442  
  1443  // verifyContainerSettings performs validation of the hostconfig and config
  1444  // structures.
  1445  func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
  1446  
  1447  	// First perform verification of settings common across all platforms.
  1448  	if config != nil {
  1449  		if config.WorkingDir != "" {
  1450  			config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
  1451  			if !system.IsAbs(config.WorkingDir) {
  1452  				return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path.", config.WorkingDir)
  1453  			}
  1454  		}
  1455  
  1456  		if len(config.StopSignal) > 0 {
  1457  			_, err := signal.ParseSignal(config.StopSignal)
  1458  			if err != nil {
  1459  				return nil, err
  1460  			}
  1461  		}
  1462  	}
  1463  
  1464  	if hostConfig == nil {
  1465  		return nil, nil
  1466  	}
  1467  
  1468  	logCfg := daemon.getLogConfig(hostConfig.LogConfig)
  1469  	if err := logger.ValidateLogOpts(logCfg.Type, logCfg.Config); err != nil {
  1470  		return nil, err
  1471  	}
  1472  
  1473  	for port := range hostConfig.PortBindings {
  1474  		_, portStr := nat.SplitProtoPort(string(port))
  1475  		if _, err := nat.ParsePort(portStr); err != nil {
  1476  			return nil, fmt.Errorf("Invalid port specification: %q", portStr)
  1477  		}
  1478  		for _, pb := range hostConfig.PortBindings[port] {
  1479  			_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
  1480  			if err != nil {
  1481  				return nil, fmt.Errorf("Invalid port specification: %q", pb.HostPort)
  1482  			}
  1483  		}
  1484  	}
  1485  
  1486  	// Now do platform-specific verification
  1487  	return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
  1488  }
  1489  
  1490  // Checks if the client set configurations for more than one network while creating a container
  1491  func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
  1492  	if nwConfig == nil || len(nwConfig.EndpointsConfig) <= 1 {
  1493  		return nil
  1494  	}
  1495  	l := make([]string, 0, len(nwConfig.EndpointsConfig))
  1496  	for k := range nwConfig.EndpointsConfig {
  1497  		l = append(l, k)
  1498  	}
  1499  	err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
  1500  	return errors.NewBadRequestError(err)
  1501  }
  1502  
  1503  func configureVolumes(config *Config, rootUID, rootGID int) (*store.VolumeStore, error) {
  1504  	volumesDriver, err := local.New(config.Root, rootUID, rootGID)
  1505  	if err != nil {
  1506  		return nil, err
  1507  	}
  1508  
  1509  	volumedrivers.Register(volumesDriver, volumesDriver.Name())
  1510  	return store.New(config.Root)
  1511  }
  1512  
  1513  // AuthenticateToRegistry checks the validity of credentials in authConfig
  1514  func (daemon *Daemon) AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error) {
  1515  	return daemon.RegistryService.Auth(authConfig, dockerversion.DockerUserAgent(ctx))
  1516  }
  1517  
  1518  // SearchRegistryForImages queries the registry for images matching
  1519  // term. authConfig is used to login.
  1520  func (daemon *Daemon) SearchRegistryForImages(ctx context.Context, term string,
  1521  	authConfig *types.AuthConfig,
  1522  	headers map[string][]string) (*registrytypes.SearchResults, error) {
  1523  	return daemon.RegistryService.Search(term, authConfig, dockerversion.DockerUserAgent(ctx), headers)
  1524  }
  1525  
  1526  // IsShuttingDown tells whether the daemon is shutting down or not
  1527  func (daemon *Daemon) IsShuttingDown() bool {
  1528  	return daemon.shutdown
  1529  }
  1530  
  1531  // GetContainerStats collects all the stats published by a container
  1532  func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.StatsJSON, error) {
  1533  	stats, err := daemon.stats(container)
  1534  	if err != nil {
  1535  		return nil, err
  1536  	}
  1537  
  1538  	if stats.Networks, err = daemon.getNetworkStats(container); err != nil {
  1539  		return nil, err
  1540  	}
  1541  
  1542  	return stats, nil
  1543  }
  1544  
  1545  func (daemon *Daemon) getNetworkStats(c *container.Container) (map[string]types.NetworkStats, error) {
  1546  	sb, err := daemon.netController.SandboxByID(c.NetworkSettings.SandboxID)
  1547  	if err != nil {
  1548  		return nil, err
  1549  	}
  1550  
  1551  	lnstats, err := sb.Statistics()
  1552  	if err != nil {
  1553  		return nil, err
  1554  	}
  1555  
  1556  	stats := make(map[string]types.NetworkStats)
  1557  	// Convert libnetwork nw stats into engine-api stats
  1558  	for ifName, ifStats := range lnstats {
  1559  		stats[ifName] = types.NetworkStats{
  1560  			RxBytes:   ifStats.RxBytes,
  1561  			RxPackets: ifStats.RxPackets,
  1562  			RxErrors:  ifStats.RxErrors,
  1563  			RxDropped: ifStats.RxDropped,
  1564  			TxBytes:   ifStats.TxBytes,
  1565  			TxPackets: ifStats.TxPackets,
  1566  			TxErrors:  ifStats.TxErrors,
  1567  			TxDropped: ifStats.TxDropped,
  1568  		}
  1569  	}
  1570  
  1571  	return stats, nil
  1572  }
  1573  
  1574  // newBaseContainer creates a new container with its initial
  1575  // configuration based on the root storage from the daemon.
  1576  func (daemon *Daemon) newBaseContainer(id string) *container.Container {
  1577  	return container.NewBaseContainer(id, daemon.containerRoot(id))
  1578  }
  1579  
  1580  // initDiscovery initializes the discovery watcher for this daemon.
  1581  func (daemon *Daemon) initDiscovery(config *Config) error {
  1582  	advertise, err := parseClusterAdvertiseSettings(config.ClusterStore, config.ClusterAdvertise)
  1583  	if err != nil {
  1584  		if err == errDiscoveryDisabled {
  1585  			return nil
  1586  		}
  1587  		return err
  1588  	}
  1589  
  1590  	config.ClusterAdvertise = advertise
  1591  	discoveryWatcher, err := initDiscovery(config.ClusterStore, config.ClusterAdvertise, config.ClusterOpts)
  1592  	if err != nil {
  1593  		return fmt.Errorf("discovery initialization failed (%v)", err)
  1594  	}
  1595  
  1596  	daemon.discoveryWatcher = discoveryWatcher
  1597  	return nil
  1598  }
  1599  
  1600  // Reload reads configuration changes and modifies the
  1601  // daemon according to those changes.
  1602  // This are the settings that Reload changes:
  1603  // - Daemon labels.
  1604  // - Cluster discovery (reconfigure and restart).
  1605  func (daemon *Daemon) Reload(config *Config) error {
  1606  	daemon.configStore.reloadLock.Lock()
  1607  	defer daemon.configStore.reloadLock.Unlock()
  1608  	if config.IsValueSet("labels") {
  1609  		daemon.configStore.Labels = config.Labels
  1610  	}
  1611  	if config.IsValueSet("debug") {
  1612  		daemon.configStore.Debug = config.Debug
  1613  	}
  1614  	return daemon.reloadClusterDiscovery(config)
  1615  }
  1616  
  1617  func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
  1618  	var err error
  1619  	newAdvertise := daemon.configStore.ClusterAdvertise
  1620  	newClusterStore := daemon.configStore.ClusterStore
  1621  	if config.IsValueSet("cluster-advertise") {
  1622  		if config.IsValueSet("cluster-store") {
  1623  			newClusterStore = config.ClusterStore
  1624  		}
  1625  		newAdvertise, err = parseClusterAdvertiseSettings(newClusterStore, config.ClusterAdvertise)
  1626  		if err != nil && err != errDiscoveryDisabled {
  1627  			return err
  1628  		}
  1629  	}
  1630  
  1631  	// check discovery modifications
  1632  	if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, config.ClusterOpts) {
  1633  		return nil
  1634  	}
  1635  
  1636  	// enable discovery for the first time if it was not previously enabled
  1637  	if daemon.discoveryWatcher == nil {
  1638  		discoveryWatcher, err := initDiscovery(newClusterStore, newAdvertise, config.ClusterOpts)
  1639  		if err != nil {
  1640  			return fmt.Errorf("discovery initialization failed (%v)", err)
  1641  		}
  1642  		daemon.discoveryWatcher = discoveryWatcher
  1643  	} else {
  1644  		if err == errDiscoveryDisabled {
  1645  			// disable discovery if it was previously enabled and it's disabled now
  1646  			daemon.discoveryWatcher.Stop()
  1647  		} else {
  1648  			// reload discovery
  1649  			if err = daemon.discoveryWatcher.Reload(config.ClusterStore, newAdvertise, config.ClusterOpts); err != nil {
  1650  				return err
  1651  			}
  1652  		}
  1653  	}
  1654  
  1655  	daemon.configStore.ClusterStore = newClusterStore
  1656  	daemon.configStore.ClusterOpts = config.ClusterOpts
  1657  	daemon.configStore.ClusterAdvertise = newAdvertise
  1658  
  1659  	if daemon.netController == nil {
  1660  		return nil
  1661  	}
  1662  	netOptions, err := daemon.networkOptions(daemon.configStore)
  1663  	if err != nil {
  1664  		logrus.Warnf("Failed to reload configuration with network controller: %v", err)
  1665  		return nil
  1666  	}
  1667  	err = daemon.netController.ReloadConfiguration(netOptions...)
  1668  	if err != nil {
  1669  		logrus.Warnf("Failed to reload configuration with network controller: %v", err)
  1670  	}
  1671  
  1672  	return nil
  1673  }
  1674  
  1675  func validateID(id string) error {
  1676  	if id == "" {
  1677  		return fmt.Errorf("Invalid empty id")
  1678  	}
  1679  	return nil
  1680  }
  1681  
  1682  func isBridgeNetworkDisabled(config *Config) bool {
  1683  	return config.bridgeConfig.Iface == disableNetworkBridge
  1684  }
  1685  
  1686  func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error) {
  1687  	options := []nwconfig.Option{}
  1688  	if dconfig == nil {
  1689  		return options, nil
  1690  	}
  1691  
  1692  	options = append(options, nwconfig.OptionDataDir(dconfig.Root))
  1693  
  1694  	dd := runconfig.DefaultDaemonNetworkMode()
  1695  	dn := runconfig.DefaultDaemonNetworkMode().NetworkName()
  1696  	options = append(options, nwconfig.OptionDefaultDriver(string(dd)))
  1697  	options = append(options, nwconfig.OptionDefaultNetwork(dn))
  1698  
  1699  	if strings.TrimSpace(dconfig.ClusterStore) != "" {
  1700  		kv := strings.Split(dconfig.ClusterStore, "://")
  1701  		if len(kv) != 2 {
  1702  			return nil, fmt.Errorf("kv store daemon config must be of the form KV-PROVIDER://KV-URL")
  1703  		}
  1704  		options = append(options, nwconfig.OptionKVProvider(kv[0]))
  1705  		options = append(options, nwconfig.OptionKVProviderURL(kv[1]))
  1706  	}
  1707  	if len(dconfig.ClusterOpts) > 0 {
  1708  		options = append(options, nwconfig.OptionKVOpts(dconfig.ClusterOpts))
  1709  	}
  1710  
  1711  	if daemon.discoveryWatcher != nil {
  1712  		options = append(options, nwconfig.OptionDiscoveryWatcher(daemon.discoveryWatcher))
  1713  	}
  1714  
  1715  	if dconfig.ClusterAdvertise != "" {
  1716  		options = append(options, nwconfig.OptionDiscoveryAddress(dconfig.ClusterAdvertise))
  1717  	}
  1718  
  1719  	options = append(options, nwconfig.OptionLabels(dconfig.Labels))
  1720  	options = append(options, driverOptions(dconfig)...)
  1721  	return options, nil
  1722  }
  1723  
  1724  func copyBlkioEntry(entries []*containerd.BlkioStatsEntry) []types.BlkioStatEntry {
  1725  	out := make([]types.BlkioStatEntry, len(entries))
  1726  	for i, re := range entries {
  1727  		out[i] = types.BlkioStatEntry{
  1728  			Major: re.Major,
  1729  			Minor: re.Minor,
  1730  			Op:    re.Op,
  1731  			Value: re.Value,
  1732  		}
  1733  	}
  1734  	return out
  1735  }