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