Browse code

Respect tar entries modes when rewriting them on Windows

Previously, only perm-related bits where preserved when rewriting
FileMode in tar entries on Windows. This had the nasty side effect of
having tarsum returning different values when executing from a tar filed
produced on Windows or Linux.

This fix the issue, and pave the way for incremental build context
to work in hybrid contexts.

Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>

Simon Ferquel authored on 2017/05/02 18:36:43
Showing 3 changed files
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"io/ioutil"
5 5
 	"os"
6 6
 	"path/filepath"
7
-	"runtime"
8 7
 	"testing"
9 8
 
10 9
 	"github.com/docker/docker/builder"
... ...
@@ -48,7 +47,7 @@ func TestHashFile(t *testing.T) {
48 48
 	contextDir, cleanup := createTestTempDir(t, "", "builder-tarsum-test")
49 49
 	defer cleanup()
50 50
 
51
-	createTestTempFile(t, contextDir, filename, contents, 0777)
51
+	createTestTempFile(t, contextDir, filename, contents, 0755)
52 52
 
53 53
 	tarSum := makeTestTarsumContext(t, contextDir)
54 54
 
... ...
@@ -63,9 +62,6 @@ func TestHashFile(t *testing.T) {
63 63
 	}
64 64
 
65 65
 	expected := "1149ab94af7be6cc1da1335e398f24ee1cf4926b720044d229969dfc248ae7ec"
66
-	if runtime.GOOS == "windows" {
67
-		expected = "55dfeb344351ab27f59aa60ebb0ed12025a2f2f4677bf77d26ea7a671274a9ca"
68
-	}
69 66
 
70 67
 	if actual := sum; expected != actual {
71 68
 		t.Fatalf("invalid checksum. expected %s, got %s", expected, actual)
... ...
@@ -77,12 +73,12 @@ func TestHashSubdir(t *testing.T) {
77 77
 	defer cleanup()
78 78
 
79 79
 	contextSubdir := filepath.Join(contextDir, "builder-tarsum-test-subdir")
80
-	err := os.Mkdir(contextSubdir, 0700)
80
+	err := os.Mkdir(contextSubdir, 0755)
81 81
 	if err != nil {
82 82
 		t.Fatalf("Failed to make directory: %s", contextSubdir)
83 83
 	}
84 84
 
85
-	testFilename := createTestTempFile(t, contextSubdir, filename, contents, 0777)
85
+	testFilename := createTestTempFile(t, contextSubdir, filename, contents, 0755)
86 86
 
87 87
 	tarSum := makeTestTarsumContext(t, contextDir)
88 88
 
... ...
@@ -103,9 +99,6 @@ func TestHashSubdir(t *testing.T) {
103 103
 	}
104 104
 
105 105
 	expected := "d7f8d6353dee4816f9134f4156bf6a9d470fdadfb5d89213721f7e86744a4e69"
106
-	if runtime.GOOS == "windows" {
107
-		expected = "74a3326b8e766ce63a8e5232f22e9dd895be647fb3ca7d337e5e0a9b3da8ef28"
108
-	}
109 106
 
110 107
 	if actual := sum; expected != actual {
111 108
 		t.Fatalf("invalid checksum. expected %s, got %s", expected, actual)
... ...
@@ -42,11 +42,14 @@ func CanonicalTarNameForPath(p string) (string, error) {
42 42
 // chmodTarEntry is used to adjust the file permissions used in tar header based
43 43
 // on the platform the archival is done.
44 44
 func chmodTarEntry(perm os.FileMode) os.FileMode {
45
-	perm &= 0755
45
+	//perm &= 0755 // this 0-ed out tar flags (like link, regular file, directory marker etc.)
46
+	permPart := perm & os.ModePerm
47
+	noPermPart := perm &^ os.ModePerm
46 48
 	// Add the x bit: make everything +x from windows
47
-	perm |= 0111
49
+	permPart |= 0111
50
+	permPart &= 0755
48 51
 
49
-	return perm
52
+	return noPermPart | permPart
50 53
 }
51 54
 
52 55
 func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (err error) {
... ...
@@ -82,6 +82,8 @@ func TestChmodTarEntry(t *testing.T) {
82 82
 		{0644, 0755},
83 83
 		{0755, 0755},
84 84
 		{0444, 0555},
85
+		{0755 | os.ModeDir, 0755 | os.ModeDir},
86
+		{0755 | os.ModeSymlink, 0755 | os.ModeSymlink},
85 87
 	}
86 88
 	for _, v := range cases {
87 89
 		if out := chmodTarEntry(v.in); out != v.expected {