1
0
mirror of https://github.com/docker/cli.git synced 2026-01-23 15:21:32 +03:00
Files
cli/components/engine/daemon/create.go
Derek McGowan 6825ac1c62 Separate graph from image
Move graph related functions in image to graph package.
Consolidating graph functionality is the first step in refactoring graph into an image store model.
Subsequent refactors will involve breaking up graph into multiple types with a strongly defined interface.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Upstream-commit: 2b58b677a54950bc78c13760ef79fe6284154847
Component: engine
2015-06-05 18:06:09 -07:00

162 lines
4.4 KiB
Go

package daemon
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/docker/docker/graph"
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/runconfig"
"github.com/docker/libcontainer/label"
)
func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hostConfig *runconfig.HostConfig) (string, []string, error) {
warnings, err := daemon.verifyHostConfig(hostConfig)
if err != nil {
return "", warnings, err
}
// The check for a valid workdir path is made on the server rather than in the
// client. This is because we don't know the type of path (Linux or Windows)
// to validate on the client.
if config.WorkingDir != "" && !filepath.IsAbs(config.WorkingDir) {
return "", warnings, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path.", config.WorkingDir)
}
container, buildWarnings, err := daemon.Create(config, hostConfig, name)
if err != nil {
if daemon.Graph().IsNotExist(err, config.Image) {
_, tag := parsers.ParseRepositoryTag(config.Image)
if tag == "" {
tag = graph.DEFAULTTAG
}
return "", warnings, fmt.Errorf("No such image: %s (tag: %s)", config.Image, tag)
}
return "", warnings, err
}
warnings = append(warnings, buildWarnings...)
return container.ID, warnings, nil
}
// Create creates a new container from the given configuration with a given name.
func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.HostConfig, name string) (*Container, []string, error) {
var (
container *Container
warnings []string
img *image.Image
imgID string
err error
)
if config.Image != "" {
img, err = daemon.repositories.LookupImage(config.Image)
if err != nil {
return nil, nil, err
}
if err = daemon.graph.CheckDepth(img); err != nil {
return nil, nil, err
}
imgID = img.ID
}
if err := daemon.mergeAndVerifyConfig(config, img); err != nil {
return nil, nil, err
}
if !config.NetworkDisabled && daemon.SystemConfig().IPv4ForwardingDisabled {
warnings = append(warnings, "IPv4 forwarding is disabled.")
}
if hostConfig == nil {
hostConfig = &runconfig.HostConfig{}
}
if hostConfig.SecurityOpt == nil {
hostConfig.SecurityOpt, err = daemon.GenerateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode)
if err != nil {
return nil, nil, err
}
}
if container, err = daemon.newContainer(name, config, imgID); err != nil {
return nil, nil, err
}
if err := daemon.Register(container); err != nil {
return nil, nil, err
}
if err := daemon.createRootfs(container); err != nil {
return nil, nil, err
}
if err := daemon.setHostConfig(container, hostConfig); err != nil {
return nil, nil, err
}
if err := container.Mount(); err != nil {
return nil, nil, err
}
defer container.Unmount()
for spec := range config.Volumes {
var (
name, destination string
parts = strings.Split(spec, ":")
)
switch len(parts) {
case 2:
name, destination = parts[0], filepath.Clean(parts[1])
default:
name = stringid.GenerateRandomID()
destination = filepath.Clean(parts[0])
}
// Skip volumes for which we already have something mounted on that
// destination because of a --volume-from.
if container.isDestinationMounted(destination) {
continue
}
path, err := container.GetResourcePath(destination)
if err != nil {
return nil, nil, err
}
stat, err := os.Stat(path)
if err == nil && !stat.IsDir() {
return nil, nil, fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
}
v, err := createVolume(name, config.VolumeDriver)
if err != nil {
return nil, nil, err
}
if err := label.Relabel(v.Path(), container.MountLabel, "z"); err != nil {
return nil, nil, err
}
if err := container.copyImagePathContent(v, destination); err != nil {
return nil, nil, err
}
container.addMountPointWithVolume(destination, v, true)
}
if err := container.ToDisk(); err != nil {
return nil, nil, err
}
container.LogEvent("create")
return container, warnings, nil
}
func (daemon *Daemon) GenerateSecurityOpt(ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) {
if ipcMode.IsHost() || pidMode.IsHost() {
return label.DisableSecOpt(), nil
}
if ipcContainer := ipcMode.Container(); ipcContainer != "" {
c, err := daemon.Get(ipcContainer)
if err != nil {
return nil, err
}
return label.DupSecOpt(c.ProcessLabel), nil
}
return nil, nil
}