Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
| ... | ... |
@@ -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 |
} |