Deprecate /containers/(id or name)/copy endpoint
| ... | ... |
@@ -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 |
} |
| ... | ... |
@@ -35,6 +35,14 @@ The docker login command is removing the ability to automatically register for a |
| 35 | 35 |
|
| 36 | 36 |
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`. |
| 37 | 37 |
|
| 38 |
+### `/containers/(id or name)/copy` endpoint |
|
| 39 |
+ |
|
| 40 |
+**Deprecated In Release: v1.8** |
|
| 41 |
+ |
|
| 42 |
+**Removed In Release: v1.12.0** |
|
| 43 |
+ |
|
| 44 |
+The endpoint `/containers/(id or name)/copy` is deprecated in favor of `/containers/(id or name)/archive`. |
|
| 45 |
+ |
|
| 38 | 46 |
### Ambiguous event fields in API |
| 39 | 47 |
**Deprecated In Release: [v1.10.0](https://github.com/docker/docker/releases/tag/v1.10.0)** |
| 40 | 48 |
|
| ... | ... |
@@ -129,6 +129,7 @@ This section lists each version from latest to oldest. Each listing includes a |
| 129 | 129 |
* `POST /containers/(id or name)/start` no longer accepts a `HostConfig`. |
| 130 | 130 |
* `POST /images/(name)/tag` no longer has a `force` query parameter. |
| 131 | 131 |
* `GET /images/search` now supports maximum returned search results `limit`. |
| 132 |
+* `POST /containers/{name:.*}/copy` is now removed and errors out starting from this API version.
|
|
| 132 | 133 |
|
| 133 | 134 |
### v1.23 API changes |
| 134 | 135 |
|
| ... | ... |
@@ -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 |
} |