Browse code

Merge pull request #8964 from jlhawn/image_checksum

Compute TarSum on storage of image layer content

Michael Crosby authored on 2014/11/14 11:07:20
Showing 2 changed files
... ...
@@ -150,6 +150,7 @@ func (s *TagStore) CmdLookup(job *engine.Job) engine.Status {
150 150
 		out.Set("Os", image.OS)
151 151
 		out.SetInt64("Size", image.Size)
152 152
 		out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size)
153
+		out.Set("Checksum", image.Checksum)
153 154
 		if _, err = out.WriteTo(job.Stdout); err != nil {
154 155
 			return job.Error(err)
155 156
 		}
... ...
@@ -11,6 +11,7 @@ import (
11 11
 
12 12
 	log "github.com/Sirupsen/logrus"
13 13
 	"github.com/docker/docker/pkg/archive"
14
+	"github.com/docker/docker/pkg/tarsum"
14 15
 	"github.com/docker/docker/runconfig"
15 16
 	"github.com/docker/docker/utils"
16 17
 )
... ...
@@ -32,6 +33,7 @@ type Image struct {
32 32
 	Config          *runconfig.Config `json:"config,omitempty"`
33 33
 	Architecture    string            `json:"architecture,omitempty"`
34 34
 	OS              string            `json:"os,omitempty"`
35
+	Checksum        string            `json:"checksum"`
35 36
 	Size            int64
36 37
 
37 38
 	graph Graph
... ...
@@ -77,19 +79,43 @@ func LoadImage(root string) (*Image, error) {
77 77
 	return img, nil
78 78
 }
79 79
 
80
+// StoreImage stores file system layer data for the given image to the
81
+// image's registered storage driver. Image metadata is stored in a file
82
+// at the specified root directory. This function also computes the TarSum
83
+// of `layerData` (currently using tarsum.dev).
80 84
 func StoreImage(img *Image, layerData archive.ArchiveReader, root string) error {
81 85
 	// Store the layer
82 86
 	var (
83
-		size   int64
84
-		err    error
85
-		driver = img.graph.Driver()
87
+		size        int64
88
+		err         error
89
+		driver      = img.graph.Driver()
90
+		layerTarSum tarsum.TarSum
86 91
 	)
87 92
 
88 93
 	// If layerData is not nil, unpack it into the new layer
89 94
 	if layerData != nil {
90
-		if size, err = driver.ApplyDiff(img.ID, img.Parent, layerData); err != nil {
95
+		layerDataDecompressed, err := archive.DecompressStream(layerData)
96
+		if err != nil {
91 97
 			return err
92 98
 		}
99
+
100
+		defer layerDataDecompressed.Close()
101
+
102
+		if layerTarSum, err = tarsum.NewTarSum(layerDataDecompressed, true, tarsum.VersionDev); err != nil {
103
+			return err
104
+		}
105
+
106
+		if size, err = driver.ApplyDiff(img.ID, img.Parent, layerTarSum); err != nil {
107
+			return err
108
+		}
109
+
110
+		checksum := layerTarSum.Sum(nil)
111
+
112
+		if img.Checksum != "" && img.Checksum != checksum {
113
+			log.Warn("image layer checksum mismatch: computed %q, expected %q", checksum, img.Checksum)
114
+		}
115
+
116
+		img.Checksum = checksum
93 117
 	}
94 118
 
95 119
 	img.Size = size