github.com/grange74/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 }