... | ... |
@@ -1,8 +1,10 @@ |
1 | 1 |
package docker |
2 | 2 |
|
3 | 3 |
import ( |
4 |
+ "bytes" |
|
4 | 5 |
"errors" |
5 | 6 |
"fmt" |
7 |
+ "github.com/dotcloud/docker/utils" |
|
6 | 8 |
"io" |
7 | 9 |
"io/ioutil" |
8 | 10 |
"os" |
... | ... |
@@ -20,6 +22,37 @@ const ( |
20 | 20 |
Xz |
21 | 21 |
) |
22 | 22 |
|
23 |
+func DetectCompression(source []byte) Compression { |
|
24 |
+ for _, c := range source[:10] { |
|
25 |
+ utils.Debugf("%x", c) |
|
26 |
+ } |
|
27 |
+ |
|
28 |
+ sourceLen := len(source) |
|
29 |
+ for compression, m := range map[Compression][]byte{ |
|
30 |
+ Bzip2: {0x42, 0x5A, 0x68}, |
|
31 |
+ Gzip: {0x1F, 0x8B, 0x08}, |
|
32 |
+ Xz: {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}, |
|
33 |
+ } { |
|
34 |
+ fail := false |
|
35 |
+ if len(m) > sourceLen { |
|
36 |
+ utils.Debugf("Len too short") |
|
37 |
+ continue |
|
38 |
+ } |
|
39 |
+ i := 0 |
|
40 |
+ for _, b := range m { |
|
41 |
+ if b != source[i] { |
|
42 |
+ fail = true |
|
43 |
+ break |
|
44 |
+ } |
|
45 |
+ i++ |
|
46 |
+ } |
|
47 |
+ if !fail { |
|
48 |
+ return compression |
|
49 |
+ } |
|
50 |
+ } |
|
51 |
+ return Uncompressed |
|
52 |
+} |
|
53 |
+ |
|
23 | 54 |
func (compression *Compression) Flag() string { |
24 | 55 |
switch *compression { |
25 | 56 |
case Bzip2: |
... | ... |
@@ -47,12 +80,21 @@ func (compression *Compression) Extension() string { |
47 | 47 |
} |
48 | 48 |
|
49 | 49 |
func Tar(path string, compression Compression) (io.Reader, error) { |
50 |
- cmd := exec.Command("bsdtar", "-f", "-", "-C", path, "-c"+compression.Flag(), ".") |
|
51 |
- return CmdStream(cmd) |
|
50 |
+ return CmdStream(exec.Command("tar", "-f", "-", "-C", path, "-c"+compression.Flag(), ".")) |
|
52 | 51 |
} |
53 | 52 |
|
54 | 53 |
func Untar(archive io.Reader, path string) error { |
55 |
- cmd := exec.Command("bsdtar", "-f", "-", "-C", path, "-x") |
|
54 |
+ |
|
55 |
+ buf := make([]byte, 10) |
|
56 |
+ if _, err := archive.Read(buf); err != nil { |
|
57 |
+ return err |
|
58 |
+ } |
|
59 |
+ compression := DetectCompression(buf) |
|
60 |
+ archive = io.MultiReader(bytes.NewReader(buf), archive) |
|
61 |
+ |
|
62 |
+ utils.Debugf("Archive compression detected: %s", compression.Extension()) |
|
63 |
+ |
|
64 |
+ cmd := exec.Command("tar", "-f", "-", "-C", path, "-x"+compression.Flag()) |
|
56 | 65 |
cmd.Stdin = archive |
57 | 66 |
// Hardcode locale environment for predictable outcome regardless of host configuration. |
58 | 67 |
// (see https://github.com/dotcloud/docker/issues/355) |