Browse code

Merge pull request #11177 from duglin/10805-cp-to-stdot

Add support for 'docker cp' to write to stdout

moxiegirl authored on 2015/03/10 01:51:48
Showing 5 changed files
... ...
@@ -2434,7 +2434,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
2434 2434
 }
2435 2435
 
2436 2436
 func (cli *DockerCli) CmdCp(args ...string) error {
2437
-	cmd := cli.Subcmd("cp", "CONTAINER:PATH HOSTPATH", "Copy files/folders from the PATH to the HOSTPATH", true)
2437
+	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)
2438 2438
 	cmd.Require(flag.Exact, 2)
2439 2439
 
2440 2440
 	utils.ParseFlags(cmd, args, true)
... ...
@@ -2461,7 +2461,14 @@ func (cli *DockerCli) CmdCp(args ...string) error {
2461 2461
 	}
2462 2462
 
2463 2463
 	if statusCode == 200 {
2464
-		if err := archive.Untar(stream, copyData.Get("HostPath"), &archive.TarOptions{NoLchown: true}); err != nil {
2464
+		dest := copyData.Get("HostPath")
2465
+
2466
+		if dest == "-" {
2467
+			_, err = io.Copy(cli.out, stream)
2468
+		} else {
2469
+			err = archive.Untar(stream, dest, &archive.TarOptions{NoLchown: true})
2470
+		}
2471
+		if err != nil {
2465 2472
 			return err
2466 2473
 		}
2467 2474
 	}
... ...
@@ -2,16 +2,17 @@
2 2
 % Docker Community
3 3
 % JUNE 2014
4 4
 # NAME
5
-docker-cp - Copy files/folders from the PATH to the HOSTPATH
5
+docker-cp - Copy files/folders from the PATH to the HOSTPATH, or STDOUT
6 6
 
7 7
 # SYNOPSIS
8 8
 **docker cp**
9 9
 [**--help**]
10
-CONTAINER:PATH HOSTPATH
10
+CONTAINER:PATH HOSTPATH|-
11 11
 
12 12
 # DESCRIPTION
13
-Copy files/folders from a container's filesystem to the host
14
-path. Paths are relative to the root of the filesystem. Files
13
+Copy files/folders from a container's filesystem to the
14
+path. Use '-' to write the data as a tar file to STDOUT.
15
+Paths are relative to the root of the filesystem. Files
15 16
 can be copied from a running or stopped container.
16 17
 
17 18
 # OPTIONS
... ...
@@ -117,7 +117,7 @@ unix://[/path/to/socket] to use.
117 117
   Create a new image from a container's changes
118 118
 
119 119
 **docker-cp(1)**
120
-  Copy files/folders from a container's filesystem to the host at path
120
+  Copy files/folders from a container's filesystem to the host
121 121
 
122 122
 **docker-create(1)**
123 123
   Create a new container
... ...
@@ -757,12 +757,15 @@ Supported `Dockerfile` instructions: `CMD`, `ENTRYPOINT`, `ENV`, `EXPOSE`,
757 757
 
758 758
 ## cp
759 759
 
760
-Copy files/folders from a container's filesystem to the host
761
-path.  Paths are relative to the root of the filesystem.
760
+Copy files/folders from a container's filesystem to the
761
+path.  Use '-' to write the data as a tar file to STDOUT.
762
+Paths are relative to the root of the filesystem.
762 763
 
763
-    Usage: docker cp CONTAINER:PATH HOSTPATH
764
+    Usage: docker cp CONTAINER:PATH HOSTPATH|-
765
+
766
+    Copy files/folders from the PATH to the HOSTPATH. Use '-' to write the data
767
+	as a tar file to STDOUT.
764 768
 
765
-    Copy files/folders from the PATH to the HOSTPATH
766 769
 
767 770
 ## create
768 771
 
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"os/exec"
9 9
 	"path"
10 10
 	"path/filepath"
11
+	"strings"
11 12
 	"testing"
12 13
 )
13 14
 
... ...
@@ -528,3 +529,30 @@ func TestCpToDot(t *testing.T) {
528 528
 	}
529 529
 	logDone("cp - to dot path")
530 530
 }
531
+
532
+func TestCpToStdout(t *testing.T) {
533
+	out, exitCode, err := dockerCmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "echo lololol > /test")
534
+	if err != nil || exitCode != 0 {
535
+		t.Fatalf("failed to create a container:%s\n%s", out, err)
536
+	}
537
+
538
+	cID := stripTrailingCharacters(out)
539
+	defer deleteContainer(cID)
540
+
541
+	out, _, err = dockerCmd(t, "wait", cID)
542
+	if err != nil || stripTrailingCharacters(out) != "0" {
543
+		t.Fatalf("failed to set up container:%s\n%s", out, err)
544
+	}
545
+
546
+	out, _, err = runCommandPipelineWithOutput(
547
+		exec.Command(dockerBinary, "cp", cID+":/test", "-"),
548
+		exec.Command("tar", "-vtf", "-"))
549
+	if err != nil {
550
+		t.Fatalf("Failed to run commands: %s", err)
551
+	}
552
+
553
+	if !strings.Contains(out, "test") || !strings.Contains(out, "-rw") {
554
+		t.Fatalf("Missing file from tar TOC:\n%s", out)
555
+	}
556
+	logDone("cp - to stdout")
557
+}