github.com/pritambaral/docker@v1.4.2-0.20150120174542-b2fe1b3dd952/daemon/daemon.go (about)

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