diff --git a/builder/builder.go b/builder/builder.go index 8d6c8ef3e2..ac045fe41e 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -125,7 +125,7 @@ type Docker interface { // Remove removes a container specified by `id`. Remove(id string, cfg *daemon.ContainerRmConfig) error // Commit creates a new Docker image from an existing Docker container. - Commit(*daemon.Container, *daemon.ContainerCommitConfig) (*image.Image, error) + Commit(string, *daemon.ContainerCommitConfig) (*image.Image, error) // Copy copies/extracts a source FileInfo to a destination path inside a container // specified by a container object. // TODO: make an Extract method instead of passing `decompress` diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go index 0ad257de4e..a75f768e82 100644 --- a/builder/dockerfile/builder.go +++ b/builder/dockerfile/builder.go @@ -6,7 +6,6 @@ import ( "io" "io/ioutil" "os" - "runtime" "strings" "sync" @@ -258,16 +257,6 @@ func BuildFromConfig(config *runconfig.Config, changes []string) (*runconfig.Con // Commit will create a new image from a container's changes // TODO: remove daemon, make Commit a method on *Builder ? func Commit(containerName string, d *daemon.Daemon, c *CommitConfig) (string, error) { - container, err := d.Get(containerName) - if err != nil { - return "", err - } - - // It is not possible to commit a running container on Windows - if runtime.GOOS == "windows" && container.IsRunning() { - return "", fmt.Errorf("Windows does not support commit of a running container") - } - if c.Config == nil { c.Config = &runconfig.Config{} } @@ -277,20 +266,17 @@ func Commit(containerName string, d *daemon.Daemon, c *CommitConfig) (string, er return "", err } - if err := runconfig.Merge(newConfig, container.Config); err != nil { - return "", err - } - commitCfg := &daemon.ContainerCommitConfig{ - Pause: c.Pause, - Repo: c.Repo, - Tag: c.Tag, - Author: c.Author, - Comment: c.Comment, - Config: newConfig, + Pause: c.Pause, + Repo: c.Repo, + Tag: c.Tag, + Author: c.Author, + Comment: c.Comment, + Config: newConfig, + MergeConfigs: true, } - img, err := d.Commit(container, commitCfg) + img, err := d.Commit(containerName, commitCfg) if err != nil { return "", err } diff --git a/builder/dockerfile/internals.go b/builder/dockerfile/internals.go index ab6c1cdf19..a82ad7b3d7 100644 --- a/builder/dockerfile/internals.go +++ b/builder/dockerfile/internals.go @@ -60,7 +60,6 @@ func (b *Builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin } else if hit { return nil } - container, err := b.create() if err != nil { return err @@ -73,11 +72,6 @@ func (b *Builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin defer b.docker.Unmount(container) } - container, err := b.docker.Container(id) - if err != nil { - return err - } - // Note: Actually copy the struct autoConfig := *b.runConfig autoConfig.Cmd = autoCmd @@ -89,7 +83,7 @@ func (b *Builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin } // Commit the container - image, err := b.docker.Commit(container, commitCfg) + image, err := b.docker.Commit(id, commitCfg) if err != nil { return err } diff --git a/daemon/commit.go b/daemon/commit.go index 35759a032c..61808eabce 100644 --- a/daemon/commit.go +++ b/daemon/commit.go @@ -1,6 +1,9 @@ package daemon import ( + "fmt" + "runtime" + "github.com/docker/docker/image" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/ioutils" @@ -15,17 +18,35 @@ type ContainerCommitConfig struct { Tag string Author string Comment string - Config *runconfig.Config + // merge container config into commit config before commit + MergeConfigs bool + Config *runconfig.Config } // Commit creates a new filesystem image from the current state of a container. // The image can optionally be tagged into a repository. -func (daemon *Daemon) Commit(container *Container, c *ContainerCommitConfig) (*image.Image, error) { +func (daemon *Daemon) Commit(name string, c *ContainerCommitConfig) (*image.Image, error) { + container, err := daemon.Get(name) + if err != nil { + return nil, err + } + + // It is not possible to commit a running container on Windows + if runtime.GOOS == "windows" && container.IsRunning() { + return nil, fmt.Errorf("Windows does not support commit of a running container") + } + if c.Pause && !container.isPaused() { daemon.containerPause(container) defer daemon.containerUnpause(container) } + if c.MergeConfigs { + if err := runconfig.Merge(c.Config, container.Config); err != nil { + return nil, err + } + } + rwTar, err := daemon.exportContainerRw(container) if err != nil { return nil, err diff --git a/daemon/daemonbuilder/builder.go b/daemon/daemonbuilder/builder.go index f6bbec4d67..0b5528f16f 100644 --- a/daemon/daemonbuilder/builder.go +++ b/daemon/daemonbuilder/builder.go @@ -106,8 +106,8 @@ func (d Docker) Remove(id string, cfg *daemon.ContainerRmConfig) error { } // Commit creates a new Docker image from an existing Docker container. -func (d Docker) Commit(c *daemon.Container, cfg *daemon.ContainerCommitConfig) (*image.Image, error) { - return d.Daemon.Commit(c, cfg) +func (d Docker) Commit(name string, cfg *daemon.ContainerCommitConfig) (*image.Image, error) { + return d.Daemon.Commit(name, cfg) } // Retain retains an image avoiding it to be removed or overwritten until a corresponding Release() call.