浏览代码

Add support for 'docker cp' to write to stdout

Closes #10805

Signed-off-by: Doug Davis <dug@us.ibm.com>
Doug Davis 10 年之前
父节点
当前提交
f3d96e81e9

+ 9 - 2
api/client/commands.go

@@ -2415,7 +2415,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 }
 
 func (cli *DockerCli) CmdCp(args ...string) error {
-	cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTPATH", "Copy files/folders from the PATH to the HOSTPATH", true)
+	cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTPATH|-", "Copy files/folders from the PATH to the HOSTPATH. Use '-' to write the data\nas a tar file to STDOUT.", true)
 	cmd.Require(flag.Exact, 2)
 
 	utils.ParseFlags(cmd, args, true)
@@ -2442,7 +2442,14 @@ func (cli *DockerCli) CmdCp(args ...string) error {
 	}
 
 	if statusCode == 200 {
-		if err := archive.Untar(stream, copyData.Get("HostPath"), &archive.TarOptions{NoLchown: true}); err != nil {
+		dest := copyData.Get("HostPath")
+
+		if dest == "-" {
+			_, err = io.Copy(cli.out, stream)
+		} else {
+			err = archive.Untar(stream, dest, &archive.TarOptions{NoLchown: true})
+		}
+		if err != nil {
 			return err
 		}
 	}

+ 5 - 4
docs/man/docker-cp.1.md

@@ -2,16 +2,17 @@
 % Docker Community
 % JUNE 2014
 # NAME
-docker-cp - Copy files/folders from the PATH to the HOSTPATH
+docker-cp - Copy files/folders from the PATH to the HOSTPATH, or STDOUT
 
 # SYNOPSIS
 **docker cp**
 [**--help**]
-CONTAINER:PATH HOSTPATH
+CONTAINER:PATH HOSTPATH|-
 
 # DESCRIPTION
-Copy files/folders from a container's filesystem to the host
-path. Paths are relative to the root of the filesystem. Files
+Copy files/folders from a container's filesystem to the
+path. Use '-' to write the data as a tar file to STDOUT.
+Paths are relative to the root of the filesystem. Files
 can be copied from a running or stopped container.
 
 # OPTIONS

+ 1 - 1
docs/man/docker.1.md

@@ -117,7 +117,7 @@ unix://[/path/to/socket] to use.
   Create a new image from a container's changes
 
 **docker-cp(1)**
-  Copy files/folders from a container's filesystem to the host at path
+  Copy files/folders from a container's filesystem to the host
 
 **docker-create(1)**
   Create a new container

+ 7 - 4
docs/sources/reference/commandline/cli.md

@@ -757,12 +757,15 @@ Supported `Dockerfile` instructions: `CMD`, `ENTRYPOINT`, `ENV`, `EXPOSE`,
 
 ## cp
 
-Copy files/folders from a container's filesystem to the host
-path.  Paths are relative to the root of the filesystem.
+Copy files/folders from a container's filesystem to the
+path.  Use '-' to write the data as a tar file to STDOUT.
+Paths are relative to the root of the filesystem.
 
-    Usage: docker cp CONTAINER:PATH HOSTPATH
+    Usage: docker cp CONTAINER:PATH HOSTPATH|-
+
+    Copy files/folders from the PATH to the HOSTPATH. Use '-' to write the data
+	as a tar file to STDOUT.
 
-    Copy files/folders from the PATH to the HOSTPATH
 
 ## create
 

+ 28 - 0
integration-cli/docker_cli_cp_test.go

@@ -8,6 +8,7 @@ import (
 	"os/exec"
 	"path"
 	"path/filepath"
+	"strings"
 	"testing"
 )
 
@@ -528,3 +529,30 @@ func TestCpToDot(t *testing.T) {
 	}
 	logDone("cp - to dot path")
 }
+
+func TestCpToStdout(t *testing.T) {
+	out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
+	if err != nil || exitCode != 0 {
+		t.Fatalf("failed to create a container:%s\n%s", out, err)
+	}
+
+	cID := stripTrailingCharacters(out)
+	defer deleteContainer(cID)
+
+	out, _, err = dockerCmd(t, "wait", cID)
+	if err != nil || stripTrailingCharacters(out) != "0" {
+		t.Fatalf("failed to set up container:%s\n%s", out, err)
+	}
+
+	out, _, err = runCommandPipelineWithOutput(
+		exec.Command(dockerBinary, "cp", cID+":/test", "-"),
+		exec.Command("tar", "-vtf", "-"))
+	if err != nil {
+		t.Fatalf("Failed to run commands: %s", err)
+	}
+
+	if !strings.Contains(out, "test") || !strings.Contains(out, "-rw") {
+		t.Fatalf("Missing file from tar TOC:\n%s", out)
+	}
+	logDone("cp - to stdout")
+}