Browse code

Add status message for V2 pull

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

Derek McGowan authored on 2014/10/09 08:14:54
Showing 1 changed files
... ...
@@ -416,6 +416,7 @@ type downloadInfo struct {
416 416
 }
417 417
 
418 418
 func (s *TagStore) pullV2Repository(eng *engine.Engine, r *registry.Session, out io.Writer, localName, remoteName, tag string, sf *utils.StreamFormatter, parallel bool) error {
419
+	var layersDownloaded bool
419 420
 	if tag == "" {
420 421
 		log.Debugf("Pulling tag list from V2 registry for %s", remoteName)
421 422
 		tags, err := r.GetV2RemoteTags(remoteName, nil)
... ...
@@ -423,33 +424,42 @@ func (s *TagStore) pullV2Repository(eng *engine.Engine, r *registry.Session, out
423 423
 			return err
424 424
 		}
425 425
 		for _, t := range tags {
426
-			if err := s.pullV2Tag(eng, r, out, localName, remoteName, t, sf, parallel); err != nil {
426
+			if downloaded, err := s.pullV2Tag(eng, r, out, localName, remoteName, t, sf, parallel); err != nil {
427 427
 				return err
428
+			} else if downloaded {
429
+				layersDownloaded = true
428 430
 			}
429 431
 		}
430 432
 	} else {
431
-		if err := s.pullV2Tag(eng, r, out, localName, remoteName, tag, sf, parallel); err != nil {
433
+		if downloaded, err := s.pullV2Tag(eng, r, out, localName, remoteName, tag, sf, parallel); err != nil {
432 434
 			return err
435
+		} else if downloaded {
436
+			layersDownloaded = true
433 437
 		}
434 438
 	}
435 439
 
440
+	requestedTag := localName
441
+	if len(tag) > 0 {
442
+		requestedTag = localName + ":" + tag
443
+	}
444
+	WriteStatus(requestedTag, out, sf, layersDownloaded)
436 445
 	return nil
437 446
 }
438 447
 
439
-func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Writer, localName, remoteName, tag string, sf *utils.StreamFormatter, parallel bool) error {
448
+func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Writer, localName, remoteName, tag string, sf *utils.StreamFormatter, parallel bool) (bool, error) {
440 449
 	log.Debugf("Pulling tag from V2 registry: %q", tag)
441 450
 	manifestBytes, err := r.GetV2ImageManifest(remoteName, tag, nil)
442 451
 	if err != nil {
443
-		return err
452
+		return false, err
444 453
 	}
445 454
 
446 455
 	manifest, verified, err := s.verifyManifest(eng, manifestBytes)
447 456
 	if err != nil {
448
-		return fmt.Errorf("error verifying manifest: %s", err)
457
+		return false, fmt.Errorf("error verifying manifest: %s", err)
449 458
 	}
450 459
 
451 460
 	if len(manifest.BlobSums) != len(manifest.History) {
452
-		return fmt.Errorf("length of history not equal to number of layers")
461
+		return false, fmt.Errorf("length of history not equal to number of layers")
453 462
 	}
454 463
 
455 464
 	if verified {
... ...
@@ -459,7 +469,7 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
459 459
 	}
460 460
 
461 461
 	if len(manifest.BlobSums) == 0 {
462
-		return fmt.Errorf("no blobSums in manifest")
462
+		return false, fmt.Errorf("no blobSums in manifest")
463 463
 	}
464 464
 
465 465
 	downloads := make([]downloadInfo, len(manifest.BlobSums))
... ...
@@ -472,7 +482,7 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
472 472
 
473 473
 		img, err := image.NewImgJSON(imgJSON)
474 474
 		if err != nil {
475
-			return fmt.Errorf("failed to parse json: %s", err)
475
+			return false, fmt.Errorf("failed to parse json: %s", err)
476 476
 		}
477 477
 		downloads[i].img = img
478 478
 
... ...
@@ -484,7 +494,7 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
484 484
 
485 485
 		chunks := strings.SplitN(sumStr, ":", 2)
486 486
 		if len(chunks) < 2 {
487
-			return fmt.Errorf("expected 2 parts in the sumStr, got %#v", chunks)
487
+			return false, fmt.Errorf("expected 2 parts in the sumStr, got %#v", chunks)
488 488
 		}
489 489
 		sumType, checksum := chunks[0], chunks[1]
490 490
 		out.Write(sf.FormatProgress(utils.TruncateID(img.ID), "Pulling fs layer", nil))
... ...
@@ -534,17 +544,18 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
534 534
 		} else {
535 535
 			err := downloadFunc(&downloads[i])
536 536
 			if err != nil {
537
-				return err
537
+				return false, err
538 538
 			}
539 539
 		}
540 540
 	}
541 541
 
542
+	var layersDownloaded bool
542 543
 	for i := len(downloads) - 1; i >= 0; i-- {
543 544
 		d := &downloads[i]
544 545
 		if d.err != nil {
545 546
 			err := <-d.err
546 547
 			if err != nil {
547
-				return err
548
+				return false, err
548 549
 			}
549 550
 		}
550 551
 		if d.downloaded {
... ...
@@ -556,13 +567,13 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
556 556
 				err = s.graph.Register(d.img, d.imgJSON,
557 557
 					utils.ProgressReader(d.tmpFile, int(d.length), out, sf, false, utils.TruncateID(d.img.ID), "Extracting"))
558 558
 				if err != nil {
559
-					return err
559
+					return false, err
560 560
 				}
561 561
 
562 562
 				// FIXME: Pool release here for parallel tag pull (ensures any downloads block until fully extracted)
563 563
 			}
564 564
 			out.Write(sf.FormatProgress(utils.TruncateID(d.img.ID), "Pull complete", nil))
565
-
565
+			layersDownloaded = true
566 566
 		} else {
567 567
 			out.Write(sf.FormatProgress(utils.TruncateID(d.img.ID), "Already exists", nil))
568 568
 		}
... ...
@@ -570,8 +581,8 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
570 570
 	}
571 571
 
572 572
 	if err = s.Set(localName, tag, downloads[0].img.ID, true); err != nil {
573
-		return err
573
+		return false, err
574 574
 	}
575 575
 
576
-	return nil
576
+	return layersDownloaded, nil
577 577
 }