github.com/erriapo/docker@v1.6.0-rc2/daemon/daemon.go (about)

     1  package daemon
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  	"path/filepath"
    11  	"regexp"
    12  	"runtime"
    13  	"strings"
    14  	"sync"
    15  	"time"
    16  
    17  	"github.com/docker/libcontainer/label"
    18  
    19  	log "github.com/Sirupsen/logrus"
    20  	"github.com/docker/docker/api"
    21  	"github.com/docker/docker/autogen/dockerversion"
    22  	"github.com/docker/docker/daemon/execdriver"
    23  	"github.com/docker/docker/daemon/execdriver/execdrivers"
    24  	"github.com/docker/docker/daemon/execdriver/lxc"
    25  	"github.com/docker/docker/daemon/graphdriver"
    26  	_ "github.com/docker/docker/daemon/graphdriver/vfs"
    27  	_ "github.com/docker/docker/daemon/networkdriver/bridge"
    28  	"github.com/docker/docker/daemon/networkdriver/portallocator"
    29  	"github.com/docker/docker/engine"
    30  	"github.com/docker/docker/graph"
    31  	"github.com/docker/docker/image"
    32  	"github.com/docker/docker/pkg/archive"
    33  	"github.com/docker/docker/pkg/broadcastwriter"
    34  	"github.com/docker/docker/pkg/common"
    35  	"github.com/docker/docker/pkg/graphdb"
    36  	"github.com/docker/docker/pkg/ioutils"
    37  	"github.com/docker/docker/pkg/namesgenerator"
    38  	"github.com/docker/docker/pkg/networkfs/resolvconf"
    39  	"github.com/docker/docker/pkg/parsers"
    40  	"github.com/docker/docker/pkg/parsers/kernel"
    41  	"github.com/docker/docker/pkg/sysinfo"
    42  	"github.com/docker/docker/pkg/truncindex"
    43  	"github.com/docker/docker/runconfig"
    44  	"github.com/docker/docker/trust"
    45  	"github.com/docker/docker/utils"
    46  	"github.com/docker/docker/volumes"
    47  
    48  	"github.com/go-fsnotify/fsnotify"
    49  )
    50  
    51  var (
    52  	validContainerNameChars   = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
    53  	validContainerNamePattern = regexp.MustCompile(`^/?` + validContainerNameChars + `+$`)
    54  )
    55  
    56  type contStore struct {
    57  	s map[string]*Container
    58  	sync.Mutex
    59  }
    60  
    61  func (c *contStore) Add(id string, cont *Container) {
    62  	c.Lock()
    63  	c.s[id] = cont
    64  	c.Unlock()
    65  }
    66  
    67  func (c *contStore) Get(id string) *Container {
    68  	c.Lock()
    69  	res := c.s[id]
    70  	c.Unlock()
    71  	return res
    72  }
    73  
    74  func (c *contStore) Delete(id string) {
    75  	c.Lock()
    76  	delete(c.s, id)
    77  	c.Unlock()
    78  }
    79  
    80  func (c *contStore) List() []*Container {
    81  	containers := new(History)
    82  	c.Lock()
    83  	for _, cont := range c.s {
    84  		containers.Add(cont)
    85  	}
    86  	c.Unlock()
    87  	containers.Sort()
    88  	return *containers
    89  }
    90  
    91  type Daemon struct {
    92  	ID               string
    93  	repository       string
    94  	sysInitPath      string
    95  	containers       *contStore
    96  	execCommands     *execStore
    97  	graph            *graph.Graph
    98  	repositories     *graph.TagStore
    99  	idIndex          *truncindex.TruncIndex
   100  	sysInfo          *sysinfo.SysInfo
   101  	volumes          *volumes.Repository
   102  	eng              *engine.Engine
   103  	config           *Config
   104  	containerGraph   *graphdb.Database
   105  	driver           graphdriver.Driver
   106  	execDriver       execdriver.Driver
   107  	trustStore       *trust.TrustStore
   108  	statsCollector   *statsCollector
   109  	defaultLogConfig runconfig.LogConfig
   110  }
   111  
   112  // Install installs daemon capabilities to eng.
   113  func (daemon *Daemon) Install(eng *engine.Engine) error {
   114  	// FIXME: remove ImageDelete's dependency on Daemon, then move to graph/
   115  	for name, method := range map[string]engine.Handler{
   116  		"attach":            daemon.ContainerAttach,
   117  		"commit":            daemon.ContainerCommit,
   118  		"container_changes": daemon.ContainerChanges,
   119  		"container_copy":    daemon.ContainerCopy,
   120  		"container_rename":  daemon.ContainerRename,
   121  		"container_inspect": daemon.ContainerInspect,
   122  		"container_stats":   daemon.ContainerStats,
   123  		"containers":        daemon.Containers,
   124  		"create":            daemon.ContainerCreate,
   125  		"rm":                daemon.ContainerRm,
   126  		"export":            daemon.ContainerExport,
   127  		"info":              daemon.CmdInfo,
   128  		"kill":              daemon.ContainerKill,
   129  		"logs":              daemon.ContainerLogs,
   130  		"pause":             daemon.ContainerPause,
   131  		"resize":            daemon.ContainerResize,
   132  		"restart":           daemon.ContainerRestart,
   133  		"start":             daemon.ContainerStart,
   134  		"stop":              daemon.ContainerStop,
   135  		"top":               daemon.ContainerTop,
   136  		"unpause":           daemon.ContainerUnpause,
   137  		"wait":              daemon.ContainerWait,
   138  		"image_delete":      daemon.ImageDelete, // FIXME: see above
   139  		"execCreate":        daemon.ContainerExecCreate,
   140  		"execStart":         daemon.ContainerExecStart,
   141  		"execResize":        daemon.ContainerExecResize,
   142  		"execInspect":       daemon.ContainerExecInspect,
   143  	} {
   144  		if err := eng.Register(name, method); err != nil {
   145  			return err
   146  		}
   147  	}
   148  	if err := daemon.Repositories().Install(eng); err != nil {
   149  		return err
   150  	}
   151  	if err := daemon.trustStore.Install(eng); err != nil {
   152  		return err
   153  	}
   154  	// FIXME: this hack is necessary for legacy integration tests to access
   155  	// the daemon object.
   156  	eng.Hack_SetGlobalVar("httpapi.daemon", daemon)
   157  	return nil
   158  }
   159  
   160  // Get looks for a container using the provided information, which could be
   161  // one of the following inputs from the caller:
   162  //  - A full container ID, which will exact match a container in daemon's list
   163  //  - A container name, which will only exact match via the GetByName() function
   164  //  - A partial container ID prefix (e.g. short ID) of any length that is
   165  //    unique enough to only return a single container object
   166  //  If none of these searches succeed, an error is returned
   167  func (daemon *Daemon) Get(prefixOrName string) (*Container, error) {
   168  	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
   169  		// prefix is an exact match to a full container ID
   170  		return containerByID, nil
   171  	}
   172  
   173  	// GetByName will match only an exact name provided; we ignore errors
   174  	containerByName, _ := daemon.GetByName(prefixOrName)
   175  	containerId, indexError := daemon.idIndex.Get(prefixOrName)
   176  
   177  	if containerByName != nil {
   178  		// prefix is an exact match to a full container Name
   179  		return containerByName, nil
   180  	}
   181  
   182  	if containerId != "" {
   183  		// prefix is a fuzzy match to a container ID
   184  		return daemon.containers.Get(containerId), nil
   185  	}
   186  	return nil, indexError
   187  }
   188  
   189  // Exists returns a true if a container of the specified ID or name exists,
   190  // false otherwise.
   191  func (daemon *Daemon) Exists(id string) bool {
   192  	c, _ := daemon.Get(id)
   193  	return c != nil
   194  }
   195  
   196  func (daemon *Daemon) containerRoot(id string) string {
   197  	return path.Join(daemon.repository, id)
   198  }
   199  
   200  // Load reads the contents of a container from disk
   201  // This is typically done at startup.
   202  func (daemon *Daemon) load(id string) (*Container, error) {
   203  	container := &Container{
   204  		root:         daemon.containerRoot(id),
   205  		State:        NewState(),
   206  		execCommands: newExecStore(),
   207  	}
   208  	if err := container.FromDisk(); err != nil {
   209  		return nil, err
   210  	}
   211  
   212  	if container.ID != id {
   213  		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
   214  	}
   215  
   216  	container.readHostConfig()
   217  
   218  	return container, nil
   219  }
   220  
   221  // Register makes a container object usable by the daemon as <container.ID>
   222  // This is a wrapper for register
   223  func (daemon *Daemon) Register(container *Container) error {
   224  	return daemon.register(container, true)
   225  }
   226  
   227  // register makes a container object usable by the daemon as <container.ID>
   228  func (daemon *Daemon) register(container *Container, updateSuffixarray bool) error {
   229  	if container.daemon != nil || daemon.Exists(container.ID) {
   230  		return fmt.Errorf("Container is already loaded")
   231  	}
   232  	if err := validateID(container.ID); err != nil {
   233  		return err
   234  	}
   235  	if err := daemon.ensureName(container); err != nil {
   236  		return err
   237  	}
   238  
   239  	container.daemon = daemon
   240  
   241  	// Attach to stdout and stderr
   242  	container.stderr = broadcastwriter.New()
   243  	container.stdout = broadcastwriter.New()
   244  	// Attach to stdin
   245  	if container.Config.OpenStdin {
   246  		container.stdin, container.stdinPipe = io.Pipe()
   247  	} else {
   248  		container.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard) // Silently drop stdin
   249  	}
   250  	// done
   251  	daemon.containers.Add(container.ID, container)
   252  
   253  	// don't update the Suffixarray if we're starting up
   254  	// we'll waste time if we update it for every container
   255  	daemon.idIndex.Add(container.ID)
   256  
   257  	container.registerVolumes()
   258  
   259  	// FIXME: if the container is supposed to be running but is not, auto restart it?
   260  	//        if so, then we need to restart monitor and init a new lock
   261  	// If the container is supposed to be running, make sure of it
   262  	if container.IsRunning() {
   263  		log.Debugf("killing old running container %s", container.ID)
   264  
   265  		existingPid := container.Pid
   266  		container.SetStopped(&execdriver.ExitStatus{ExitCode: 0})
   267  
   268  		// We only have to handle this for lxc because the other drivers will ensure that
   269  		// no processes are left when docker dies
   270  		if container.ExecDriver == "" || strings.Contains(container.ExecDriver, "lxc") {
   271  			lxc.KillLxc(container.ID, 9)
   272  		} else {
   273  			// use the current driver and ensure that the container is dead x.x
   274  			cmd := &execdriver.Command{
   275  				ID: container.ID,
   276  			}
   277  			var err error
   278  			cmd.ProcessConfig.Process, err = os.FindProcess(existingPid)
   279  			if err != nil {
   280  				log.Debugf("cannot find existing process for %d", existingPid)
   281  			}
   282  			daemon.execDriver.Terminate(cmd)
   283  		}
   284  
   285  		if err := container.Unmount(); err != nil {
   286  			log.Debugf("unmount error %s", err)
   287  		}
   288  		if err := container.ToDisk(); err != nil {
   289  			log.Debugf("saving stopped state to disk %s", err)
   290  		}
   291  
   292  		info := daemon.execDriver.Info(container.ID)
   293  		if !info.IsRunning() {
   294  			log.Debugf("Container %s was supposed to be running but is not.", container.ID)
   295  
   296  			log.Debugf("Marking as stopped")
   297  
   298  			container.SetStopped(&execdriver.ExitStatus{ExitCode: -127})
   299  			if err := container.ToDisk(); err != nil {
   300  				return err
   301  			}
   302  		}
   303  	}
   304  	return nil
   305  }
   306  
   307  func (daemon *Daemon) ensureName(container *Container) error {
   308  	if container.Name == "" {
   309  		name, err := daemon.generateNewName(container.ID)
   310  		if err != nil {
   311  			return err
   312  		}
   313  		container.Name = name
   314  
   315  		if err := container.ToDisk(); err != nil {
   316  			log.Debugf("Error saving container name %s", err)
   317  		}
   318  	}
   319  	return nil
   320  }
   321  
   322  func (daemon *Daemon) LogToDisk(src *broadcastwriter.BroadcastWriter, dst, stream string) error {
   323  	log, err := os.OpenFile(dst, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600)
   324  	if err != nil {
   325  		return err
   326  	}
   327  	src.AddWriter(log, stream)
   328  	return nil
   329  }
   330  
   331  func (daemon *Daemon) restore() error {
   332  	var (
   333  		debug         = (os.Getenv("DEBUG") != "" || os.Getenv("TEST") != "")
   334  		containers    = make(map[string]*Container)
   335  		currentDriver = daemon.driver.String()
   336  	)
   337  
   338  	if !debug {
   339  		log.Infof("Loading containers: start.")
   340  	}
   341  	dir, err := ioutil.ReadDir(daemon.repository)
   342  	if err != nil {
   343  		return err
   344  	}
   345  
   346  	for _, v := range dir {
   347  		id := v.Name()
   348  		container, err := daemon.load(id)
   349  		if !debug && log.GetLevel() == log.InfoLevel {
   350  			fmt.Print(".")
   351  		}
   352  		if err != nil {
   353  			log.Errorf("Failed to load container %v: %v", id, err)
   354  			continue
   355  		}
   356  
   357  		// Ignore the container if it does not support the current driver being used by the graph
   358  		if (container.Driver == "" && currentDriver == "aufs") || container.Driver == currentDriver {
   359  			log.Debugf("Loaded container %v", container.ID)
   360  
   361  			containers[container.ID] = container
   362  		} else {
   363  			log.Debugf("Cannot load container %s because it was created with another graph driver.", container.ID)
   364  		}
   365  	}
   366  
   367  	registeredContainers := []*Container{}
   368  
   369  	if entities := daemon.containerGraph.List("/", -1); entities != nil {
   370  		for _, p := range entities.Paths() {
   371  			if !debug && log.GetLevel() == log.InfoLevel {
   372  				fmt.Print(".")
   373  			}
   374  
   375  			e := entities[p]
   376  
   377  			if container, ok := containers[e.ID()]; ok {
   378  				if err := daemon.register(container, false); err != nil {
   379  					log.Debugf("Failed to register container %s: %s", container.ID, err)
   380  				}
   381  
   382  				registeredContainers = append(registeredContainers, container)
   383  
   384  				// delete from the map so that a new name is not automatically generated
   385  				delete(containers, e.ID())
   386  			}
   387  		}
   388  	}
   389  
   390  	// Any containers that are left over do not exist in the graph
   391  	for _, container := range containers {
   392  		// Try to set the default name for a container if it exists prior to links
   393  		container.Name, err = daemon.generateNewName(container.ID)
   394  		if err != nil {
   395  			log.Debugf("Setting default id - %s", err)
   396  		}
   397  
   398  		if err := daemon.register(container, false); err != nil {
   399  			log.Debugf("Failed to register container %s: %s", container.ID, err)
   400  		}
   401  
   402  		registeredContainers = append(registeredContainers, container)
   403  	}
   404  
   405  	// check the restart policy on the containers and restart any container with
   406  	// the restart policy of "always"
   407  	if daemon.config.AutoRestart {
   408  		log.Debugf("Restarting containers...")
   409  
   410  		for _, container := range registeredContainers {
   411  			if container.hostConfig.RestartPolicy.Name == "always" ||
   412  				(container.hostConfig.RestartPolicy.Name == "on-failure" && container.ExitCode != 0) {
   413  				log.Debugf("Starting container %s", container.ID)
   414  
   415  				if err := container.Start(); err != nil {
   416  					log.Debugf("Failed to start container %s: %s", container.ID, err)
   417  				}
   418  			}
   419  		}
   420  	}
   421  
   422  	if !debug {
   423  		if log.GetLevel() == log.InfoLevel {
   424  			fmt.Println()
   425  		}
   426  		log.Infof("Loading containers: done.")
   427  	}
   428  
   429  	return nil
   430  }
   431  
   432  // set up the watch on the host's /etc/resolv.conf so that we can update container's
   433  // live resolv.conf when the network changes on the host
   434  func (daemon *Daemon) setupResolvconfWatcher() error {
   435  
   436  	watcher, err := fsnotify.NewWatcher()
   437  	if err != nil {
   438  		return err
   439  	}
   440  
   441  	//this goroutine listens for the events on the watch we add
   442  	//on the resolv.conf file on the host
   443  	go func() {
   444  		for {
   445  			select {
   446  			case event := <-watcher.Events:
   447  				if event.Name == "/etc/resolv.conf" &&
   448  					(event.Op&fsnotify.Write == fsnotify.Write ||
   449  						event.Op&fsnotify.Create == fsnotify.Create) {
   450  					// verify a real change happened before we go further--a file write may have happened
   451  					// without an actual change to the file
   452  					updatedResolvConf, newResolvConfHash, err := resolvconf.GetIfChanged()
   453  					if err != nil {
   454  						log.Debugf("Error retrieving updated host resolv.conf: %v", err)
   455  					} else if updatedResolvConf != nil {
   456  						// because the new host resolv.conf might have localhost nameservers..
   457  						updatedResolvConf, modified := resolvconf.FilterResolvDns(updatedResolvConf, daemon.config.EnableIPv6)
   458  						if modified {
   459  							// changes have occurred during localhost cleanup: generate an updated hash
   460  							newHash, err := utils.HashData(bytes.NewReader(updatedResolvConf))
   461  							if err != nil {
   462  								log.Debugf("Error generating hash of new resolv.conf: %v", err)
   463  							} else {
   464  								newResolvConfHash = newHash
   465  							}
   466  						}
   467  						log.Debugf("host network resolv.conf changed--walking container list for updates")
   468  						contList := daemon.containers.List()
   469  						for _, container := range contList {
   470  							if err := container.updateResolvConf(updatedResolvConf, newResolvConfHash); err != nil {
   471  								log.Debugf("Error on resolv.conf update check for container ID: %s: %v", container.ID, err)
   472  							}
   473  						}
   474  					}
   475  				}
   476  			case err := <-watcher.Errors:
   477  				log.Debugf("host resolv.conf notify error: %v", err)
   478  			}
   479  		}
   480  	}()
   481  
   482  	if err := watcher.Add("/etc"); err != nil {
   483  		return err
   484  	}
   485  	return nil
   486  }
   487  
   488  func (daemon *Daemon) checkDeprecatedExpose(config *runconfig.Config) bool {
   489  	if config != nil {
   490  		if config.PortSpecs != nil {
   491  			for _, p := range config.PortSpecs {
   492  				if strings.Contains(p, ":") {
   493  					return true
   494  				}
   495  			}
   496  		}
   497  	}
   498  	return false
   499  }
   500  
   501  func (daemon *Daemon) mergeAndVerifyConfig(config *runconfig.Config, img *image.Image) ([]string, error) {
   502  	warnings := []string{}
   503  	if (img != nil && daemon.checkDeprecatedExpose(img.Config)) || daemon.checkDeprecatedExpose(config) {
   504  		warnings = append(warnings, "The mapping to public ports on your host via Dockerfile EXPOSE (host:port:port) has been deprecated. Use -p to publish the ports.")
   505  	}
   506  	if img != nil && img.Config != nil {
   507  		if err := runconfig.Merge(config, img.Config); err != nil {
   508  			return nil, err
   509  		}
   510  	}
   511  	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
   512  		return nil, fmt.Errorf("No command specified")
   513  	}
   514  	return warnings, nil
   515  }
   516  
   517  func (daemon *Daemon) generateIdAndName(name string) (string, string, error) {
   518  	var (
   519  		err error
   520  		id  = common.GenerateRandomID()
   521  	)
   522  
   523  	if name == "" {
   524  		if name, err = daemon.generateNewName(id); err != nil {
   525  			return "", "", err
   526  		}
   527  		return id, name, nil
   528  	}
   529  
   530  	if name, err = daemon.reserveName(id, name); err != nil {
   531  		return "", "", err
   532  	}
   533  
   534  	return id, name, nil
   535  }
   536  
   537  func (daemon *Daemon) reserveName(id, name string) (string, error) {
   538  	if !validContainerNamePattern.MatchString(name) {
   539  		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
   540  	}
   541  
   542  	if name[0] != '/' {
   543  		name = "/" + name
   544  	}
   545  
   546  	if _, err := daemon.containerGraph.Set(name, id); err != nil {
   547  		if !graphdb.IsNonUniqueNameError(err) {
   548  			return "", err
   549  		}
   550  
   551  		conflictingContainer, err := daemon.GetByName(name)
   552  		if err != nil {
   553  			if strings.Contains(err.Error(), "Could not find entity") {
   554  				return "", err
   555  			}
   556  
   557  			// Remove name and continue starting the container
   558  			if err := daemon.containerGraph.Delete(name); err != nil {
   559  				return "", err
   560  			}
   561  		} else {
   562  			nameAsKnownByUser := strings.TrimPrefix(name, "/")
   563  			return "", fmt.Errorf(
   564  				"Conflict. The name %q is already in use by container %s. You have to delete (or rename) that container to be able to reuse that name.", nameAsKnownByUser,
   565  				common.TruncateID(conflictingContainer.ID))
   566  		}
   567  	}
   568  	return name, nil
   569  }
   570  
   571  func (daemon *Daemon) generateNewName(id string) (string, error) {
   572  	var name string
   573  	for i := 0; i < 6; i++ {
   574  		name = namesgenerator.GetRandomName(i)
   575  		if name[0] != '/' {
   576  			name = "/" + name
   577  		}
   578  
   579  		if _, err := daemon.containerGraph.Set(name, id); err != nil {
   580  			if !graphdb.IsNonUniqueNameError(err) {
   581  				return "", err
   582  			}
   583  			continue
   584  		}
   585  		return name, nil
   586  	}
   587  
   588  	name = "/" + common.TruncateID(id)
   589  	if _, err := daemon.containerGraph.Set(name, id); err != nil {
   590  		return "", err
   591  	}
   592  	return name, nil
   593  }
   594  
   595  func (daemon *Daemon) generateHostname(id string, config *runconfig.Config) {
   596  	// Generate default hostname
   597  	// FIXME: the lxc template no longer needs to set a default hostname
   598  	if config.Hostname == "" {
   599  		config.Hostname = id[:12]
   600  	}
   601  }
   602  
   603  func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint, configCmd []string) (string, []string) {
   604  	var (
   605  		entrypoint string
   606  		args       []string
   607  	)
   608  	if len(configEntrypoint) != 0 {
   609  		entrypoint = configEntrypoint[0]
   610  		args = append(configEntrypoint[1:], configCmd...)
   611  	} else {
   612  		entrypoint = configCmd[0]
   613  		args = configCmd[1:]
   614  	}
   615  	return entrypoint, args
   616  }
   617  
   618  func parseSecurityOpt(container *Container, config *runconfig.HostConfig) error {
   619  	var (
   620  		labelOpts []string
   621  		err       error
   622  	)
   623  
   624  	for _, opt := range config.SecurityOpt {
   625  		con := strings.SplitN(opt, ":", 2)
   626  		if len(con) == 1 {
   627  			return fmt.Errorf("Invalid --security-opt: %q", opt)
   628  		}
   629  		switch con[0] {
   630  		case "label":
   631  			labelOpts = append(labelOpts, con[1])
   632  		case "apparmor":
   633  			container.AppArmorProfile = con[1]
   634  		default:
   635  			return fmt.Errorf("Invalid --security-opt: %q", opt)
   636  		}
   637  	}
   638  
   639  	container.ProcessLabel, container.MountLabel, err = label.InitLabels(labelOpts)
   640  	return err
   641  }
   642  
   643  func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID string) (*Container, error) {
   644  	var (
   645  		id  string
   646  		err error
   647  	)
   648  	id, name, err = daemon.generateIdAndName(name)
   649  	if err != nil {
   650  		return nil, err
   651  	}
   652  
   653  	daemon.generateHostname(id, config)
   654  	entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
   655  
   656  	container := &Container{
   657  		// FIXME: we should generate the ID here instead of receiving it as an argument
   658  		ID:              id,
   659  		Created:         time.Now().UTC(),
   660  		Path:            entrypoint,
   661  		Args:            args, //FIXME: de-duplicate from config
   662  		Config:          config,
   663  		hostConfig:      &runconfig.HostConfig{},
   664  		ImageID:         imgID,
   665  		NetworkSettings: &NetworkSettings{},
   666  		Name:            name,
   667  		Driver:          daemon.driver.String(),
   668  		ExecDriver:      daemon.execDriver.Name(),
   669  		State:           NewState(),
   670  		execCommands:    newExecStore(),
   671  	}
   672  	container.root = daemon.containerRoot(container.ID)
   673  	return container, err
   674  }
   675  
   676  func (daemon *Daemon) createRootfs(container *Container) error {
   677  	// Step 1: create the container directory.
   678  	// This doubles as a barrier to avoid race conditions.
   679  	if err := os.Mkdir(container.root, 0700); err != nil {
   680  		return err
   681  	}
   682  	initID := fmt.Sprintf("%s-init", container.ID)
   683  	if err := daemon.driver.Create(initID, container.ImageID); err != nil {
   684  		return err
   685  	}
   686  	initPath, err := daemon.driver.Get(initID, "")
   687  	if err != nil {
   688  		return err
   689  	}
   690  	defer daemon.driver.Put(initID)
   691  
   692  	if err := graph.SetupInitLayer(initPath); err != nil {
   693  		return err
   694  	}
   695  
   696  	if err := daemon.driver.Create(container.ID, initID); err != nil {
   697  		return err
   698  	}
   699  	return nil
   700  }
   701  
   702  func GetFullContainerName(name string) (string, error) {
   703  	if name == "" {
   704  		return "", fmt.Errorf("Container name cannot be empty")
   705  	}
   706  	if name[0] != '/' {
   707  		name = "/" + name
   708  	}
   709  	return name, nil
   710  }
   711  
   712  func (daemon *Daemon) GetByName(name string) (*Container, error) {
   713  	fullName, err := GetFullContainerName(name)
   714  	if err != nil {
   715  		return nil, err
   716  	}
   717  	entity := daemon.containerGraph.Get(fullName)
   718  	if entity == nil {
   719  		return nil, fmt.Errorf("Could not find entity for %s", name)
   720  	}
   721  	e := daemon.containers.Get(entity.ID())
   722  	if e == nil {
   723  		return nil, fmt.Errorf("Could not find container for entity id %s", entity.ID())
   724  	}
   725  	return e, nil
   726  }
   727  
   728  func (daemon *Daemon) Children(name string) (map[string]*Container, error) {
   729  	name, err := GetFullContainerName(name)
   730  	if err != nil {
   731  		return nil, err
   732  	}
   733  	children := make(map[string]*Container)
   734  
   735  	err = daemon.containerGraph.Walk(name, func(p string, e *graphdb.Entity) error {
   736  		c, err := daemon.Get(e.ID())
   737  		if err != nil {
   738  			return err
   739  		}
   740  		children[p] = c
   741  		return nil
   742  	}, 0)
   743  
   744  	if err != nil {
   745  		return nil, err
   746  	}
   747  	return children, nil
   748  }
   749  
   750  func (daemon *Daemon) Parents(name string) ([]string, error) {
   751  	name, err := GetFullContainerName(name)
   752  	if err != nil {
   753  		return nil, err
   754  	}
   755  
   756  	return daemon.containerGraph.Parents(name)
   757  }
   758  
   759  func (daemon *Daemon) RegisterLink(parent, child *Container, alias string) error {
   760  	fullName := path.Join(parent.Name, alias)
   761  	if !daemon.containerGraph.Exists(fullName) {
   762  		_, err := daemon.containerGraph.Set(fullName, child.ID)
   763  		return err
   764  	}
   765  	return nil
   766  }
   767  
   768  func (daemon *Daemon) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
   769  	if hostConfig != nil && hostConfig.Links != nil {
   770  		for _, l := range hostConfig.Links {
   771  			parts, err := parsers.PartParser("name:alias", l)
   772  			if err != nil {
   773  				return err
   774  			}
   775  			child, err := daemon.Get(parts["name"])
   776  			if err != nil {
   777  				//An error from daemon.Get() means this name could not be found
   778  				return fmt.Errorf("Could not get container for %s", parts["name"])
   779  			}
   780  			for child.hostConfig.NetworkMode.IsContainer() {
   781  				parts := strings.SplitN(string(child.hostConfig.NetworkMode), ":", 2)
   782  				child, err = daemon.Get(parts[1])
   783  				if err != nil {
   784  					return fmt.Errorf("Could not get container for %s", parts[1])
   785  				}
   786  			}
   787  			if child.hostConfig.NetworkMode.IsHost() {
   788  				return runconfig.ErrConflictHostNetworkAndLinks
   789  			}
   790  			if err := daemon.RegisterLink(container, child, parts["alias"]); err != nil {
   791  				return err
   792  			}
   793  		}
   794  
   795  		// After we load all the links into the daemon
   796  		// set them to nil on the hostconfig
   797  		hostConfig.Links = nil
   798  		if err := container.WriteHostConfig(); err != nil {
   799  			return err
   800  		}
   801  	}
   802  	return nil
   803  }
   804  
   805  // FIXME: harmonize with NewGraph()
   806  func NewDaemon(config *Config, eng *engine.Engine) (*Daemon, error) {
   807  	daemon, err := NewDaemonFromDirectory(config, eng)
   808  	if err != nil {
   809  		return nil, err
   810  	}
   811  	return daemon, nil
   812  }
   813  
   814  func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) {
   815  	if config.Mtu == 0 {
   816  		config.Mtu = getDefaultNetworkMtu()
   817  	}
   818  	// Check for mutually incompatible config options
   819  	if config.BridgeIface != "" && config.BridgeIP != "" {
   820  		return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")
   821  	}
   822  	if !config.EnableIptables && !config.InterContainerCommunication {
   823  		return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
   824  	}
   825  	if !config.EnableIptables && config.EnableIpMasq {
   826  		config.EnableIpMasq = false
   827  	}
   828  	config.DisableNetwork = config.BridgeIface == disableNetworkBridge
   829  
   830  	// register portallocator release on shutdown
   831  	eng.OnShutdown(func() {
   832  		if err := portallocator.ReleaseAll(); err != nil {
   833  			log.Errorf("portallocator.ReleaseAll(): %s", err)
   834  		}
   835  	})
   836  	// Claim the pidfile first, to avoid any and all unexpected race conditions.
   837  	// Some of the init doesn't need a pidfile lock - but let's not try to be smart.
   838  	if config.Pidfile != "" {
   839  		if err := utils.CreatePidFile(config.Pidfile); err != nil {
   840  			return nil, err
   841  		}
   842  		eng.OnShutdown(func() {
   843  			// Always release the pidfile last, just in case
   844  			utils.RemovePidFile(config.Pidfile)
   845  		})
   846  	}
   847  
   848  	// Check that the system is supported and we have sufficient privileges
   849  	if runtime.GOOS != "linux" {
   850  		return nil, fmt.Errorf("The Docker daemon is only supported on linux")
   851  	}
   852  	if os.Geteuid() != 0 {
   853  		return nil, fmt.Errorf("The Docker daemon needs to be run as root")
   854  	}
   855  	if err := checkKernel(); err != nil {
   856  		return nil, err
   857  	}
   858  
   859  	// set up the TempDir to use a canonical path
   860  	tmp, err := utils.TempDir(config.Root)
   861  	if err != nil {
   862  		return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err)
   863  	}
   864  	realTmp, err := utils.ReadSymlinkedDirectory(tmp)
   865  	if err != nil {
   866  		return nil, fmt.Errorf("Unable to get the full path to the TempDir (%s): %s", tmp, err)
   867  	}
   868  	os.Setenv("TMPDIR", realTmp)
   869  
   870  	// get the canonical path to the Docker root directory
   871  	var realRoot string
   872  	if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
   873  		realRoot = config.Root
   874  	} else {
   875  		realRoot, err = utils.ReadSymlinkedDirectory(config.Root)
   876  		if err != nil {
   877  			return nil, fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)
   878  		}
   879  	}
   880  	config.Root = realRoot
   881  	// Create the root directory if it doesn't exists
   882  	if err := os.MkdirAll(config.Root, 0700); err != nil && !os.IsExist(err) {
   883  		return nil, err
   884  	}
   885  
   886  	// Set the default driver
   887  	graphdriver.DefaultDriver = config.GraphDriver
   888  
   889  	// Load storage driver
   890  	driver, err := graphdriver.New(config.Root, config.GraphOptions)
   891  	if err != nil {
   892  		return nil, fmt.Errorf("error intializing graphdriver: %v", err)
   893  	}
   894  	log.Debugf("Using graph driver %s", driver)
   895  	// register cleanup for graph driver
   896  	eng.OnShutdown(func() {
   897  		if err := driver.Cleanup(); err != nil {
   898  			log.Errorf("Error during graph storage driver.Cleanup(): %v", err)
   899  		}
   900  	})
   901  
   902  	if config.EnableSelinuxSupport {
   903  		if selinuxEnabled() {
   904  			// As Docker on btrfs and SELinux are incompatible at present, error on both being enabled
   905  			if driver.String() == "btrfs" {
   906  				return nil, fmt.Errorf("SELinux is not supported with the BTRFS graph driver")
   907  			}
   908  			log.Debug("SELinux enabled successfully")
   909  		} else {
   910  			log.Warn("Docker could not enable SELinux on the host system")
   911  		}
   912  	} else {
   913  		selinuxSetDisabled()
   914  	}
   915  
   916  	daemonRepo := path.Join(config.Root, "containers")
   917  
   918  	if err := os.MkdirAll(daemonRepo, 0700); err != nil && !os.IsExist(err) {
   919  		return nil, err
   920  	}
   921  
   922  	// Migrate the container if it is aufs and aufs is enabled
   923  	if err = migrateIfAufs(driver, config.Root); err != nil {
   924  		return nil, err
   925  	}
   926  
   927  	log.Debugf("Creating images graph")
   928  	g, err := graph.NewGraph(path.Join(config.Root, "graph"), driver)
   929  	if err != nil {
   930  		return nil, err
   931  	}
   932  
   933  	volumesDriver, err := graphdriver.GetDriver("vfs", config.Root, config.GraphOptions)
   934  	if err != nil {
   935  		return nil, err
   936  	}
   937  
   938  	volumes, err := volumes.NewRepository(filepath.Join(config.Root, "volumes"), volumesDriver)
   939  	if err != nil {
   940  		return nil, err
   941  	}
   942  
   943  	trustKey, err := api.LoadOrCreateTrustKey(config.TrustKeyPath)
   944  	if err != nil {
   945  		return nil, err
   946  	}
   947  
   948  	log.Debugf("Creating repository list")
   949  	repositories, err := graph.NewTagStore(path.Join(config.Root, "repositories-"+driver.String()), g, trustKey)
   950  	if err != nil {
   951  		return nil, fmt.Errorf("Couldn't create Tag store: %s", err)
   952  	}
   953  
   954  	trustDir := path.Join(config.Root, "trust")
   955  	if err := os.MkdirAll(trustDir, 0700); err != nil && !os.IsExist(err) {
   956  		return nil, err
   957  	}
   958  	t, err := trust.NewTrustStore(trustDir)
   959  	if err != nil {
   960  		return nil, fmt.Errorf("could not create trust store: %s", err)
   961  	}
   962  
   963  	if !config.DisableNetwork {
   964  		job := eng.Job("init_networkdriver")
   965  
   966  		job.SetenvBool("EnableIptables", config.EnableIptables)
   967  		job.SetenvBool("InterContainerCommunication", config.InterContainerCommunication)
   968  		job.SetenvBool("EnableIpForward", config.EnableIpForward)
   969  		job.SetenvBool("EnableIpMasq", config.EnableIpMasq)
   970  		job.SetenvBool("EnableIPv6", config.EnableIPv6)
   971  		job.Setenv("BridgeIface", config.BridgeIface)
   972  		job.Setenv("BridgeIP", config.BridgeIP)
   973  		job.Setenv("FixedCIDR", config.FixedCIDR)
   974  		job.Setenv("FixedCIDRv6", config.FixedCIDRv6)
   975  		job.Setenv("DefaultBindingIP", config.DefaultIp.String())
   976  
   977  		if err := job.Run(); err != nil {
   978  			return nil, err
   979  		}
   980  	}
   981  
   982  	graphdbPath := path.Join(config.Root, "linkgraph.db")
   983  	graph, err := graphdb.NewSqliteConn(graphdbPath)
   984  	if err != nil {
   985  		return nil, err
   986  	}
   987  	// register graph close on shutdown
   988  	eng.OnShutdown(func() {
   989  		if err := graph.Close(); err != nil {
   990  			log.Errorf("Error during container graph.Close(): %v", err)
   991  		}
   992  	})
   993  
   994  	localCopy := path.Join(config.Root, "init", fmt.Sprintf("dockerinit-%s", dockerversion.VERSION))
   995  	sysInitPath := utils.DockerInitPath(localCopy)
   996  	if sysInitPath == "" {
   997  		return nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly. See http://docs.docker.com/contributing/devenvironment for official build instructions.")
   998  	}
   999  
  1000  	if sysInitPath != localCopy {
  1001  		// When we find a suitable dockerinit binary (even if it's our local binary), we copy it into config.Root at localCopy for future use (so that the original can go away without that being a problem, for example during a package upgrade).
  1002  		if err := os.Mkdir(path.Dir(localCopy), 0700); err != nil && !os.IsExist(err) {
  1003  			return nil, err
  1004  		}
  1005  		if _, err := utils.CopyFile(sysInitPath, localCopy); err != nil {
  1006  			return nil, err
  1007  		}
  1008  		if err := os.Chmod(localCopy, 0700); err != nil {
  1009  			return nil, err
  1010  		}
  1011  		sysInitPath = localCopy
  1012  	}
  1013  
  1014  	sysInfo := sysinfo.New(false)
  1015  	const runDir = "/var/run/docker"
  1016  	ed, err := execdrivers.NewDriver(config.ExecDriver, runDir, config.Root, sysInitPath, sysInfo)
  1017  	if err != nil {
  1018  		return nil, err
  1019  	}
  1020  
  1021  	daemon := &Daemon{
  1022  		ID:               trustKey.PublicKey().KeyID(),
  1023  		repository:       daemonRepo,
  1024  		containers:       &contStore{s: make(map[string]*Container)},
  1025  		execCommands:     newExecStore(),
  1026  		graph:            g,
  1027  		repositories:     repositories,
  1028  		idIndex:          truncindex.NewTruncIndex([]string{}),
  1029  		sysInfo:          sysInfo,
  1030  		volumes:          volumes,
  1031  		config:           config,
  1032  		containerGraph:   graph,
  1033  		driver:           driver,
  1034  		sysInitPath:      sysInitPath,
  1035  		execDriver:       ed,
  1036  		eng:              eng,
  1037  		trustStore:       t,
  1038  		statsCollector:   newStatsCollector(1 * time.Second),
  1039  		defaultLogConfig: config.LogConfig,
  1040  	}
  1041  
  1042  	eng.OnShutdown(func() {
  1043  		if err := daemon.shutdown(); err != nil {
  1044  			log.Errorf("Error during daemon.shutdown(): %v", err)
  1045  		}
  1046  	})
  1047  
  1048  	if err := daemon.restore(); err != nil {
  1049  		return nil, err
  1050  	}
  1051  
  1052  	// set up filesystem watch on resolv.conf for network changes
  1053  	if err := daemon.setupResolvconfWatcher(); err != nil {
  1054  		return nil, err
  1055  	}
  1056  
  1057  	return daemon, nil
  1058  }
  1059  
  1060  func (daemon *Daemon) shutdown() error {
  1061  	group := sync.WaitGroup{}
  1062  	log.Debugf("starting clean shutdown of all containers...")
  1063  	for _, container := range daemon.List() {
  1064  		c := container
  1065  		if c.IsRunning() {
  1066  			log.Debugf("stopping %s", c.ID)
  1067  			group.Add(1)
  1068  
  1069  			go func() {
  1070  				defer group.Done()
  1071  				if err := c.KillSig(15); err != nil {
  1072  					log.Debugf("kill 15 error for %s - %s", c.ID, err)
  1073  				}
  1074  				c.WaitStop(-1 * time.Second)
  1075  				log.Debugf("container stopped %s", c.ID)
  1076  			}()
  1077  		}
  1078  	}
  1079  	group.Wait()
  1080  
  1081  	return nil
  1082  }
  1083  
  1084  func (daemon *Daemon) Mount(container *Container) error {
  1085  	dir, err := daemon.driver.Get(container.ID, container.GetMountLabel())
  1086  	if err != nil {
  1087  		return fmt.Errorf("Error getting container %s from driver %s: %s", container.ID, daemon.driver, err)
  1088  	}
  1089  	if container.basefs == "" {
  1090  		container.basefs = dir
  1091  	} else if container.basefs != dir {
  1092  		daemon.driver.Put(container.ID)
  1093  		return fmt.Errorf("Error: driver %s is returning inconsistent paths for container %s ('%s' then '%s')",
  1094  			daemon.driver, container.ID, container.basefs, dir)
  1095  	}
  1096  	return nil
  1097  }
  1098  
  1099  func (daemon *Daemon) Unmount(container *Container) error {
  1100  	daemon.driver.Put(container.ID)
  1101  	return nil
  1102  }
  1103  
  1104  func (daemon *Daemon) Changes(container *Container) ([]archive.Change, error) {
  1105  	initID := fmt.Sprintf("%s-init", container.ID)
  1106  	return daemon.driver.Changes(container.ID, initID)
  1107  }
  1108  
  1109  func (daemon *Daemon) Diff(container *Container) (archive.Archive, error) {
  1110  	initID := fmt.Sprintf("%s-init", container.ID)
  1111  	return daemon.driver.Diff(container.ID, initID)
  1112  }
  1113  
  1114  func (daemon *Daemon) Run(c *Container, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (execdriver.ExitStatus, error) {
  1115  	return daemon.execDriver.Run(c.command, pipes, startCallback)
  1116  }
  1117  
  1118  func (daemon *Daemon) Pause(c *Container) error {
  1119  	if err := daemon.execDriver.Pause(c.command); err != nil {
  1120  		return err
  1121  	}
  1122  	c.SetPaused()
  1123  	return nil
  1124  }
  1125  
  1126  func (daemon *Daemon) Unpause(c *Container) error {
  1127  	if err := daemon.execDriver.Unpause(c.command); err != nil {
  1128  		return err
  1129  	}
  1130  	c.SetUnpaused()
  1131  	return nil
  1132  }
  1133  
  1134  func (daemon *Daemon) Kill(c *Container, sig int) error {
  1135  	return daemon.execDriver.Kill(c.command, sig)
  1136  }
  1137  
  1138  func (daemon *Daemon) Stats(c *Container) (*execdriver.ResourceStats, error) {
  1139  	return daemon.execDriver.Stats(c.ID)
  1140  }
  1141  
  1142  func (daemon *Daemon) SubscribeToContainerStats(name string) (chan interface{}, error) {
  1143  	c, err := daemon.Get(name)
  1144  	if err != nil {
  1145  		return nil, err
  1146  	}
  1147  	ch := daemon.statsCollector.collect(c)
  1148  	return ch, nil
  1149  }
  1150  
  1151  func (daemon *Daemon) UnsubscribeToContainerStats(name string, ch chan interface{}) error {
  1152  	c, err := daemon.Get(name)
  1153  	if err != nil {
  1154  		return err
  1155  	}
  1156  	daemon.statsCollector.unsubscribe(c, ch)
  1157  	return nil
  1158  }
  1159  
  1160  // Nuke kills all containers then removes all content
  1161  // from the content root, including images, volumes and
  1162  // container filesystems.
  1163  // Again: this will remove your entire docker daemon!
  1164  // FIXME: this is deprecated, and only used in legacy
  1165  // tests. Please remove.
  1166  func (daemon *Daemon) Nuke() error {
  1167  	var wg sync.WaitGroup
  1168  	for _, container := range daemon.List() {
  1169  		wg.Add(1)
  1170  		go func(c *Container) {
  1171  			c.Kill()
  1172  			wg.Done()
  1173  		}(container)
  1174  	}
  1175  	wg.Wait()
  1176  
  1177  	return os.RemoveAll(daemon.config.Root)
  1178  }
  1179  
  1180  // FIXME: this is a convenience function for integration tests
  1181  // which need direct access to daemon.graph.
  1182  // Once the tests switch to using engine and jobs, this method
  1183  // can go away.
  1184  func (daemon *Daemon) Graph() *graph.Graph {
  1185  	return daemon.graph
  1186  }
  1187  
  1188  func (daemon *Daemon) Repositories() *graph.TagStore {
  1189  	return daemon.repositories
  1190  }
  1191  
  1192  func (daemon *Daemon) Config() *Config {
  1193  	return daemon.config
  1194  }
  1195  
  1196  func (daemon *Daemon) SystemConfig() *sysinfo.SysInfo {
  1197  	return daemon.sysInfo
  1198  }
  1199  
  1200  func (daemon *Daemon) SystemInitPath() string {
  1201  	return daemon.sysInitPath
  1202  }
  1203  
  1204  func (daemon *Daemon) GraphDriver() graphdriver.Driver {
  1205  	return daemon.driver
  1206  }
  1207  
  1208  func (daemon *Daemon) ExecutionDriver() execdriver.Driver {
  1209  	return daemon.execDriver
  1210  }
  1211  
  1212  func (daemon *Daemon) ContainerGraph() *graphdb.Database {
  1213  	return daemon.containerGraph
  1214  }
  1215  
  1216  func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) {
  1217  	// Retrieve all images
  1218  	images, err := daemon.Graph().Map()
  1219  	if err != nil {
  1220  		return nil, err
  1221  	}
  1222  
  1223  	// Store the tree in a map of map (map[parentId][childId])
  1224  	imageMap := make(map[string]map[string]struct{})
  1225  	for _, img := range images {
  1226  		if _, exists := imageMap[img.Parent]; !exists {
  1227  			imageMap[img.Parent] = make(map[string]struct{})
  1228  		}
  1229  		imageMap[img.Parent][img.ID] = struct{}{}
  1230  	}
  1231  
  1232  	// Loop on the children of the given image and check the config
  1233  	var match *image.Image
  1234  	for elem := range imageMap[imgID] {
  1235  		img, ok := images[elem]
  1236  		if !ok {
  1237  			return nil, fmt.Errorf("unable to find image %q", elem)
  1238  		}
  1239  		if runconfig.Compare(&img.ContainerConfig, config) {
  1240  			if match == nil || match.Created.Before(img.Created) {
  1241  				match = img
  1242  			}
  1243  		}
  1244  	}
  1245  	return match, nil
  1246  }
  1247  
  1248  func checkKernel() error {
  1249  	// Check for unsupported kernel versions
  1250  	// FIXME: it would be cleaner to not test for specific versions, but rather
  1251  	// test for specific functionalities.
  1252  	// Unfortunately we can't test for the feature "does not cause a kernel panic"
  1253  	// without actually causing a kernel panic, so we need this workaround until
  1254  	// the circumstances of pre-3.8 crashes are clearer.
  1255  	// For details see http://github.com/docker/docker/issues/407
  1256  	if k, err := kernel.GetKernelVersion(); err != nil {
  1257  		log.Warnf("%s", err)
  1258  	} else {
  1259  		if kernel.CompareKernelVersion(k, &kernel.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
  1260  			if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
  1261  				log.Warnf("You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
  1262  			}
  1263  		}
  1264  	}
  1265  	return nil
  1266  }