Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit 8a48dc9

Browse files
cpuguy83thaJeztah
authored andcommitted
Use ocischema package instead of custom handler
Previously we were re-using schema2.DeserializedManifest to handle oci manifests. The issue lies in the fact that distribution started validating the media type string during json deserialization. This change broke our usage of that type. Instead distribution now provides direct support for oci schemas, so use that instead of our custom handlers. Signed-off-by: Brian Goff <cpuguy83@gmail.com> (cherry picked from commit e443512ce4799380941374ef64fc30edc989650e) Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Upstream-commit: e037bade8cac920cc2927c194c77778ddd041101 Component: engine
1 parent 5334d2e commit 8a48dc9

4 files changed

Lines changed: 274 additions & 48 deletions

File tree

components/engine/distribution/oci.go

Lines changed: 0 additions & 29 deletions
This file was deleted.

components/engine/distribution/pull_v2.go

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

732750
func 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
}

components/engine/vendor/github.com/docker/distribution/manifest/ocischema/builder.go

Lines changed: 107 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)