Browse code

Wrap response errors for container copy methods.

This allows IsErrNotFound and IsErrNotImplemented to work as intended.

Signed-off-by: Emil Davtyan <emil2k@gmail.com>

Emil Davtyan authored on 2018/01/11 21:15:46
Showing 2 changed files
... ...
@@ -23,7 +23,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
23 23
 	urlStr := "/containers/" + containerID + "/archive"
24 24
 	response, err := cli.head(ctx, urlStr, query, nil)
25 25
 	if err != nil {
26
-		return types.ContainerPathStat{}, err
26
+		return types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+path)
27 27
 	}
28 28
 	defer ensureReaderClosed(response)
29 29
 	return getContainerPathStatFromHeader(response.header)
... ...
@@ -31,9 +31,9 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
31 31
 
32 32
 // CopyToContainer copies content into the container filesystem.
33 33
 // Note that `content` must be a Reader for a TAR archive
34
-func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error {
34
+func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options types.CopyToContainerOptions) error {
35 35
 	query := url.Values{}
36
-	query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
36
+	query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API.
37 37
 	// Do not allow for an existing directory to be overwritten by a non-directory and vice versa.
38 38
 	if !options.AllowOverwriteDirWithFile {
39 39
 		query.Set("noOverwriteDirNonDir", "true")
... ...
@@ -43,11 +43,11 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string,
43 43
 		query.Set("copyUIDGID", "true")
44 44
 	}
45 45
 
46
-	apiPath := "/containers/" + container + "/archive"
46
+	apiPath := "/containers/" + containerID + "/archive"
47 47
 
48 48
 	response, err := cli.putRaw(ctx, apiPath, query, content, nil)
49 49
 	if err != nil {
50
-		return err
50
+		return wrapResponseError(err, response, "container:path", containerID+":"+dstPath)
51 51
 	}
52 52
 	defer ensureReaderClosed(response)
53 53
 
... ...
@@ -60,14 +60,14 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string,
60 60
 
61 61
 // CopyFromContainer gets the content from the container and returns it as a Reader
62 62
 // for a TAR archive to manipulate it in the host. It's up to the caller to close the reader.
63
-func (cli *Client) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
63
+func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
64 64
 	query := make(url.Values, 1)
65 65
 	query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.
66 66
 
67
-	apiPath := "/containers/" + container + "/archive"
67
+	apiPath := "/containers/" + containerID + "/archive"
68 68
 	response, err := cli.get(ctx, apiPath, query, nil)
69 69
 	if err != nil {
70
-		return nil, types.ContainerPathStat{}, err
70
+		return nil, types.ContainerPathStat{}, wrapResponseError(err, response, "container:path", containerID+":"+srcPath)
71 71
 	}
72 72
 
73 73
 	if response.statusCode != http.StatusOK {
... ...
@@ -25,6 +25,16 @@ func TestContainerStatPathError(t *testing.T) {
25 25
 	}
26 26
 }
27 27
 
28
+func TestContainerStatPathNotFoundError(t *testing.T) {
29
+	client := &Client{
30
+		client: newMockClient(errorMock(http.StatusNotFound, "Not found")),
31
+	}
32
+	_, err := client.ContainerStatPath(context.Background(), "container_id", "path")
33
+	if !IsErrNotFound(err) {
34
+		t.Fatalf("expected a not found error, got %v", err)
35
+	}
36
+}
37
+
28 38
 func TestContainerStatPathNoHeaderError(t *testing.T) {
29 39
 	client := &Client{
30 40
 		client: newMockClient(func(req *http.Request) (*http.Response, error) {
... ...
@@ -95,6 +105,16 @@ func TestCopyToContainerError(t *testing.T) {
95 95
 	}
96 96
 }
97 97
 
98
+func TestCopyToContainerNotFoundError(t *testing.T) {
99
+	client := &Client{
100
+		client: newMockClient(errorMock(http.StatusNotFound, "Not found")),
101
+	}
102
+	err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
103
+	if !IsErrNotFound(err) {
104
+		t.Fatalf("expected a not found error, got %v", err)
105
+	}
106
+}
107
+
98 108
 func TestCopyToContainerNotStatusOKError(t *testing.T) {
99 109
 	client := &Client{
100 110
 		client: newMockClient(errorMock(http.StatusNoContent, "No content")),
... ...
@@ -161,6 +181,16 @@ func TestCopyFromContainerError(t *testing.T) {
161 161
 	}
162 162
 }
163 163
 
164
+func TestCopyFromContainerNotFoundError(t *testing.T) {
165
+	client := &Client{
166
+		client: newMockClient(errorMock(http.StatusNotFound, "Not found")),
167
+	}
168
+	_, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
169
+	if !IsErrNotFound(err) {
170
+		t.Fatalf("expected a not found error, got %v", err)
171
+	}
172
+}
173
+
164 174
 func TestCopyFromContainerNotStatusOKError(t *testing.T) {
165 175
 	client := &Client{
166 176
 		client: newMockClient(errorMock(http.StatusNoContent, "No content")),