Browse code

Remove bsdtar by checking magic

Guillaume J. Charmes authored on 2013/06/14 09:53:38
Showing 1 changed files
... ...
@@ -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)