github.com/daaku/docker@v1.5.0/daemon/start.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/docker/docker/engine"
     9  	"github.com/docker/docker/runconfig"
    10  )
    11  
    12  func (daemon *Daemon) ContainerStart(job *engine.Job) engine.Status {
    13  	if len(job.Args) < 1 {
    14  		return job.Errorf("Usage: %s container_id", job.Name)
    15  	}
    16  	var (
    17  		name      = job.Args[0]
    18  		container = daemon.Get(name)
    19  	)
    20  
    21  	if container == nil {
    22  		return job.Errorf("No such container: %s", name)
    23  	}
    24  
    25  	if container.IsPaused() {
    26  		return job.Errorf("Cannot start a paused container, try unpause instead.")
    27  	}
    28  
    29  	if container.IsRunning() {
    30  		return job.Errorf("Container already started")
    31  	}
    32  
    33  	// If no environment was set, then no hostconfig was passed.
    34  	// This is kept for backward compatibility - hostconfig should be passed when
    35  	// creating a container, not during start.
    36  	if len(job.Environ()) > 0 {
    37  		hostConfig := runconfig.ContainerHostConfigFromJob(job)
    38  		if err := daemon.setHostConfig(container, hostConfig); err != nil {
    39  			return job.Error(err)
    40  		}
    41  	}
    42  	if err := container.Start(); err != nil {
    43  		container.LogEvent("die")
    44  		return job.Errorf("Cannot start container %s: %s", name, err)
    45  	}
    46  
    47  	return engine.StatusOK
    48  }
    49  
    50  func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.HostConfig) error {
    51  	container.Lock()
    52  	defer container.Unlock()
    53  	if err := parseSecurityOpt(container, hostConfig); err != nil {
    54  		return err
    55  	}
    56  
    57  	// FIXME: this should be handled by the volume subsystem
    58  	// Validate the HostConfig binds. Make sure that:
    59  	// the source exists
    60  	for _, bind := range hostConfig.Binds {
    61  		splitBind := strings.Split(bind, ":")
    62  		source := splitBind[0]
    63  
    64  		// ensure the source exists on the host
    65  		_, err := os.Stat(source)
    66  		if err != nil && os.IsNotExist(err) {
    67  			err = os.MkdirAll(source, 0755)
    68  			if err != nil {
    69  				return fmt.Errorf("Could not create local directory '%s' for bind mount: %s!", source, err.Error())
    70  			}
    71  		}
    72  	}
    73  	// Register any links from the host config before starting the container
    74  	if err := daemon.RegisterLinks(container, hostConfig); err != nil {
    75  		return err
    76  	}
    77  	container.hostConfig = hostConfig
    78  	container.toDisk()
    79  
    80  	return nil
    81  }