diff --git a/api.go b/api.go index f9257b1cc..46fe8251e 100644 --- a/api.go +++ b/api.go @@ -878,23 +878,24 @@ func postContainersCopy(srv *Server, version float64, w http.ResponseWriter, r * name := vars["name"] copyData := &APICopy{} - if r.Header.Get("Content-Type") == "application/json" { + contentType := r.Header.Get("Content-Type") + if contentType == "application/json" { if err := json.NewDecoder(r.Body).Decode(copyData); err != nil { return err } } else { - return fmt.Errorf("Content-Type not supported: %s", r.Header.Get("Content-Type")) + return fmt.Errorf("Content-Type not supported: %s", contentType) } if copyData.Resource == "" { return fmt.Errorf("Resource cannot be empty") } if copyData.Resource[0] == '/' { - return fmt.Errorf("Resource cannot contain a leading /") + copyData.Resource = copyData.Resource[1:] } if err := srv.ContainerCopy(name, copyData.Resource, w); err != nil { - utils.Debugf("%s", err) + utils.Debugf("%s", err.Error()) return err } return nil diff --git a/api_test.go b/api_test.go index 52baf35f3..928daf963 100644 --- a/api_test.go +++ b/api_test.go @@ -1181,7 +1181,7 @@ func TestPostContainersCopy(t *testing.T) { } r := httptest.NewRecorder() - copyData := APICopy{HostPath: ".", Resource: "test.txt"} + copyData := APICopy{HostPath: ".", Resource: "/test.txt"} jsonData, err := json.Marshal(copyData) if err != nil { diff --git a/commands.go b/commands.go index eb05202de..d4cf91ea1 100644 --- a/commands.go +++ b/commands.go @@ -1492,8 +1492,8 @@ func (cli *DockerCli) CmdCp(args ...string) error { return err } - r := bytes.NewReader(data) if statusCode == 200 { + r := bytes.NewReader(data) if err := Untar(r, copyData.HostPath); err != nil { return err } diff --git a/container.go b/container.go index 7791d4b4a..6a60597ed 100644 --- a/container.go +++ b/container.go @@ -1094,5 +1094,19 @@ func (container *Container) Copy(resource string) (Archive, error) { if err := container.EnsureMounted(); err != nil { return nil, err } - return TarFilter(container.RootfsPath(), Uncompressed, []string{resource}) + var filter []string + basePath := path.Join(container.RootfsPath(), resource) + stat, err := os.Stat(basePath) + if err != nil { + return nil, err + } + if !stat.IsDir() { + d, f := path.Split(basePath) + basePath = d + filter = []string{f} + } else { + filter = []string{path.Base(basePath)} + basePath = path.Dir(basePath) + } + return TarFilter(basePath, Uncompressed, filter) }