Browse code

Deprecate /containers/(id or name)/copy endpoint

This endpoint has been deprecated since 1.8. Return an error starting
from this API version (1.24) in order to make sure it's not used for the
next API version and so that we can remove it some times later.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2016/06/04 02:38:03
Showing 6 changed files
... ...
@@ -62,7 +62,7 @@ func (r *containerRouter) initRoutes() {
62 62
 		router.NewPostRoute("/containers/{name:.*}/wait", r.postContainersWait),
63 63
 		router.NewPostRoute("/containers/{name:.*}/resize", r.postContainersResize),
64 64
 		router.NewPostRoute("/containers/{name:.*}/attach", r.postContainersAttach),
65
-		router.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy),
65
+		router.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy), // Deprecated since 1.8, Errors out since 1.12
66 66
 		router.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate),
67 67
 		router.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart),
68 68
 		router.NewPostRoute("/exec/{name:.*}/resize", r.postContainerExecResize),
... ...
@@ -11,11 +11,18 @@ import (
11 11
 
12 12
 	"github.com/docker/docker/api/server/httputils"
13 13
 	"github.com/docker/engine-api/types"
14
+	"github.com/docker/engine-api/types/versions"
14 15
 	"golang.org/x/net/context"
15 16
 )
16 17
 
17 18
 // postContainersCopy is deprecated in favor of getContainersArchive.
18 19
 func (s *containerRouter) postContainersCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
20
+	// Deprecated since 1.8, Errors out since 1.12
21
+	version := httputils.VersionFromContext(ctx)
22
+	if versions.GreaterThanOrEqualTo(version, "1.24") {
23
+		w.WriteHeader(http.StatusNotFound)
24
+		return nil
25
+	}
19 26
 	if err := httputils.CheckForJSON(r); err != nil {
20 27
 		return err
21 28
 	}
... ...
@@ -28,6 +28,14 @@ The docker login command is removing the ability to automatically register for a
28 28
 
29 29
 The flag `--security-opt` doesn't use the colon separator(`:`) anymore to divide keys and values, it uses the equal symbol(`=`) for consinstency with other similar flags, like `--storage-opt`.
30 30
 
31
+### `/containers/(id or name)/copy` endpoint
32
+
33
+**Deprecated In Release: v1.8**
34
+
35
+**Removed In Release: v1.12.0**
36
+
37
+The endpoint `/containers/(id or name)/copy` is deprecated in favor of `/containers/(id or name)/archive`.
38
+
31 39
 ### Ambiguous event fields in API
32 40
 **Deprecated In Release: v1.10**
33 41
 
... ...
@@ -125,6 +125,7 @@ This section lists each version from latest to oldest.  Each listing includes a
125 125
 * `POST /containers/(id or name)/start` no longer accepts a `HostConfig`.
126 126
 * `POST /images/(name)/tag` no longer has a `force` query parameter.
127 127
 * `GET /images/search` now supports maximum returned search results `limit`.
128
+* `POST /containers/{name:.*}/copy` is now removed and errors out starting from this API version.
128 129
 
129 130
 ### v1.23 API changes
130 131
 
... ...
@@ -1389,36 +1389,6 @@ Status Codes:
1389 1389
 -   **404** – no such container
1390 1390
 -   **500** – server error
1391 1391
 
1392
-### Copy files or folders from a container
1393
-
1394
-`POST /containers/(id or name)/copy`
1395
-
1396
-Copy files or folders of container `id`
1397
-
1398
-**Deprecated** in favor of the `archive` endpoint below.
1399
-
1400
-**Example request**:
1401
-
1402
-    POST /containers/4fa6e0f0c678/copy HTTP/1.1
1403
-    Content-Type: application/json
1404
-
1405
-    {
1406
-         "Resource": "test.txt"
1407
-    }
1408
-
1409
-**Example response**:
1410
-
1411
-    HTTP/1.1 200 OK
1412
-    Content-Type: application/x-tar
1413
-
1414
-    {{ TAR STREAM }}
1415
-
1416
-Status Codes:
1417
-
1418
--   **200** – no error
1419
--   **404** – no such container
1420
--   **500** – server error
1421
-
1422 1392
 ### Retrieving information about files and folders in a container
1423 1393
 
1424 1394
 `HEAD /containers/(id or name)/archive`
... ...
@@ -892,7 +892,7 @@ func (s *DockerSuite) TestContainerApiWait(c *check.C) {
892 892
 	c.Assert(waitres.StatusCode, checker.Equals, 0)
893 893
 }
894 894
 
895
-func (s *DockerSuite) TestContainerApiCopy(c *check.C) {
895
+func (s *DockerSuite) TestContainerApiCopyNotExistsAnyMore(c *check.C) {
896 896
 	// TODO Windows to Windows CI. This can be ported.
897 897
 	testRequires(c, DaemonIsLinux)
898 898
 	name := "test-container-api-copy"
... ...
@@ -902,7 +902,22 @@ func (s *DockerSuite) TestContainerApiCopy(c *check.C) {
902 902
 		Resource: "/test.txt",
903 903
 	}
904 904
 
905
-	status, body, err := sockRequest("POST", "/containers/"+name+"/copy", postData)
905
+	status, _, err := sockRequest("POST", "/containers/"+name+"/copy", postData)
906
+	c.Assert(err, checker.IsNil)
907
+	c.Assert(status, checker.Equals, http.StatusNotFound)
908
+}
909
+
910
+func (s *DockerSuite) TestContainerApiCopyPre124(c *check.C) {
911
+	// TODO Windows to Windows CI. This can be ported.
912
+	testRequires(c, DaemonIsLinux)
913
+	name := "test-container-api-copy"
914
+	dockerCmd(c, "run", "--name", name, "busybox", "touch", "/test.txt")
915
+
916
+	postData := types.CopyConfig{
917
+		Resource: "/test.txt",
918
+	}
919
+
920
+	status, body, err := sockRequest("POST", "/v1.23/containers/"+name+"/copy", postData)
906 921
 	c.Assert(err, checker.IsNil)
907 922
 	c.Assert(status, checker.Equals, http.StatusOK)
908 923
 
... ...
@@ -923,7 +938,7 @@ func (s *DockerSuite) TestContainerApiCopy(c *check.C) {
923 923
 	c.Assert(found, checker.True)
924 924
 }
925 925
 
926
-func (s *DockerSuite) TestContainerApiCopyResourcePathEmpty(c *check.C) {
926
+func (s *DockerSuite) TestContainerApiCopyResourcePathEmptyPr124(c *check.C) {
927 927
 	// TODO Windows to Windows CI. This can be ported.
928 928
 	testRequires(c, DaemonIsLinux)
929 929
 	name := "test-container-api-copy-resource-empty"
... ...
@@ -933,13 +948,13 @@ func (s *DockerSuite) TestContainerApiCopyResourcePathEmpty(c *check.C) {
933 933
 		Resource: "",
934 934
 	}
935 935
 
936
-	status, body, err := sockRequest("POST", "/containers/"+name+"/copy", postData)
936
+	status, body, err := sockRequest("POST", "/v1.23/containers/"+name+"/copy", postData)
937 937
 	c.Assert(err, checker.IsNil)
938 938
 	c.Assert(status, checker.Equals, http.StatusInternalServerError)
939 939
 	c.Assert(string(body), checker.Matches, "Path cannot be empty\n")
940 940
 }
941 941
 
942
-func (s *DockerSuite) TestContainerApiCopyResourcePathNotFound(c *check.C) {
942
+func (s *DockerSuite) TestContainerApiCopyResourcePathNotFoundPre124(c *check.C) {
943 943
 	// TODO Windows to Windows CI. This can be ported.
944 944
 	testRequires(c, DaemonIsLinux)
945 945
 	name := "test-container-api-copy-resource-not-found"
... ...
@@ -949,18 +964,18 @@ func (s *DockerSuite) TestContainerApiCopyResourcePathNotFound(c *check.C) {
949 949
 		Resource: "/notexist",
950 950
 	}
951 951
 
952
-	status, body, err := sockRequest("POST", "/containers/"+name+"/copy", postData)
952
+	status, body, err := sockRequest("POST", "/v1.23/containers/"+name+"/copy", postData)
953 953
 	c.Assert(err, checker.IsNil)
954 954
 	c.Assert(status, checker.Equals, http.StatusInternalServerError)
955 955
 	c.Assert(string(body), checker.Matches, "Could not find the file /notexist in container "+name+"\n")
956 956
 }
957 957
 
958
-func (s *DockerSuite) TestContainerApiCopyContainerNotFound(c *check.C) {
958
+func (s *DockerSuite) TestContainerApiCopyContainerNotFoundPr124(c *check.C) {
959 959
 	postData := types.CopyConfig{
960 960
 		Resource: "/something",
961 961
 	}
962 962
 
963
-	status, _, err := sockRequest("POST", "/containers/notexists/copy", postData)
963
+	status, _, err := sockRequest("POST", "/v1.23/containers/notexists/copy", postData)
964 964
 	c.Assert(err, checker.IsNil)
965 965
 	c.Assert(status, checker.Equals, http.StatusNotFound)
966 966
 }