@@ -14,6 +14,7 @@ import (
1414 "github.com/containerd/containerd/platforms"
1515 "github.com/docker/distribution"
1616 "github.com/docker/distribution/manifest/manifestlist"
17+ "github.com/docker/distribution/manifest/ocischema"
1718 "github.com/docker/distribution/manifest/schema1"
1819 "github.com/docker/distribution/manifest/schema2"
1920 "github.com/docker/distribution/reference"
@@ -410,6 +411,11 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform
410411 if err != nil {
411412 return false , err
412413 }
414+ case * ocischema.DeserializedManifest :
415+ id , manifestDigest , err = p .pullOCI (ctx , ref , v , platform )
416+ if err != nil {
417+ return false , err
418+ }
413419 case * manifestlist.DeserializedManifestList :
414420 id , manifestDigest , err = p .pullManifestList (ctx , ref , v , platform )
415421 if err != nil {
@@ -557,24 +563,18 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unv
557563 return imageID , manifestDigest , nil
558564}
559565
560- func (p * v2Puller ) pullSchema2 (ctx context.Context , ref reference.Named , mfst * schema2.DeserializedManifest , platform * specs.Platform ) (id digest.Digest , manifestDigest digest.Digest , err error ) {
561- manifestDigest , err = schema2ManifestDigest (ref , mfst )
562- if err != nil {
563- return "" , "" , err
564- }
565-
566- target := mfst .Target ()
566+ func (p * v2Puller ) pullSchema2Layers (ctx context.Context , target distribution.Descriptor , layers []distribution.Descriptor , platform * specs.Platform ) (id digest.Digest , err error ) {
567567 if _ , err := p .config .ImageStore .Get (target .Digest ); err == nil {
568568 // If the image already exists locally, no need to pull
569569 // anything.
570- return target .Digest , manifestDigest , nil
570+ return target .Digest , nil
571571 }
572572
573573 var descriptors []xfer.DownloadDescriptor
574574
575575 // Note that the order of this loop is in the direction of bottom-most
576576 // to top-most, so that the downloads slice gets ordered correctly.
577- for _ , d := range mfst . Layers {
577+ for _ , d := range layers {
578578 layerDescriptor := & v2LayerDescriptor {
579579 digest : d .Digest ,
580580 repo : p .repo ,
@@ -629,23 +629,23 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
629629 if runtime .GOOS == "windows" {
630630 configJSON , configRootFS , configPlatform , err = receiveConfig (p .config .ImageStore , configChan , configErrChan )
631631 if err != nil {
632- return "" , "" , err
632+ return "" , err
633633 }
634634 if configRootFS == nil {
635- return "" , "" , errRootFSInvalid
635+ return "" , errRootFSInvalid
636636 }
637637 if err := checkImageCompatibility (configPlatform .OS , configPlatform .OSVersion ); err != nil {
638- return "" , "" , err
638+ return "" , err
639639 }
640640
641641 if len (descriptors ) != len (configRootFS .DiffIDs ) {
642- return "" , "" , errRootFSMismatch
642+ return "" , errRootFSMismatch
643643 }
644644 if platform == nil {
645645 // Early bath if the requested OS doesn't match that of the configuration.
646646 // This avoids doing the download, only to potentially fail later.
647647 if ! system .IsOSSupported (configPlatform .OS ) {
648- return "" , "" , fmt .Errorf ("cannot download image with operating system %q when requesting %q" , configPlatform .OS , layerStoreOS )
648+ return "" , fmt .Errorf ("cannot download image with operating system %q when requesting %q" , configPlatform .OS , layerStoreOS )
649649 }
650650 layerStoreOS = configPlatform .OS
651651 }
@@ -692,14 +692,14 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
692692 case <- downloadsDone :
693693 case <- layerErrChan :
694694 }
695- return "" , "" , err
695+ return "" , err
696696 }
697697 }
698698
699699 select {
700700 case <- downloadsDone :
701701 case err = <- layerErrChan :
702- return "" , "" , err
702+ return "" , err
703703 }
704704
705705 if release != nil {
@@ -711,22 +711,40 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
711711 // Otherwise the image config could be referencing layers that aren't
712712 // included in the manifest.
713713 if len (downloadedRootFS .DiffIDs ) != len (configRootFS .DiffIDs ) {
714- return "" , "" , errRootFSMismatch
714+ return "" , errRootFSMismatch
715715 }
716716
717717 for i := range downloadedRootFS .DiffIDs {
718718 if downloadedRootFS .DiffIDs [i ] != configRootFS .DiffIDs [i ] {
719- return "" , "" , errRootFSMismatch
719+ return "" , errRootFSMismatch
720720 }
721721 }
722722 }
723723
724724 imageID , err := p .config .ImageStore .Put (configJSON )
725+ if err != nil {
726+ return "" , err
727+ }
728+
729+ return imageID , nil
730+ }
731+
732+ func (p * v2Puller ) pullSchema2 (ctx context.Context , ref reference.Named , mfst * schema2.DeserializedManifest , platform * specs.Platform ) (id digest.Digest , manifestDigest digest.Digest , err error ) {
733+ manifestDigest , err = schema2ManifestDigest (ref , mfst )
725734 if err != nil {
726735 return "" , "" , err
727736 }
737+ id , err = p .pullSchema2Layers (ctx , mfst .Target (), mfst .Layers , platform )
738+ return id , manifestDigest , err
739+ }
728740
729- return imageID , manifestDigest , nil
741+ func (p * v2Puller ) pullOCI (ctx context.Context , ref reference.Named , mfst * ocischema.DeserializedManifest , platform * specs.Platform ) (id digest.Digest , manifestDigest digest.Digest , err error ) {
742+ manifestDigest , err = schema2ManifestDigest (ref , mfst )
743+ if err != nil {
744+ return "" , "" , err
745+ }
746+ id , err = p .pullSchema2Layers (ctx , mfst .Target (), mfst .Layers , platform )
747+ return id , manifestDigest , err
730748}
731749
732750func receiveConfig (s ImageConfigStore , configChan <- chan []byte , errChan <- chan error ) ([]byte , * image.RootFS , * specs.Platform , error ) {
@@ -811,6 +829,12 @@ func (p *v2Puller) pullManifestList(ctx context.Context, ref reference.Named, mf
811829 if err != nil {
812830 return "" , "" , err
813831 }
832+ case * ocischema.DeserializedManifest :
833+ platform := toOCIPlatform (manifestMatches [0 ].Platform )
834+ id , _ , err = p .pullOCI (ctx , manifestRef , v , & platform )
835+ if err != nil {
836+ return "" , "" , err
837+ }
814838 default :
815839 return "" , "" , errors .New ("unsupported manifest format" )
816840 }
0 commit comments