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