Forráskód Böngészése

Store tar checksum in separate file

Fixes #10432

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Derek McGowan 10 éve
szülő
commit
e9f6f1a930
3 módosított fájl, 109 hozzáadás és 1 törlés
  1. 9 1
      graph/manifest.go
  2. 82 0
      graph/manifest_test.go
  3. 18 0
      image/image.go

+ 9 - 1
graph/manifest.go

@@ -92,7 +92,10 @@ func (s *TagStore) newManifest(localName, remoteName, tag string) ([]byte, error
 			}
 		}
 
-		checksum := layer.Checksum
+		checksum, err := layer.GetCheckSum(s.graph.ImageRoot(layer.ID))
+		if err != nil {
+			return nil, fmt.Errorf("Error getting image checksum: %s", err)
+		}
 		if tarsum.VersionLabelForChecksum(checksum) != tarsum.Version1.String() {
 			archive, err := layer.TarLayer()
 			if err != nil {
@@ -108,6 +111,11 @@ func (s *TagStore) newManifest(localName, remoteName, tag string) ([]byte, error
 			}
 
 			checksum = tarSum.Sum(nil)
+
+			// Save checksum value
+			if err := layer.SaveCheckSum(s.graph.ImageRoot(layer.ID), checksum); err != nil {
+				return nil, err
+			}
 		}
 
 		jsonData, err := layer.RawJson()

+ 82 - 0
graph/manifest_test.go

@@ -0,0 +1,82 @@
+package graph
+
+import (
+	"encoding/json"
+	"os"
+	"testing"
+
+	"github.com/docker/docker/image"
+	"github.com/docker/docker/registry"
+	"github.com/docker/docker/utils"
+)
+
+const (
+	testManifestImageName    = "testapp"
+	testManifestImageID      = "d821b739e8834ec89ac4469266c3d11515da88fdcbcbdddcbcddb636f54fdde9"
+	testManifestImageIDShort = "d821b739e883"
+	testManifestTag          = "manifesttest"
+)
+
+func TestManifestTarsumCache(t *testing.T) {
+	tmp, err := utils.TestDirectory("")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmp)
+	store := mkTestTagStore(tmp, t)
+	defer store.graph.driver.Cleanup()
+
+	archive, err := fakeTar()
+	if err != nil {
+		t.Fatal(err)
+	}
+	img := &image.Image{ID: testManifestImageID}
+	if err := store.graph.Register(img, archive); err != nil {
+		t.Fatal(err)
+	}
+	if err := store.Set(testManifestImageName, testManifestTag, testManifestImageID, false); err != nil {
+		t.Fatal(err)
+	}
+
+	if cs, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID)); err != nil {
+		t.Fatal(err)
+	} else if cs != "" {
+		t.Fatalf("Non-empty checksum file after register")
+	}
+
+	// Generate manifest
+	payload, err := store.newManifest(testManifestImageName, testManifestImageName, testManifestTag)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	manifestChecksum, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var manifest registry.ManifestData
+	if err := json.Unmarshal(payload, &manifest); err != nil {
+		t.Fatalf("error unmarshalling manifest: %s", err)
+	}
+
+	if len(manifest.FSLayers) != 1 {
+		t.Fatalf("Unexpected number of layers, expecting 1: %d", len(manifest.FSLayers))
+	}
+
+	if manifest.FSLayers[0].BlobSum != manifestChecksum {
+		t.Fatalf("Unexpected blob sum, expecting %q, got %q", manifestChecksum, manifest.FSLayers[0].BlobSum)
+	}
+
+	if len(manifest.History) != 1 {
+		t.Fatalf("Unexpected number of layer history, expecting 1: %d", len(manifest.History))
+	}
+
+	v1compat, err := img.RawJson()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if manifest.History[0].V1Compatibility != string(v1compat) {
+		t.Fatalf("Unexpected json value\nExpected:\n%s\nActual:\n%s", v1compat, manifest.History[0].V1Compatibility)
+	}
+}

+ 18 - 0
image/image.go

@@ -114,6 +114,24 @@ func (img *Image) SaveSize(root string) error {
 	return nil
 }
 
+func (img *Image) SaveCheckSum(root, checksum string) error {
+	if err := ioutil.WriteFile(path.Join(root, "checksum"), []byte(checksum), 0600); err != nil {
+		return fmt.Errorf("Error storing checksum in %s/checksum: %s", root, err)
+	}
+	return nil
+}
+
+func (img *Image) GetCheckSum(root string) (string, error) {
+	cs, err := ioutil.ReadFile(path.Join(root, "checksum"))
+	if err != nil {
+		if os.IsNotExist(err) {
+			return "", nil
+		}
+		return "", err
+	}
+	return string(cs), err
+}
+
 func jsonPath(root string) string {
 	return path.Join(root, "json")
 }