зеркало из https://github.com/microsoft/docker.git
Move init volumes code to func
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Родитель
b466672a4c
Коммит
e454be7567
|
@ -607,15 +607,18 @@ func (daemon *Daemon) Commit(container *Container, repository, tag, comment, aut
|
|||
containerID, containerImage string
|
||||
containerConfig *runconfig.Config
|
||||
)
|
||||
|
||||
if container != nil {
|
||||
containerID = container.ID
|
||||
containerImage = container.Image
|
||||
containerConfig = container.Config
|
||||
}
|
||||
|
||||
img, err := daemon.graph.Create(rwTar, containerID, containerImage, comment, author, containerConfig, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Register the image if needed
|
||||
if repository != "" {
|
||||
if err := daemon.repositories.Set(repository, tag, img.ID, true); err != nil {
|
||||
|
|
|
@ -162,114 +162,10 @@ func createVolumes(container *Container) error {
|
|||
return err
|
||||
}
|
||||
|
||||
volumesDriver := container.daemon.volumes.Driver()
|
||||
// Create the requested volumes if they don't exist
|
||||
for volPath := range container.Config.Volumes {
|
||||
volPath = filepath.Clean(volPath)
|
||||
volIsDir := true
|
||||
// Skip existing volumes
|
||||
if _, exists := container.Volumes[volPath]; exists {
|
||||
continue
|
||||
}
|
||||
var srcPath string
|
||||
var isBindMount bool
|
||||
srcRW := false
|
||||
// If an external bind is defined for this volume, use that as a source
|
||||
if bindMap, exists := binds[volPath]; exists {
|
||||
isBindMount = true
|
||||
srcPath = bindMap.SrcPath
|
||||
if !filepath.IsAbs(srcPath) {
|
||||
return fmt.Errorf("%s must be an absolute path", srcPath)
|
||||
}
|
||||
if strings.ToLower(bindMap.Mode) == "rw" {
|
||||
srcRW = true
|
||||
}
|
||||
if stat, err := os.Stat(bindMap.SrcPath); err != nil {
|
||||
return err
|
||||
} else {
|
||||
volIsDir = stat.IsDir()
|
||||
}
|
||||
// Otherwise create an directory in $ROOT/volumes/ and use that
|
||||
} else {
|
||||
|
||||
// Do not pass a container as the parameter for the volume creation.
|
||||
// The graph driver using the container's information ( Image ) to
|
||||
// create the parent.
|
||||
c, err := container.daemon.volumes.Create(nil, "", "", "", "", nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srcPath, err = volumesDriver.Get(c.ID, "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Driver %s failed to get volume rootfs %s: %s", volumesDriver, c.ID, err)
|
||||
}
|
||||
srcRW = true // RW by default
|
||||
}
|
||||
|
||||
if p, err := filepath.EvalSymlinks(srcPath); err != nil {
|
||||
if err := initializeVolume(container, volPath, binds); err != nil {
|
||||
return err
|
||||
} else {
|
||||
srcPath = p
|
||||
}
|
||||
|
||||
// Create the mountpoint
|
||||
rootVolPath, err := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, volPath), container.basefs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newVolPath, err := filepath.Rel(container.basefs, rootVolPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newVolPath = "/" + newVolPath
|
||||
|
||||
if volPath != newVolPath {
|
||||
delete(container.Volumes, volPath)
|
||||
delete(container.VolumesRW, volPath)
|
||||
}
|
||||
|
||||
container.Volumes[newVolPath] = srcPath
|
||||
container.VolumesRW[newVolPath] = srcRW
|
||||
|
||||
if err := createIfNotExists(rootVolPath, volIsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Do not copy or change permissions if we are mounting from the host
|
||||
if srcRW && !isBindMount {
|
||||
volList, err := ioutil.ReadDir(rootVolPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(volList) > 0 {
|
||||
srcList, err := ioutil.ReadDir(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(srcList) == 0 {
|
||||
// If the source volume is empty copy files from the root into the volume
|
||||
if err := archive.CopyWithTar(rootVolPath, srcPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stat syscall.Stat_t
|
||||
if err := syscall.Stat(rootVolPath, &stat); err != nil {
|
||||
return err
|
||||
}
|
||||
var srcStat syscall.Stat_t
|
||||
if err := syscall.Stat(srcPath, &srcStat); err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the source volume's ownership if it differs from the root
|
||||
// files that were just copied
|
||||
if stat.Uid != srcStat.Uid || stat.Gid != srcStat.Gid {
|
||||
if err := os.Chown(srcPath, int(stat.Uid), int(stat.Gid)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -296,3 +192,119 @@ func createIfNotExists(path string, isDir bool) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initializeVolume(container *Container, volPath string, binds map[string]BindMap) error {
|
||||
volumesDriver := container.daemon.volumes.Driver()
|
||||
volPath = filepath.Clean(volPath)
|
||||
// Skip existing volumes
|
||||
if _, exists := container.Volumes[volPath]; exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
srcPath string
|
||||
isBindMount bool
|
||||
volIsDir = true
|
||||
|
||||
srcRW = false
|
||||
)
|
||||
|
||||
// If an external bind is defined for this volume, use that as a source
|
||||
if bindMap, exists := binds[volPath]; exists {
|
||||
isBindMount = true
|
||||
srcPath = bindMap.SrcPath
|
||||
if !filepath.IsAbs(srcPath) {
|
||||
return fmt.Errorf("%s must be an absolute path", srcPath)
|
||||
}
|
||||
if strings.ToLower(bindMap.Mode) == "rw" {
|
||||
srcRW = true
|
||||
}
|
||||
if stat, err := os.Stat(bindMap.SrcPath); err != nil {
|
||||
return err
|
||||
} else {
|
||||
volIsDir = stat.IsDir()
|
||||
}
|
||||
// Otherwise create an directory in $ROOT/volumes/ and use that
|
||||
} else {
|
||||
|
||||
// Do not pass a container as the parameter for the volume creation.
|
||||
// The graph driver using the container's information ( Image ) to
|
||||
// create the parent.
|
||||
c, err := container.daemon.volumes.Create(nil, "", "", "", "", nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srcPath, err = volumesDriver.Get(c.ID, "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Driver %s failed to get volume rootfs %s: %s", volumesDriver, c.ID, err)
|
||||
}
|
||||
srcRW = true // RW by default
|
||||
}
|
||||
|
||||
if p, err := filepath.EvalSymlinks(srcPath); err != nil {
|
||||
return err
|
||||
} else {
|
||||
srcPath = p
|
||||
}
|
||||
|
||||
// Create the mountpoint
|
||||
rootVolPath, err := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, volPath), container.basefs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newVolPath, err := filepath.Rel(container.basefs, rootVolPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newVolPath = "/" + newVolPath
|
||||
|
||||
if volPath != newVolPath {
|
||||
delete(container.Volumes, volPath)
|
||||
delete(container.VolumesRW, volPath)
|
||||
}
|
||||
|
||||
container.Volumes[newVolPath] = srcPath
|
||||
container.VolumesRW[newVolPath] = srcRW
|
||||
|
||||
if err := createIfNotExists(rootVolPath, volIsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Do not copy or change permissions if we are mounting from the host
|
||||
if srcRW && !isBindMount {
|
||||
volList, err := ioutil.ReadDir(rootVolPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(volList) > 0 {
|
||||
srcList, err := ioutil.ReadDir(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(srcList) == 0 {
|
||||
// If the source volume is empty copy files from the root into the volume
|
||||
if err := archive.CopyWithTar(rootVolPath, srcPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stat syscall.Stat_t
|
||||
if err := syscall.Stat(rootVolPath, &stat); err != nil {
|
||||
return err
|
||||
}
|
||||
var srcStat syscall.Stat_t
|
||||
if err := syscall.Stat(srcPath, &srcStat); err != nil {
|
||||
return err
|
||||
}
|
||||
// Change the source volume's ownership if it differs from the root
|
||||
// files that were just copied
|
||||
if stat.Uid != srcStat.Uid || stat.Gid != srcStat.Gid {
|
||||
if err := os.Chown(srcPath, int(stat.Uid), int(stat.Gid)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,12 +2,6 @@ package graph
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/archive"
|
||||
"github.com/dotcloud/docker/daemon/graphdriver"
|
||||
"github.com/dotcloud/docker/dockerversion"
|
||||
"github.com/dotcloud/docker/image"
|
||||
"github.com/dotcloud/docker/runconfig"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -17,6 +11,13 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/dotcloud/docker/archive"
|
||||
"github.com/dotcloud/docker/daemon/graphdriver"
|
||||
"github.com/dotcloud/docker/dockerversion"
|
||||
"github.com/dotcloud/docker/image"
|
||||
"github.com/dotcloud/docker/runconfig"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
)
|
||||
|
||||
// A Graph is a store for versioned filesystem images and the relationship between them.
|
||||
|
@ -141,11 +142,13 @@ func (graph *Graph) Create(layerData archive.ArchiveReader, containerID, contain
|
|||
Architecture: runtime.GOARCH,
|
||||
OS: runtime.GOOS,
|
||||
}
|
||||
|
||||
if containerID != "" {
|
||||
img.Parent = containerImage
|
||||
img.Container = containerID
|
||||
img.ContainerConfig = *containerConfig
|
||||
}
|
||||
|
||||
if err := graph.Register(nil, layerData, img); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package runconfig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/dotcloud/docker/nat"
|
||||
"github.com/dotcloud/docker/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Merge(userConf, imageConf *Config) error {
|
||||
|
@ -82,6 +83,7 @@ func Merge(userConf, imageConf *Config) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if userConf.Cmd == nil || len(userConf.Cmd) == 0 {
|
||||
userConf.Cmd = imageConf.Cmd
|
||||
}
|
||||
|
|
|
@ -1050,8 +1050,12 @@ func (srv *Server) ContainerCommit(job *engine.Job) engine.Status {
|
|||
if container == nil {
|
||||
return job.Errorf("No such container: %s", name)
|
||||
}
|
||||
var config = container.Config
|
||||
var newConfig runconfig.Config
|
||||
|
||||
var (
|
||||
config = container.Config
|
||||
newConfig runconfig.Config
|
||||
)
|
||||
|
||||
if err := job.GetenvJson("config", &newConfig); err != nil {
|
||||
return job.Error(err)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче