github.com/microsoft/docker@v1.5.0-rc2/daemon/create.go (about)

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