Browse code

Factorize the checksums functions

Guillaume J. Charmes authored on 2013/05/09 14:37:33
Showing 3 changed files
... ...
@@ -1,6 +1,7 @@
1 1
 package docker
2 2
 
3 3
 import (
4
+	"encoding/json"
4 5
 	"fmt"
5 6
 	"io"
6 7
 	"io/ioutil"
... ...
@@ -300,3 +301,26 @@ func (graph *Graph) Heads() (map[string]*Image, error) {
300 300
 func (graph *Graph) imageRoot(id string) string {
301 301
 	return path.Join(graph.Root, id)
302 302
 }
303
+
304
+func (graph *Graph) getStoredChecksums() (map[string]string, error) {
305
+	checksums := make(map[string]string)
306
+	// FIXME: Store the checksum in memory
307
+
308
+	if checksumDict, err := ioutil.ReadFile(path.Join(graph.Root, "checksums")); err == nil {
309
+		if err := json.Unmarshal(checksumDict, &checksums); err != nil {
310
+			return nil, err
311
+		}
312
+	}
313
+	return checksums, nil
314
+}
315
+
316
+func (graph *Graph) storeChecksums(checksums map[string]string) error {
317
+	checksumJson, err := json.Marshal(checksums)
318
+	if err != nil {
319
+		return err
320
+	}
321
+	if err := ioutil.WriteFile(path.Join(graph.Root, "checksums"), checksumJson, 0600); err != nil {
322
+		return err
323
+	}
324
+	return nil
325
+}
... ...
@@ -295,16 +295,12 @@ func (img *Image) Checksum() (string, error) {
295 295
 		return "", err
296 296
 	}
297 297
 
298
-	checksumDictPth := path.Join(root, "..", "..", "checksums")
299
-	checksums := make(map[string]string)
300
-
301
-	if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
302
-		if err := json.Unmarshal(checksumDict, &checksums); err != nil {
303
-			return "", err
304
-		}
305
-		if checksum, ok := checksums[img.Id]; ok {
306
-			return checksum, nil
307
-		}
298
+	checksums, err := img.graph.getStoredChecksums()
299
+	if err != nil {
300
+		return "", err
301
+	}
302
+	if checksum, ok := checksums[img.Id]; ok {
303
+		return checksum, nil
308 304
 	}
309 305
 
310 306
 	layer, err := img.layer()
... ...
@@ -343,24 +339,23 @@ func (img *Image) Checksum() (string, error) {
343 343
 	if _, err := io.Copy(h, layerData); err != nil {
344 344
 		return "", err
345 345
 	}
346
-
347 346
 	hash := "sha256:" + hex.EncodeToString(h.Sum(nil))
348
-	checksums[img.Id] = hash
349 347
 
350 348
 	// Reload the json file to make sure not to overwrite faster sums
351 349
 	img.graph.lockSumFile.Lock()
352 350
 	defer img.graph.lockSumFile.Unlock()
353
-	if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
354
-		if err := json.Unmarshal(checksumDict, &checksums); err != nil {
355
-			return "", err
356
-		}
357
-	}
358
-	checksumJson, err := json.Marshal(checksums)
351
+
352
+	checksums, err = img.graph.getStoredChecksums()
359 353
 	if err != nil {
360
-		return hash, err
354
+		return "", err
361 355
 	}
362
-	if err := ioutil.WriteFile(checksumDictPth, checksumJson, 0600); err != nil {
356
+
357
+	checksums[img.Id] = hash
358
+
359
+	// Dump the checksums to disc
360
+	if err := img.graph.storeChecksums(checksums); err != nil {
363 361
 		return hash, err
364 362
 	}
363
+
365 364
 	return hash, nil
366 365
 }
... ...
@@ -578,6 +578,24 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re
578 578
 	return filteredRepo, nil
579 579
 }
580 580
 
581
+// Retrieve the checksum of an image
582
+// Priority:
583
+// - Check on the stored checksums
584
+// - Check if the archive is exists, if it does not, ask the registry
585
+// - If the archive does exists, process the checksum from it
586
+// - If the archive does not exists and not found on registry, process checksum from layer
587
+func (graph *Graph) getChecksum(imageId string) (string, error) {
588
+	img, err := graph.Get(imageId)
589
+	if err != nil {
590
+		return "", err
591
+	}
592
+	checksum, err := img.Checksum()
593
+	if err != nil {
594
+		return "", err
595
+	}
596
+	return checksum, nil
597
+}
598
+
581 599
 type ImgListJson struct {
582 600
 	Id       string `json:"id"`
583 601
 	Checksum string `json:"checksum,omitempty"`
... ...
@@ -592,7 +610,14 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re
592 592
 	var imgList []*ImgListJson
593 593
 
594 594
 	for _, id := range localRepo {
595
-		imgList = append(imgList, &ImgListJson{Id: id})
595
+		checksum, err := graph.getChecksum(id)
596
+		if err != nil {
597
+			return err
598
+		}
599
+		imgList = append(imgList, &ImgListJson{
600
+			Id:       id,
601
+			Checksum: checksum,
602
+		})
596 603
 	}
597 604
 
598 605
 	imgListJson, err := json.Marshal(imgList)
... ...
@@ -666,21 +691,6 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re
666 666
 		}
667 667
 	}
668 668
 
669
-	for _, elem := range imgList {
670
-		img, err := graph.Get(elem.Id)
671
-		if err != nil {
672
-			return err
673
-		}
674
-		if elem.Checksum, err = img.Checksum(); err != nil {
675
-			return err
676
-		}
677
-	}
678
-	imgListJson, err = json.Marshal(imgList)
679
-	if err != nil {
680
-		return err
681
-	}
682
-	Debugf("json sent: %s\n", imgListJson)
683
-
684 669
 	req2, err := http.NewRequest("PUT", INDEX_ENDPOINT+"/repositories/"+remote+"/images", bytes.NewReader(imgListJson))
685 670
 	if err != nil {
686 671
 		return err