Просмотр исходного кода

api: remove POST /containers/{id}/copy endpoint (api < v1.23)

This endpoint was deprecated in API v1.20 (Docker Engine v1.8.0) in
commit db9cc91a9ef7dea4c8d85f64578889cec3dd99b2, in favor of the
`PUT /containers/{id}/archive` and `HEAD /containers/{id}/archive`
endpoints, and disabled in API v1.24 (Docker Engine v1.12.0) through
commit 428328908dc529b1678fb3d8b033fb0591a294e3.

This patch removes the endpoint, and the associated `daemon.ContainerCopy`
method in the backend.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 1 год назад
Родитель
Сommit
b3a0ff9944

+ 0 - 1
api/server/router/container/backend.go

@@ -24,7 +24,6 @@ type execBackend interface {
 // copyBackend includes functions to implement to provide container copy functionality.
 type copyBackend interface {
 	ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error)
-	ContainerCopy(name string, res string) (io.ReadCloser, error)
 	ContainerExport(ctx context.Context, name string, out io.Writer) error
 	ContainerExtractToDir(name, path string, copyUIDGID, noOverwriteDirNonDir bool, content io.Reader) error
 	ContainerStatPath(name string, path string) (stat *types.ContainerPathStat, err error)

+ 0 - 1
api/server/router/container/container.go

@@ -56,7 +56,6 @@ 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), // Deprecated since 1.8 (API v1.20), errors out since 1.12 (API v1.24)
 		router.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate),
 		router.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart),
 		router.NewPostRoute("/exec/{name:.*}/resize", r.postContainerExecResize),

+ 1 - 40
api/server/router/container/copy.go

@@ -11,49 +11,10 @@ import (
 
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/versions"
 	gddohttputil "github.com/golang/gddo/httputil"
 )
 
-type pathError struct{}
-
-func (pathError) Error() string {
-	return "Path cannot be empty"
-}
-
-func (pathError) InvalidParameter() {}
-
-// postContainersCopy is deprecated in favor of getContainersArchive.
-//
-// Deprecated since 1.8 (API v1.20), errors out since 1.12 (API v1.24)
-func (s *containerRouter) postContainersCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	version := httputils.VersionFromContext(ctx)
-	if versions.GreaterThanOrEqualTo(version, "1.24") {
-		w.WriteHeader(http.StatusNotFound)
-		return nil
-	}
-
-	cfg := types.CopyConfig{}
-	if err := httputils.ReadJSON(r, &cfg); err != nil {
-		return err
-	}
-
-	if cfg.Resource == "" {
-		return pathError{}
-	}
-
-	data, err := s.backend.ContainerCopy(vars["name"], cfg.Resource)
-	if err != nil {
-		return err
-	}
-	defer data.Close()
-
-	w.Header().Set("Content-Type", "application/x-tar")
-	_, err = io.Copy(w, data)
-	return err
-}
-
-// // Encode the stat to JSON, base64 encode, and place in a header.
+// setContainerPathStatHeader encodes the stat to JSON, base64 encode, and place in a header.
 func setContainerPathStatHeader(stat *types.ContainerPathStat, header http.Header) error {
 	statJSON, err := json.Marshal(stat)
 	if err != nil {

+ 0 - 19
daemon/archive.go

@@ -8,25 +8,6 @@ import (
 	"github.com/docker/docker/errdefs"
 )
 
-// ContainerCopy performs a deprecated operation of archiving the resource at
-// the specified path in the container identified by the given name.
-func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, error) {
-	ctr, err := daemon.GetContainer(name)
-	if err != nil {
-		return nil, err
-	}
-
-	data, err := daemon.containerCopy(ctr, res)
-	if err == nil {
-		return data, nil
-	}
-
-	if os.IsNotExist(err) {
-		return nil, containerFileNotFound{res, name}
-	}
-	return nil, errdefs.System(err)
-}
-
 // ContainerStatPath stats the filesystem resource at the specified path in the
 // container identified by the given name.
 func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.ContainerPathStat, err error) {

+ 0 - 49
daemon/archive_unix.go

@@ -161,55 +161,6 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path
 	return nil
 }
 
-func (daemon *Daemon) containerCopy(container *container.Container, resource string) (rc io.ReadCloser, err error) {
-	container.Lock()
-
-	defer func() {
-		if err != nil {
-			// Wait to unlock the container until the archive is fully read
-			// (see the ReadCloseWrapper func below) or if there is an error
-			// before that occurs.
-			container.Unlock()
-		}
-	}()
-
-	cfs, err := daemon.openContainerFS(container)
-	if err != nil {
-		return nil, err
-	}
-	defer func() {
-		if err != nil {
-			cfs.Close()
-		}
-	}()
-
-	err = cfs.RunInFS(context.TODO(), func() error {
-		_, err := os.Stat(resource)
-		return err
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	tb, err := archive.NewTarballer(resource, &archive.TarOptions{
-		Compression: archive.Uncompressed,
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	cfs.GoInFS(context.TODO(), tb.Do)
-	archv := tb.Reader()
-	reader := ioutils.NewReadCloserWrapper(archv, func() error {
-		err := archv.Close()
-		_ = cfs.Close()
-		container.Unlock()
-		return err
-	})
-	daemon.LogContainerEvent(container, events.ActionCopy)
-	return reader, nil
-}
-
 // checkIfPathIsInAVolume checks if the path is in a volume. If it is, it
 // cannot be in a read-only volume. If it  is not in a volume, the container
 // cannot be configured with a read-only rootfs.

+ 0 - 75
integration-cli/docker_api_containers_test.go

@@ -958,81 +958,6 @@ func (s *DockerAPISuite) TestContainerAPICopyNotExistsAnyMore(c *testing.T) {
 	assert.Equal(c, res.StatusCode, http.StatusNotFound)
 }
 
-func (s *DockerAPISuite) TestContainerAPICopyPre124(c *testing.T) {
-	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
-	const name = "test-container-api-copy"
-	cli.DockerCmd(c, "run", "--name", name, "busybox", "touch", "/test.txt")
-
-	postData := types.CopyConfig{
-		Resource: "/test.txt",
-	}
-
-	res, body, err := request.Post(testutil.GetContext(c), "/v1.23/containers/"+name+"/copy", request.JSONBody(postData))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusOK)
-
-	found := false
-	for tarReader := tar.NewReader(body); ; {
-		h, err := tarReader.Next()
-		if err != nil {
-			if err == io.EOF {
-				break
-			}
-			c.Fatal(err)
-		}
-		if h.Name == "test.txt" {
-			found = true
-			break
-		}
-	}
-	assert.Assert(c, found)
-}
-
-func (s *DockerAPISuite) TestContainerAPICopyResourcePathEmptyPre124(c *testing.T) {
-	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
-	const name = "test-container-api-copy-resource-empty"
-	cli.DockerCmd(c, "run", "--name", name, "busybox", "touch", "/test.txt")
-
-	postData := types.CopyConfig{
-		Resource: "",
-	}
-
-	res, body, err := request.Post(testutil.GetContext(c), "/v1.23/containers/"+name+"/copy", request.JSONBody(postData))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
-	b, err := request.ReadBody(body)
-	assert.NilError(c, err)
-	assert.Assert(c, is.Regexp("^Path cannot be empty\n$", string(b)))
-}
-
-func (s *DockerAPISuite) TestContainerAPICopyResourcePathNotFoundPre124(c *testing.T) {
-	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
-	const name = "test-container-api-copy-resource-not-found"
-	cli.DockerCmd(c, "run", "--name", name, "busybox")
-
-	postData := types.CopyConfig{
-		Resource: "/notexist",
-	}
-
-	res, body, err := request.Post(testutil.GetContext(c), "/v1.23/containers/"+name+"/copy", request.JSONBody(postData))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNotFound)
-	b, err := request.ReadBody(body)
-	assert.NilError(c, err)
-	assert.Assert(c, is.Regexp("^Could not find the file /notexist in container "+name+"\n$", string(b)))
-}
-
-func (s *DockerAPISuite) TestContainerAPICopyContainerNotFoundPr124(c *testing.T) {
-	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
-	postData := types.CopyConfig{
-		Resource: "/something",
-	}
-
-	res, _, err := request.Post(testutil.GetContext(c), "/v1.23/containers/notexists/copy", request.JSONBody(postData))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNotFound)
-}
-
 func (s *DockerAPISuite) TestContainerAPIDelete(c *testing.T) {
 	id := runSleepingContainer(c)
 	cli.WaitRun(c, id)

+ 0 - 1
integration/container/container_test.go

@@ -29,7 +29,6 @@ func TestContainerInvalidJSON(t *testing.T) {
 	if runtime.GOOS != "windows" {
 		endpoints = append(
 			endpoints,
-			"/v1.23/containers/foobar/copy",  // deprecated since 1.8 (API v1.20), errors out since 1.12 (API v1.24)
 			"/v1.23/containers/foobar/start", // accepts a body on API < v1.24
 		)
 	}