From 428328908dc529b1678fb3d8b033fb0591a294e3 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 3 Jun 2016 19:38:03 +0200 Subject: [PATCH] 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 --- api/server/router/container/container.go | 2 +- api/server/router/container/copy.go | 7 +++++ docs/deprecated.md | 8 +++++ docs/reference/api/docker_remote_api.md | 1 + docs/reference/api/docker_remote_api_v1.24.md | 30 ------------------ integration-cli/docker_api_containers_test.go | 31 ++++++++++++++----- 6 files changed, 40 insertions(+), 39 deletions(-) diff --git a/api/server/router/container/container.go b/api/server/router/container/container.go index df505ad196..d6fea4c353 100644 --- a/api/server/router/container/container.go +++ b/api/server/router/container/container.go @@ -62,7 +62,7 @@ func (r *containerRouter) initRoutes() { router.NewPostRoute("/containers/{name:.*}/wait", r.postContainersWait), router.NewPostRoute("/containers/{name:.*}/resize", r.postContainersResize), router.NewPostRoute("/containers/{name:.*}/attach", r.postContainersAttach), - router.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy), + router.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy), // Deprecated since 1.8, Errors out since 1.12 router.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate), router.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart), router.NewPostRoute("/exec/{name:.*}/resize", r.postContainerExecResize), diff --git a/api/server/router/container/copy.go b/api/server/router/container/copy.go index 69584b31f5..554b40e8be 100644 --- a/api/server/router/container/copy.go +++ b/api/server/router/container/copy.go @@ -11,11 +11,18 @@ import ( "github.com/docker/docker/api/server/httputils" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/versions" "golang.org/x/net/context" ) // postContainersCopy is deprecated in favor of getContainersArchive. func (s *containerRouter) postContainersCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + // Deprecated since 1.8, Errors out since 1.12 + version := httputils.VersionFromContext(ctx) + if versions.GreaterThanOrEqualTo(version, "1.24") { + w.WriteHeader(http.StatusNotFound) + return nil + } if err := httputils.CheckForJSON(r); err != nil { return err } diff --git a/docs/deprecated.md b/docs/deprecated.md index 9de65b28c2..a2ee7eaa8d 100644 --- a/docs/deprecated.md +++ b/docs/deprecated.md @@ -28,6 +28,14 @@ The docker login command is removing the ability to automatically register for a 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`. +### `/containers/(id or name)/copy` endpoint + +**Deprecated In Release: v1.8** + +**Removed In Release: v1.12.0** + +The endpoint `/containers/(id or name)/copy` is deprecated in favor of `/containers/(id or name)/archive`. + ### Ambiguous event fields in API **Deprecated In Release: v1.10** diff --git a/docs/reference/api/docker_remote_api.md b/docs/reference/api/docker_remote_api.md index 58c0743959..7cc8f03a5b 100644 --- a/docs/reference/api/docker_remote_api.md +++ b/docs/reference/api/docker_remote_api.md @@ -125,6 +125,7 @@ This section lists each version from latest to oldest. Each listing includes a * `POST /containers/(id or name)/start` no longer accepts a `HostConfig`. * `POST /images/(name)/tag` no longer has a `force` query parameter. * `GET /images/search` now supports maximum returned search results `limit`. +* `POST /containers/{name:.*}/copy` is now removed and errors out starting from this API version. ### v1.23 API changes diff --git a/docs/reference/api/docker_remote_api_v1.24.md b/docs/reference/api/docker_remote_api_v1.24.md index 5fd040389a..bc56278d1c 100644 --- a/docs/reference/api/docker_remote_api_v1.24.md +++ b/docs/reference/api/docker_remote_api_v1.24.md @@ -1389,36 +1389,6 @@ Status Codes: - **404** – no such container - **500** – server error -### Copy files or folders from a container - -`POST /containers/(id or name)/copy` - -Copy files or folders of container `id` - -**Deprecated** in favor of the `archive` endpoint below. - -**Example request**: - - POST /containers/4fa6e0f0c678/copy HTTP/1.1 - Content-Type: application/json - - { - "Resource": "test.txt" - } - -**Example response**: - - HTTP/1.1 200 OK - Content-Type: application/x-tar - - {{ TAR STREAM }} - -Status Codes: - -- **200** – no error -- **404** – no such container -- **500** – server error - ### Retrieving information about files and folders in a container `HEAD /containers/(id or name)/archive` diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 5c19abddf9..52e3a02326 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -892,7 +892,7 @@ func (s *DockerSuite) TestContainerApiWait(c *check.C) { c.Assert(waitres.StatusCode, checker.Equals, 0) } -func (s *DockerSuite) TestContainerApiCopy(c *check.C) { +func (s *DockerSuite) TestContainerApiCopyNotExistsAnyMore(c *check.C) { // TODO Windows to Windows CI. This can be ported. testRequires(c, DaemonIsLinux) name := "test-container-api-copy" @@ -902,7 +902,22 @@ func (s *DockerSuite) TestContainerApiCopy(c *check.C) { Resource: "/test.txt", } - status, body, err := sockRequest("POST", "/containers/"+name+"/copy", postData) + status, _, err := sockRequest("POST", "/containers/"+name+"/copy", postData) + c.Assert(err, checker.IsNil) + c.Assert(status, checker.Equals, http.StatusNotFound) +} + +func (s *DockerSuite) TestContainerApiCopyPre124(c *check.C) { + // TODO Windows to Windows CI. This can be ported. + testRequires(c, DaemonIsLinux) + name := "test-container-api-copy" + dockerCmd(c, "run", "--name", name, "busybox", "touch", "/test.txt") + + postData := types.CopyConfig{ + Resource: "/test.txt", + } + + status, body, err := sockRequest("POST", "/v1.23/containers/"+name+"/copy", postData) c.Assert(err, checker.IsNil) c.Assert(status, checker.Equals, http.StatusOK) @@ -923,7 +938,7 @@ func (s *DockerSuite) TestContainerApiCopy(c *check.C) { c.Assert(found, checker.True) } -func (s *DockerSuite) TestContainerApiCopyResourcePathEmpty(c *check.C) { +func (s *DockerSuite) TestContainerApiCopyResourcePathEmptyPr124(c *check.C) { // TODO Windows to Windows CI. This can be ported. testRequires(c, DaemonIsLinux) name := "test-container-api-copy-resource-empty" @@ -933,13 +948,13 @@ func (s *DockerSuite) TestContainerApiCopyResourcePathEmpty(c *check.C) { Resource: "", } - status, body, err := sockRequest("POST", "/containers/"+name+"/copy", postData) + status, body, err := sockRequest("POST", "/v1.23/containers/"+name+"/copy", postData) c.Assert(err, checker.IsNil) c.Assert(status, checker.Equals, http.StatusInternalServerError) c.Assert(string(body), checker.Matches, "Path cannot be empty\n") } -func (s *DockerSuite) TestContainerApiCopyResourcePathNotFound(c *check.C) { +func (s *DockerSuite) TestContainerApiCopyResourcePathNotFoundPre124(c *check.C) { // TODO Windows to Windows CI. This can be ported. testRequires(c, DaemonIsLinux) name := "test-container-api-copy-resource-not-found" @@ -949,18 +964,18 @@ func (s *DockerSuite) TestContainerApiCopyResourcePathNotFound(c *check.C) { Resource: "/notexist", } - status, body, err := sockRequest("POST", "/containers/"+name+"/copy", postData) + status, body, err := sockRequest("POST", "/v1.23/containers/"+name+"/copy", postData) c.Assert(err, checker.IsNil) c.Assert(status, checker.Equals, http.StatusInternalServerError) c.Assert(string(body), checker.Matches, "Could not find the file /notexist in container "+name+"\n") } -func (s *DockerSuite) TestContainerApiCopyContainerNotFound(c *check.C) { +func (s *DockerSuite) TestContainerApiCopyContainerNotFoundPr124(c *check.C) { postData := types.CopyConfig{ Resource: "/something", } - status, _, err := sockRequest("POST", "/containers/notexists/copy", postData) + status, _, err := sockRequest("POST", "/v1.23/containers/notexists/copy", postData) c.Assert(err, checker.IsNil) c.Assert(status, checker.Equals, http.StatusNotFound) }