Browse code

Fix #1162 - Remove bufio from Untar

Guillaume J. Charmes authored on 2013/07/09 05:30:03
Showing 2 changed files
... ...
@@ -2,7 +2,6 @@ package docker
2 2
 
3 3
 import (
4 4
 	"archive/tar"
5
-	"bufio"
6 5
 	"bytes"
7 6
 	"fmt"
8 7
 	"github.com/dotcloud/docker/utils"
... ...
@@ -26,10 +25,6 @@ const (
26 26
 )
27 27
 
28 28
 func DetectCompression(source []byte) Compression {
29
-	for _, c := range source[:10] {
30
-		utils.Debugf("%x", c)
31
-	}
32
-
33 29
 	sourceLen := len(source)
34 30
 	for compression, m := range map[Compression][]byte{
35 31
 		Bzip2: {0x42, 0x5A, 0x68},
... ...
@@ -110,17 +105,26 @@ func Untar(archive io.Reader, path string) error {
110 110
 	if archive == nil {
111 111
 		return fmt.Errorf("Empty archive")
112 112
 	}
113
-	bufferedArchive := bufio.NewReaderSize(archive, 10)
114
-	buf, err := bufferedArchive.Peek(10)
115
-	if err != nil {
116
-		return err
113
+
114
+	buf := make([]byte, 10)
115
+	totalN := 0
116
+	for totalN < 10 {
117
+		if n, err := archive.Read(buf[totalN:]); err != nil {
118
+			if err == io.EOF {
119
+				return fmt.Errorf("Tarball too short")
120
+			}
121
+			return err
122
+		} else {
123
+			totalN += n
124
+			utils.Debugf("[tar autodetect] n: %d", n)
125
+		}
117 126
 	}
118 127
 	compression := DetectCompression(buf)
119 128
 
120 129
 	utils.Debugf("Archive compression detected: %s", compression.Extension())
121 130
 
122 131
 	cmd := exec.Command("tar", "--numeric-owner", "-f", "-", "-C", path, "-x"+compression.Flag())
123
-	cmd.Stdin = bufferedArchive
132
+	cmd.Stdin = io.MultiReader(bytes.NewReader(buf), archive)
124 133
 	// Hardcode locale environment for predictable outcome regardless of host configuration.
125 134
 	//   (see https://github.com/dotcloud/docker/issues/355)
126 135
 	cmd.Env = []string{"LANG=en_US.utf-8", "LC_ALL=en_US.utf-8"}
... ...
@@ -94,9 +94,12 @@ func StoreImage(img *Image, layerData Archive, root string, store bool) error {
94 94
 	}
95 95
 	// If layerData is not nil, unpack it into the new layer
96 96
 	if layerData != nil {
97
+		start := time.Now()
98
+		utils.Debugf("Start untar layer")
97 99
 		if err := Untar(layerData, layer); err != nil {
98 100
 			return err
99 101
 		}
102
+		utils.Debugf("Untar time: %vs\n", time.Now().Sub(start).Seconds())
100 103
 	}
101 104
 
102 105
 	return StoreSize(img, root)