浏览代码

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 10 年之前
父节点
当前提交
d1535131d2
共有 4 个文件被更改,包括 26 次插入4 次删除
  1. 1 4
      pkg/chrootarchive/archive.go
  2. 16 0
      pkg/chrootarchive/archive_test.go
  3. 1 0
      pkg/chrootarchive/diff.go
  4. 8 0
      pkg/chrootarchive/init.go

+ 1 - 4
pkg/chrootarchive/archive.go

@@ -6,7 +6,6 @@ import (
 	"flag"
 	"flag"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
-	"io/ioutil"
 	"os"
 	"os"
 	"runtime"
 	"runtime"
 	"strings"
 	"strings"
@@ -35,9 +34,7 @@ func untar() {
 		fatal(err)
 		fatal(err)
 	}
 	}
 	// fully consume stdin in case it is zero padded
 	// fully consume stdin in case it is zero padded
-	if _, err := ioutil.ReadAll(os.Stdin); err != nil {
-		fatal(err)
-	}
+	flush(os.Stdin)
 	os.Exit(0)
 	os.Exit(0)
 }
 }
 
 

+ 16 - 0
pkg/chrootarchive/archive_test.go

@@ -83,3 +83,19 @@ func TestChrootUntarEmptyArchiveFromSlowReader(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 }
 }
+
+func TestChrootApplyEmptyArchiveFromSlowReader(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "docker-TestChrootApplyEmptyArchiveFromSlowReader")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+	dest := filepath.Join(tmpdir, "dest")
+	if err := os.MkdirAll(dest, 0700); err != nil {
+		t.Fatal(err)
+	}
+	stream := &slowEmptyTarReader{size: 10240, chunkSize: 1024}
+	if err := ApplyLayer(dest, stream); err != nil {
+		t.Fatal(err)
+	}
+}

+ 1 - 0
pkg/chrootarchive/diff.go

@@ -32,6 +32,7 @@ func applyLayer() {
 		fatal(err)
 		fatal(err)
 	}
 	}
 	os.RemoveAll(tmpDir)
 	os.RemoveAll(tmpDir)
+	flush(os.Stdin)
 	os.Exit(0)
 	os.Exit(0)
 }
 }
 
 

+ 8 - 0
pkg/chrootarchive/init.go

@@ -2,6 +2,8 @@ package chrootarchive
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"io"
+	"io/ioutil"
 	"os"
 	"os"
 
 
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/reexec"
@@ -16,3 +18,9 @@ func fatal(err error) {
 	fmt.Fprint(os.Stderr, err)
 	fmt.Fprint(os.Stderr, err)
 	os.Exit(1)
 	os.Exit(1)
 }
 }
+
+// flush consumes all the bytes from the reader discarding
+// any errors
+func flush(r io.Reader) {
+	io.Copy(ioutil.Discard, r)
+}