2017-03-17 21:46:25 +00:00
|
|
|
package remotes
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/Sirupsen/logrus"
|
2017-04-03 20:14:15 +00:00
|
|
|
"github.com/containerd/containerd/content"
|
|
|
|
"github.com/containerd/containerd/images"
|
|
|
|
"github.com/containerd/containerd/log"
|
2017-03-17 21:46:25 +00:00
|
|
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
// MakeRef returns a unique reference for the descriptor. This reference can be
|
|
|
|
// used to lookup ongoing processes related to the descriptor. This function
|
|
|
|
// may look to the context to namespace the reference appropriately.
|
|
|
|
func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string {
|
|
|
|
// TODO(stevvooe): Need better remote key selection here. Should be a
|
|
|
|
// product of the context, which may include information about the ongoing
|
|
|
|
// fetch process.
|
|
|
|
switch desc.MediaType {
|
2017-03-22 00:36:37 +00:00
|
|
|
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest,
|
|
|
|
images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
2017-03-17 21:46:25 +00:00
|
|
|
return "manifest-" + desc.Digest.String()
|
2017-03-22 00:36:37 +00:00
|
|
|
case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip:
|
2017-03-17 21:46:25 +00:00
|
|
|
return "layer-" + desc.Digest.String()
|
|
|
|
case "application/vnd.docker.container.image.v1+json":
|
|
|
|
return "config-" + desc.Digest.String()
|
|
|
|
default:
|
|
|
|
log.G(ctx).Warnf("reference for unknown type: %s", desc.MediaType)
|
|
|
|
return "unknown-" + desc.Digest.String()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FetchHandler returns a handler that will fetch all content into the ingester
|
|
|
|
// discovered in a call to Dispatch. Use with ChildrenHandler to do a full
|
|
|
|
// recursive fetch.
|
2017-03-22 00:36:37 +00:00
|
|
|
func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc {
|
2017-03-17 21:46:25 +00:00
|
|
|
return func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) {
|
|
|
|
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{
|
|
|
|
"digest": desc.Digest,
|
|
|
|
"mediatype": desc.MediaType,
|
|
|
|
"size": desc.Size,
|
|
|
|
}))
|
|
|
|
|
|
|
|
switch desc.MediaType {
|
2017-03-22 00:36:37 +00:00
|
|
|
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
2017-03-17 21:46:25 +00:00
|
|
|
return nil, fmt.Errorf("%v not yet supported", desc.MediaType)
|
|
|
|
default:
|
|
|
|
err := fetch(ctx, ingester, fetcher, desc)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error {
|
|
|
|
log.G(ctx).Debug("fetch")
|
|
|
|
ref := MakeRefKey(ctx, desc)
|
|
|
|
rc, err := fetcher.Fetch(ctx, desc)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer rc.Close()
|
|
|
|
|
|
|
|
return content.WriteBlob(ctx, ingester, ref, rc, desc.Size, desc.Digest)
|
|
|
|
}
|