From 44369bdd6507006108f39b85b5950f933bf1380a Mon Sep 17 00:00:00 2001 From: Emil Davtyan Date: Thu, 11 Jan 2018 13:15:46 +0100 Subject: [PATCH] Wrap response errors for container copy methods. This allows IsErrNotFound and IsErrNotImplemented to work as intended. Signed-off-by: Emil Davtyan --- client/container_copy.go | 16 ++++++++-------- client/container_copy_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/client/container_copy.go b/client/container_copy.go index b7d5252ab2..6985036df8 100644 --- a/client/container_copy.go +++ b/client/container_copy.go @@ -23,7 +23,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri urlStr := "/containers/" + containerID + "/archive" response, err := cli.head(ctx, urlStr, query, nil) if err != nil { - return types.ContainerPathStat{}, err + return types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+path) } defer ensureReaderClosed(response) return getContainerPathStatFromHeader(response.header) @@ -31,9 +31,9 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri // CopyToContainer copies content into the container filesystem. // Note that `content` must be a Reader for a TAR archive -func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error { +func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options types.CopyToContainerOptions) error { query := url.Values{} - query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. + query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API. // Do not allow for an existing directory to be overwritten by a non-directory and vice versa. if !options.AllowOverwriteDirWithFile { query.Set("noOverwriteDirNonDir", "true") @@ -43,11 +43,11 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string, query.Set("copyUIDGID", "true") } - apiPath := "/containers/" + container + "/archive" + apiPath := "/containers/" + containerID + "/archive" response, err := cli.putRaw(ctx, apiPath, query, content, nil) if err != nil { - return err + return wrapResponseError(err, response, "container:path", containerID+":"+dstPath) } defer ensureReaderClosed(response) @@ -60,14 +60,14 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string, // CopyFromContainer gets the content from the container and returns it as a Reader // for a TAR archive to manipulate it in the host. It's up to the caller to close the reader. -func (cli *Client) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { +func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { query := make(url.Values, 1) query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. - apiPath := "/containers/" + container + "/archive" + apiPath := "/containers/" + containerID + "/archive" response, err := cli.get(ctx, apiPath, query, nil) if err != nil { - return nil, types.ContainerPathStat{}, err + return nil, types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+srcPath) } if response.statusCode != http.StatusOK { diff --git a/client/container_copy_test.go b/client/container_copy_test.go index c84f82e9fb..706711ece0 100644 --- a/client/container_copy_test.go +++ b/client/container_copy_test.go @@ -25,6 +25,16 @@ func TestContainerStatPathError(t *testing.T) { } } +func TestContainerStatPathNotFoundError(t *testing.T) { + client := &Client{ + client: newMockClient(errorMock(http.StatusNotFound, "Not found")), + } + _, err := client.ContainerStatPath(context.Background(), "container_id", "path") + if !IsErrNotFound(err) { + t.Fatalf("expected a not found error, got %v", err) + } +} + func TestContainerStatPathNoHeaderError(t *testing.T) { client := &Client{ client: newMockClient(func(req *http.Request) (*http.Response, error) { @@ -95,6 +105,16 @@ func TestCopyToContainerError(t *testing.T) { } } +func TestCopyToContainerNotFoundError(t *testing.T) { + client := &Client{ + client: newMockClient(errorMock(http.StatusNotFound, "Not found")), + } + err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{}) + if !IsErrNotFound(err) { + t.Fatalf("expected a not found error, got %v", err) + } +} + func TestCopyToContainerNotStatusOKError(t *testing.T) { client := &Client{ client: newMockClient(errorMock(http.StatusNoContent, "No content")), @@ -161,6 +181,16 @@ func TestCopyFromContainerError(t *testing.T) { } } +func TestCopyFromContainerNotFoundError(t *testing.T) { + client := &Client{ + client: newMockClient(errorMock(http.StatusNotFound, "Not found")), + } + _, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file") + if !IsErrNotFound(err) { + t.Fatalf("expected a not found error, got %v", err) + } +} + func TestCopyFromContainerNotStatusOKError(t *testing.T) { client := &Client{ client: newMockClient(errorMock(http.StatusNoContent, "No content")),