github.com/clcy1243/docker@v1.6.0-rc3/daemon/create.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/docker/docker/engine"
     8  	"github.com/docker/docker/graph"
     9  	"github.com/docker/docker/image"
    10  	"github.com/docker/docker/pkg/parsers"
    11  	"github.com/docker/docker/runconfig"
    12  	"github.com/docker/libcontainer/label"
    13  )
    14  
    15  func (daemon *Daemon) ContainerCreate(job *engine.Job) engine.Status {
    16  	var name string
    17  	if len(job.Args) == 1 {
    18  		name = job.Args[0]
    19  	} else if len(job.Args) > 1 {
    20  		return job.Errorf("Usage: %s", job.Name)
    21  	}
    22  
    23  	config := runconfig.ContainerConfigFromJob(job)
    24  	hostConfig := runconfig.ContainerHostConfigFromJob(job)
    25  
    26  	if len(hostConfig.LxcConf) > 0 && !strings.Contains(daemon.ExecutionDriver().Name(), "lxc") {
    27  		return job.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver().Name())
    28  	}
    29  	if hostConfig.Memory != 0 && hostConfig.Memory < 4194304 {
    30  		return job.Errorf("Minimum memory limit allowed is 4MB")
    31  	}
    32  	if hostConfig.Memory > 0 && !daemon.SystemConfig().MemoryLimit {
    33  		job.Errorf("Your kernel does not support memory limit capabilities. Limitation discarded.\n")
    34  		hostConfig.Memory = 0
    35  	}
    36  	if hostConfig.Memory > 0 && hostConfig.MemorySwap != -1 && !daemon.SystemConfig().SwapLimit {
    37  		job.Errorf("Your kernel does not support swap limit capabilities. Limitation discarded.\n")
    38  		hostConfig.MemorySwap = -1
    39  	}
    40  	if hostConfig.Memory > 0 && hostConfig.MemorySwap > 0 && hostConfig.MemorySwap < hostConfig.Memory {
    41  		return job.Errorf("Minimum memoryswap limit should be larger than memory limit, see usage.\n")
    42  	}
    43  	if hostConfig.Memory == 0 && hostConfig.MemorySwap > 0 {
    44  		return job.Errorf("You should always set the Memory limit when using Memoryswap limit, see usage.\n")
    45  	}
    46  
    47  	container, buildWarnings, err := daemon.Create(config, hostConfig, name)
    48  	if err != nil {
    49  		if daemon.Graph().IsNotExist(err) {
    50  			_, tag := parsers.ParseRepositoryTag(config.Image)
    51  			if tag == "" {
    52  				tag = graph.DEFAULTTAG
    53  			}
    54  			return job.Errorf("No such image: %s (tag: %s)", config.Image, tag)
    55  		}
    56  		return job.Error(err)
    57  	}
    58  	if !container.Config.NetworkDisabled && daemon.SystemConfig().IPv4ForwardingDisabled {
    59  		job.Errorf("IPv4 forwarding is disabled.\n")
    60  	}
    61  	container.LogEvent("create")
    62  
    63  	job.Printf("%s\n", container.ID)
    64  
    65  	for _, warning := range buildWarnings {
    66  		job.Errorf("%s\n", warning)
    67  	}
    68  
    69  	return engine.StatusOK
    70  }
    71  
    72  // Create creates a new container from the given configuration with a given name.
    73  func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.HostConfig, name string) (*Container, []string, error) {
    74  	var (
    75  		container *Container
    76  		warnings  []string
    77  		img       *image.Image
    78  		imgID     string
    79  		err       error
    80  	)
    81  
    82  	if config.Image != "" {
    83  		img, err = daemon.repositories.LookupImage(config.Image)
    84  		if err != nil {
    85  			return nil, nil, err
    86  		}
    87  		if err = img.CheckDepth(); err != nil {
    88  			return nil, nil, err
    89  		}
    90  		imgID = img.ID
    91  	}
    92  
    93  	if warnings, err = daemon.mergeAndVerifyConfig(config, img); err != nil {
    94  		return nil, nil, err
    95  	}
    96  	if hostConfig == nil {
    97  		hostConfig = &runconfig.HostConfig{}
    98  	}
    99  	if hostConfig.SecurityOpt == nil {
   100  		hostConfig.SecurityOpt, err = daemon.GenerateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode)
   101  		if err != nil {
   102  			return nil, nil, err
   103  		}
   104  	}
   105  	if container, err = daemon.newContainer(name, config, imgID); err != nil {
   106  		return nil, nil, err
   107  	}
   108  	if err := daemon.Register(container); err != nil {
   109  		return nil, nil, err
   110  	}
   111  	if err := daemon.createRootfs(container); err != nil {
   112  		return nil, nil, err
   113  	}
   114  	if hostConfig != nil {
   115  		if err := daemon.setHostConfig(container, hostConfig); err != nil {
   116  			return nil, nil, err
   117  		}
   118  	}
   119  	if err := container.Mount(); err != nil {
   120  		return nil, nil, err
   121  	}
   122  	defer container.Unmount()
   123  	if err := container.prepareVolumes(); err != nil {
   124  		return nil, nil, err
   125  	}
   126  	if err := container.ToDisk(); err != nil {
   127  		return nil, nil, err
   128  	}
   129  	return container, warnings, nil
   130  }
   131  
   132  func (daemon *Daemon) GenerateSecurityOpt(ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) {
   133  	if ipcMode.IsHost() || pidMode.IsHost() {
   134  		return label.DisableSecOpt(), nil
   135  	}
   136  	if ipcContainer := ipcMode.Container(); ipcContainer != "" {
   137  		c, err := daemon.Get(ipcContainer)
   138  		if err != nil {
   139  			return nil, err
   140  		}
   141  		if !c.IsRunning() {
   142  			return nil, fmt.Errorf("cannot join IPC of a non running container: %s", ipcContainer)
   143  		}
   144  
   145  		return label.DupSecOpt(c.ProcessLabel), nil
   146  	}
   147  	return nil, nil
   148  }