... | ... |
@@ -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) |