Merge pull request #1022 from stevvooe/add-pull-support-for-manifest-list
image: add support for pulling manifest lists/oci indexes
This commit is contained in:
commit
7e3b7dead6
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
|
"github.com/containerd/containerd/log"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
@ -128,32 +129,43 @@ func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor)
|
|||||||
// arbitrary types.
|
// arbitrary types.
|
||||||
func ChildrenHandler(provider content.Provider) HandlerFunc {
|
func ChildrenHandler(provider content.Provider) HandlerFunc {
|
||||||
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
|
var descs []ocispec.Descriptor
|
||||||
switch desc.MediaType {
|
switch desc.MediaType {
|
||||||
case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
|
case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
|
||||||
|
p, err := content.ReadBlob(ctx, provider, desc.Digest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(stevvooe): We just assume oci manifest, for now. There may be
|
||||||
|
// subtle differences from the docker version.
|
||||||
|
var manifest ocispec.Manifest
|
||||||
|
if err := json.Unmarshal(p, &manifest); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
descs = append(descs, manifest.Config)
|
||||||
|
descs = append(descs, manifest.Layers...)
|
||||||
|
case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
||||||
|
p, err := content.ReadBlob(ctx, provider, desc.Digest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var index ocispec.Index
|
||||||
|
if err := json.Unmarshal(p, &index); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
descs = append(descs, index.Manifests...)
|
||||||
case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip,
|
case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip,
|
||||||
MediaTypeDockerSchema2Config:
|
MediaTypeDockerSchema2Config, ocispec.MediaTypeImageLayer,
|
||||||
|
ocispec.MediaTypeImageLayerGzip: // childless data types.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("%v not yet supported", desc.MediaType)
|
log.G(ctx).Warnf("encounted unknown type %v; children may not be fetched", desc.MediaType)
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := content.ReadBlob(ctx, provider, desc.Digest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(stevvooe): We just assume oci manifest, for now. There may be
|
|
||||||
// subtle differences from the docker version.
|
|
||||||
var manifest ocispec.Manifest
|
|
||||||
if err := json.Unmarshal(p, &manifest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var descs []ocispec.Descriptor
|
|
||||||
|
|
||||||
descs = append(descs, manifest.Config)
|
|
||||||
descs = append(descs, manifest.Layers...)
|
|
||||||
|
|
||||||
return descs, nil
|
return descs, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,13 @@ func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string {
|
|||||||
// product of the context, which may include information about the ongoing
|
// product of the context, which may include information about the ongoing
|
||||||
// fetch process.
|
// fetch process.
|
||||||
switch desc.MediaType {
|
switch desc.MediaType {
|
||||||
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest,
|
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
|
||||||
images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
|
||||||
return "manifest-" + desc.Digest.String()
|
return "manifest-" + desc.Digest.String()
|
||||||
case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip:
|
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
||||||
|
return "index-" + desc.Digest.String()
|
||||||
|
case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip,
|
||||||
|
ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip,
|
||||||
|
ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip:
|
||||||
return "layer-" + desc.Digest.String()
|
return "layer-" + desc.Digest.String()
|
||||||
case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig:
|
case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig:
|
||||||
return "config-" + desc.Digest.String()
|
return "config-" + desc.Digest.String()
|
||||||
@ -45,8 +48,6 @@ func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
switch desc.MediaType {
|
switch desc.MediaType {
|
||||||
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
|
||||||
return nil, fmt.Errorf("%v not yet supported", desc.MediaType)
|
|
||||||
case images.MediaTypeDockerSchema1Manifest:
|
case images.MediaTypeDockerSchema1Manifest:
|
||||||
return nil, fmt.Errorf("%v not supported", desc.MediaType)
|
return nil, fmt.Errorf("%v not supported", desc.MediaType)
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user