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) }