From 289ee90b04a2315cd36d6ff363b41c89f8ebf2aa Mon Sep 17 00:00:00 2001 From: Lei Jitang Date: Wed, 8 Jul 2015 11:15:09 +0800 Subject: [PATCH] Fix copy from a "created" container. Fixes #14420 Signed-off-by: Lei Jitang --- daemon/container.go | 9 +++++++++ integration-cli/docker_cli_cp_test.go | 17 +++++++++++++++++ pkg/fileutils/fileutils.go | 20 ++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/daemon/container.go b/daemon/container.go index 6292fd365f..a06033c890 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -23,6 +23,7 @@ import ( "github.com/docker/docker/image" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/broadcastwriter" + "github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/jsonlog" "github.com/docker/docker/pkg/mount" @@ -627,6 +628,14 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) { if err != nil { return nil, err } + var stat os.FileInfo + stat, err = os.Stat(m.Source) + if err != nil { + return nil, err + } + if err = fileutils.CreateIfNotExists(dest, stat.IsDir()); err != nil { + return nil, err + } if err = mount.Mount(m.Source, dest, "bind", "rbind,ro"); err != nil { return nil, err } diff --git a/integration-cli/docker_cli_cp_test.go b/integration-cli/docker_cli_cp_test.go index fd63bdbf2b..7bd3356b65 100644 --- a/integration-cli/docker_cli_cp_test.go +++ b/integration-cli/docker_cli_cp_test.go @@ -632,3 +632,20 @@ func (s *DockerSuite) TestCopyAndRestart(c *check.C) { c.Fatalf("expected %q but got %q", expectedMsg, msg) } } + +func (s *DockerSuite) TestCopyCreatedContainer(c *check.C) { + out, err := exec.Command(dockerBinary, "create", "--name", "test_cp", "-v", "/test", "busybox").CombinedOutput() + if err != nil { + c.Fatalf(string(out), err) + } + + tmpDir, err := ioutil.TempDir("", "test") + if err != nil { + c.Fatalf("unable to make temporary directory: %s", err) + } + defer os.RemoveAll(tmpDir) + out, err = exec.Command(dockerBinary, "cp", "test_cp:/bin/sh", tmpDir).CombinedOutput() + if err != nil { + c.Fatalf(string(out), err) + } +} diff --git a/pkg/fileutils/fileutils.go b/pkg/fileutils/fileutils.go index 8575150fe7..f5ca966249 100644 --- a/pkg/fileutils/fileutils.go +++ b/pkg/fileutils/fileutils.go @@ -167,3 +167,23 @@ func ReadSymlinkedDirectory(path string) (string, error) { } return realPath, nil } + +// CreateIfNotExists creates a file or a directory only if it does not already exist. +func CreateIfNotExists(path string, isDir bool) error { + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + if isDir { + return os.MkdirAll(path, 0755) + } + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + f, err := os.OpenFile(path, os.O_CREATE, 0755) + if err != nil { + return err + } + f.Close() + } + } + return nil +}