Browse code

Always store images with tarsum.v1 checksum added

Updates `image.StoreImage()` to always ensure that images
that are installed in Docker have a tarsum.v1 checksum.

Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)

Josh Hawn authored on 2015/01/24 02:54:17
Showing 3 changed files
... ...
@@ -81,8 +81,8 @@ func LoadImage(root string) (*Image, error) {
81 81
 
82 82
 // StoreImage stores file system layer data for the given image to the
83 83
 // image's registered storage driver. Image metadata is stored in a file
84
-// at the specified root directory. This function also computes the TarSum
85
-// of `layerData` (currently using tarsum.dev).
84
+// at the specified root directory. This function also computes a checksum
85
+// of `layerData` if the image does not have one already.
86 86
 func StoreImage(img *Image, layerData archive.ArchiveReader, root string) error {
87 87
 	// Store the layer
88 88
 	var (
... ...
@@ -96,15 +96,18 @@ func StoreImage(img *Image, layerData archive.ArchiveReader, root string) error
96 96
 	if layerData != nil {
97 97
 		// If the image doesn't have a checksum, we should add it. The layer
98 98
 		// checksums are verified when they are pulled from a remote, but when
99
-		// a container is committed it should be added here.
100
-		if img.Checksum == "" {
99
+		// a container is committed it should be added here. Also ensure that
100
+		// the stored checksum has the latest version of tarsum (assuming we
101
+		// are using tarsum).
102
+		if tarsum.VersionLabelForChecksum(img.Checksum) != tarsum.Version1.String() {
103
+			// Either there was no checksum or it's not a tarsum.v1
101 104
 			layerDataDecompressed, err := archive.DecompressStream(layerData)
102 105
 			if err != nil {
103 106
 				return err
104 107
 			}
105 108
 			defer layerDataDecompressed.Close()
106 109
 
107
-			if layerTarSum, err = tarsum.NewTarSum(layerDataDecompressed, true, tarsum.VersionDev); err != nil {
110
+			if layerTarSum, err = tarsum.NewTarSum(layerDataDecompressed, true, tarsum.Version1); err != nil {
108 111
 				return err
109 112
 			}
110 113
 
... ...
@@ -122,6 +122,7 @@ type tHashConfig struct {
122 122
 }
123 123
 
124 124
 var (
125
+	// NOTE: DO NOT include MD5 or SHA1, which are considered insecure.
125 126
 	standardHashConfigs = map[string]tHashConfig{
126 127
 		"sha256": {name: "sha256", hash: crypto.SHA256},
127 128
 		"sha512": {name: "sha512", hash: crypto.SHA512},
... ...
@@ -22,6 +22,18 @@ const (
22 22
 	VersionDev
23 23
 )
24 24
 
25
+// VersionLabelForChecksum returns the label for the given tarsum
26
+// checksum, i.e., everything before the first `+` character in
27
+// the string or an empty string if no label separator is found.
28
+func VersionLabelForChecksum(checksum string) string {
29
+	// Checksums are in the form: {versionLabel}+{hashID}:{hex}
30
+	sepIndex := strings.Index(checksum, "+")
31
+	if sepIndex < 0 {
32
+		return ""
33
+	}
34
+	return checksum[:sepIndex]
35
+}
36
+
25 37
 // Get a list of all known tarsum Version
26 38
 func GetVersions() []Version {
27 39
 	v := []Version{}