Browse code

Flush stdin from within chroot archive

This makes sure that we don't buffer in memory and that we also flush
stdin from diff as well as untar.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Michael Crosby authored on 2014/12/09 08:04:34
Showing 4 changed files
... ...
@@ -6,7 +6,6 @@ import (
6 6
 	"flag"
7 7
 	"fmt"
8 8
 	"io"
9
-	"io/ioutil"
10 9
 	"os"
11 10
 	"runtime"
12 11
 	"strings"
... ...
@@ -35,9 +34,7 @@ func untar() {
35 35
 		fatal(err)
36 36
 	}
37 37
 	// fully consume stdin in case it is zero padded
38
-	if _, err := ioutil.ReadAll(os.Stdin); err != nil {
39
-		fatal(err)
40
-	}
38
+	flush(os.Stdin)
41 39
 	os.Exit(0)
42 40
 }
43 41
 
... ...
@@ -83,3 +83,19 @@ func TestChrootUntarEmptyArchiveFromSlowReader(t *testing.T) {
83 83
 		t.Fatal(err)
84 84
 	}
85 85
 }
86
+
87
+func TestChrootApplyEmptyArchiveFromSlowReader(t *testing.T) {
88
+	tmpdir, err := ioutil.TempDir("", "docker-TestChrootApplyEmptyArchiveFromSlowReader")
89
+	if err != nil {
90
+		t.Fatal(err)
91
+	}
92
+	defer os.RemoveAll(tmpdir)
93
+	dest := filepath.Join(tmpdir, "dest")
94
+	if err := os.MkdirAll(dest, 0700); err != nil {
95
+		t.Fatal(err)
96
+	}
97
+	stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024}
98
+	if err := ApplyLayer(dest, stream); err != nil {
99
+		t.Fatal(err)
100
+	}
101
+}
... ...
@@ -32,6 +32,7 @@ func applyLayer() {
32 32
 		fatal(err)
33 33
 	}
34 34
 	os.RemoveAll(tmpDir)
35
+	flush(os.Stdin)
35 36
 	os.Exit(0)
36 37
 }
37 38
 
... ...
@@ -2,6 +2,8 @@ package chrootarchive
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"io"
6
+	"io/ioutil"
5 7
 	"os"
6 8
 
7 9
 	"github.com/docker/docker/pkg/reexec"
... ...
@@ -16,3 +18,9 @@ func fatal(err error) {
16 16
 	fmt.Fprint(os.Stderr, err)
17 17
 	os.Exit(1)
18 18
 }
19
+
20
+// flush consumes all the bytes from the reader discarding
21
+// any errors
22
+func flush(r io.Reader) {
23
+	io.Copy(ioutil.Discard, r)
24
+}