Browse code

Store tar checksum in separate file

Fixes #10432

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)

Derek McGowan authored on 2015/01/30 14:28:20
Showing 3 changed files
... ...
@@ -92,7 +92,10 @@ func (s *TagStore) newManifest(localName, remoteName, tag string) ([]byte, error
92 92
 			}
93 93
 		}
94 94
 
95
-		checksum := layer.Checksum
95
+		checksum, err := layer.GetCheckSum(s.graph.ImageRoot(layer.ID))
96
+		if err != nil {
97
+			return nil, fmt.Errorf("Error getting image checksum: %s", err)
98
+		}
96 99
 		if tarsum.VersionLabelForChecksum(checksum) != tarsum.Version1.String() {
97 100
 			archive, err := layer.TarLayer()
98 101
 			if err != nil {
... ...
@@ -108,6 +111,11 @@ func (s *TagStore) newManifest(localName, remoteName, tag string) ([]byte, error
108 108
 			}
109 109
 
110 110
 			checksum = tarSum.Sum(nil)
111
+
112
+			// Save checksum value
113
+			if err := layer.SaveCheckSum(s.graph.ImageRoot(layer.ID), checksum); err != nil {
114
+				return nil, err
115
+			}
111 116
 		}
112 117
 
113 118
 		jsonData, err := layer.RawJson()
114 119
new file mode 100644
... ...
@@ -0,0 +1,82 @@
0
+package graph
1
+
2
+import (
3
+	"encoding/json"
4
+	"os"
5
+	"testing"
6
+
7
+	"github.com/docker/docker/image"
8
+	"github.com/docker/docker/registry"
9
+	"github.com/docker/docker/utils"
10
+)
11
+
12
+const (
13
+	testManifestImageName    = "testapp"
14
+	testManifestImageID      = "d821b739e8834ec89ac4469266c3d11515da88fdcbcbdddcbcddb636f54fdde9"
15
+	testManifestImageIDShort = "d821b739e883"
16
+	testManifestTag          = "manifesttest"
17
+)
18
+
19
+func TestManifestTarsumCache(t *testing.T) {
20
+	tmp, err := utils.TestDirectory("")
21
+	if err != nil {
22
+		t.Fatal(err)
23
+	}
24
+	defer os.RemoveAll(tmp)
25
+	store := mkTestTagStore(tmp, t)
26
+	defer store.graph.driver.Cleanup()
27
+
28
+	archive, err := fakeTar()
29
+	if err != nil {
30
+		t.Fatal(err)
31
+	}
32
+	img := &image.Image{ID: testManifestImageID}
33
+	if err := store.graph.Register(img, archive); err != nil {
34
+		t.Fatal(err)
35
+	}
36
+	if err := store.Set(testManifestImageName, testManifestTag, testManifestImageID, false); err != nil {
37
+		t.Fatal(err)
38
+	}
39
+
40
+	if cs, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID)); err != nil {
41
+		t.Fatal(err)
42
+	} else if cs != "" {
43
+		t.Fatalf("Non-empty checksum file after register")
44
+	}
45
+
46
+	// Generate manifest
47
+	payload, err := store.newManifest(testManifestImageName, testManifestImageName, testManifestTag)
48
+	if err != nil {
49
+		t.Fatal(err)
50
+	}
51
+
52
+	manifestChecksum, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID))
53
+	if err != nil {
54
+		t.Fatal(err)
55
+	}
56
+
57
+	var manifest registry.ManifestData
58
+	if err := json.Unmarshal(payload, &manifest); err != nil {
59
+		t.Fatalf("error unmarshalling manifest: %s", err)
60
+	}
61
+
62
+	if len(manifest.FSLayers) != 1 {
63
+		t.Fatalf("Unexpected number of layers, expecting 1: %d", len(manifest.FSLayers))
64
+	}
65
+
66
+	if manifest.FSLayers[0].BlobSum != manifestChecksum {
67
+		t.Fatalf("Unexpected blob sum, expecting %q, got %q", manifestChecksum, manifest.FSLayers[0].BlobSum)
68
+	}
69
+
70
+	if len(manifest.History) != 1 {
71
+		t.Fatalf("Unexpected number of layer history, expecting 1: %d", len(manifest.History))
72
+	}
73
+
74
+	v1compat, err := img.RawJson()
75
+	if err != nil {
76
+		t.Fatal(err)
77
+	}
78
+	if manifest.History[0].V1Compatibility != string(v1compat) {
79
+		t.Fatalf("Unexpected json value\nExpected:\n%s\nActual:\n%s", v1compat, manifest.History[0].V1Compatibility)
80
+	}
81
+}
... ...
@@ -114,6 +114,24 @@ func (img *Image) SaveSize(root string) error {
114 114
 	return nil
115 115
 }
116 116
 
117
+func (img *Image) SaveCheckSum(root, checksum string) error {
118
+	if err := ioutil.WriteFile(path.Join(root, "checksum"), []byte(checksum), 0600); err != nil {
119
+		return fmt.Errorf("Error storing checksum in %s/checksum: %s", root, err)
120
+	}
121
+	return nil
122
+}
123
+
124
+func (img *Image) GetCheckSum(root string) (string, error) {
125
+	cs, err := ioutil.ReadFile(path.Join(root, "checksum"))
126
+	if err != nil {
127
+		if os.IsNotExist(err) {
128
+			return "", nil
129
+		}
130
+		return "", err
131
+	}
132
+	return string(cs), err
133
+}
134
+
117 135
 func jsonPath(root string) string {
118 136
 	return path.Join(root, "json")
119 137
 }