Merge pull request #8744 from cardyok/bugfix_remote_fetch_mediatype
This commit is contained in:
commit
e7276fe35a
@ -451,7 +451,12 @@ var (
|
||||
Usage: "Retrieve blobs from a remote",
|
||||
ArgsUsage: "[flags] <remote> [<digest>, ...]",
|
||||
Description: `Fetch blobs by digests from a remote.`,
|
||||
Flags: commands.RegistryFlags,
|
||||
Flags: append(commands.RegistryFlags, []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "media-type",
|
||||
Usage: "Specify target mediatype for request header",
|
||||
},
|
||||
}...),
|
||||
Action: func(context *cli.Context) error {
|
||||
var (
|
||||
ref = context.Args().First()
|
||||
@ -486,7 +491,7 @@ var (
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rc, _, err := fetcherByDigest.FetchByDigest(ctx, dgst)
|
||||
rc, _, err := fetcherByDigest.FetchByDigest(ctx, dgst, remotes.WithMediaType(context.String("media-type")))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
@ -151,12 +152,18 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
|
||||
})
|
||||
}
|
||||
|
||||
func (r dockerFetcher) createGetReq(ctx context.Context, host RegistryHost, ps ...string) (*request, int64, error) {
|
||||
func (r dockerFetcher) createGetReq(ctx context.Context, host RegistryHost, mediatype string, ps ...string) (*request, int64, error) {
|
||||
headReq := r.request(host, http.MethodHead, ps...)
|
||||
if err := headReq.addNamespace(r.refspec.Hostname()); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if mediatype == "" {
|
||||
headReq.header.Set("Accept", "*/*")
|
||||
} else {
|
||||
headReq.header.Set("Accept", strings.Join([]string{mediatype, `*/*`}, ", "))
|
||||
}
|
||||
|
||||
headResp, err := headReq.doWithRetries(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
@ -175,9 +182,15 @@ func (r dockerFetcher) createGetReq(ctx context.Context, host RegistryHost, ps .
|
||||
return getReq, headResp.ContentLength, nil
|
||||
}
|
||||
|
||||
func (r dockerFetcher) FetchByDigest(ctx context.Context, dgst digest.Digest) (io.ReadCloser, ocispec.Descriptor, error) {
|
||||
func (r dockerFetcher) FetchByDigest(ctx context.Context, dgst digest.Digest, opts ...remotes.FetchByDigestOpts) (io.ReadCloser, ocispec.Descriptor, error) {
|
||||
var desc ocispec.Descriptor
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithField("digest", dgst))
|
||||
var config remotes.FetchByDigestConfig
|
||||
for _, o := range opts {
|
||||
if err := o(ctx, &config); err != nil {
|
||||
return nil, desc, err
|
||||
}
|
||||
}
|
||||
|
||||
hosts := r.filterHosts(HostCapabilityPull)
|
||||
if len(hosts) == 0 {
|
||||
@ -196,7 +209,7 @@ func (r dockerFetcher) FetchByDigest(ctx context.Context, dgst digest.Digest) (i
|
||||
)
|
||||
|
||||
for _, host := range r.hosts {
|
||||
getReq, sz, err = r.createGetReq(ctx, host, "blobs", dgst.String())
|
||||
getReq, sz, err = r.createGetReq(ctx, host, config.Mediatype, "blobs", dgst.String())
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
@ -209,7 +222,7 @@ func (r dockerFetcher) FetchByDigest(ctx context.Context, dgst digest.Digest) (i
|
||||
if getReq == nil {
|
||||
// Fall back to the "manifests" endpoint
|
||||
for _, host := range r.hosts {
|
||||
getReq, sz, err = r.createGetReq(ctx, host, "manifests", dgst.String())
|
||||
getReq, sz, err = r.createGetReq(ctx, host, config.Mediatype, "manifests", dgst.String())
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
@ -231,7 +244,7 @@ func (r dockerFetcher) FetchByDigest(ctx context.Context, dgst digest.Digest) (i
|
||||
}
|
||||
|
||||
seeker, err := newHTTPReadSeeker(sz, func(offset int64) (io.ReadCloser, error) {
|
||||
return r.open(ctx, getReq, "", offset)
|
||||
return r.open(ctx, getReq, config.Mediatype, offset)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, desc, err
|
||||
|
@ -65,7 +65,7 @@ type FetcherByDigest interface {
|
||||
// FetcherByDigest usually returns an incomplete descriptor.
|
||||
// Typically, the media type is always set to "application/octet-stream",
|
||||
// and the annotations are unset.
|
||||
FetchByDigest(ctx context.Context, dgst digest.Digest) (io.ReadCloser, ocispec.Descriptor, error)
|
||||
FetchByDigest(ctx context.Context, dgst digest.Digest, opts ...FetchByDigestOpts) (io.ReadCloser, ocispec.Descriptor, error)
|
||||
}
|
||||
|
||||
// Pusher pushes content
|
||||
@ -92,3 +92,20 @@ type PusherFunc func(ctx context.Context, desc ocispec.Descriptor) (content.Writ
|
||||
func (fn PusherFunc) Push(ctx context.Context, desc ocispec.Descriptor) (content.Writer, error) {
|
||||
return fn(ctx, desc)
|
||||
}
|
||||
|
||||
// FetchByDigestConfig provides configuration for fetching content by digest
|
||||
type FetchByDigestConfig struct {
|
||||
//Mediatype specifies mediatype header to append for fetch request
|
||||
Mediatype string
|
||||
}
|
||||
|
||||
// FetchByDigestOpts allows callers to set options for fetch object
|
||||
type FetchByDigestOpts func(context.Context, *FetchByDigestConfig) error
|
||||
|
||||
// WithMediaType sets the media type header for fetch request
|
||||
func WithMediaType(mediatype string) FetchByDigestOpts {
|
||||
return func(ctx context.Context, cfg *FetchByDigestConfig) error {
|
||||
cfg.Mediatype = mediatype
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user