Skip to content

Commit

Permalink
fix: deal with internal error coming from docker registry
Browse files Browse the repository at this point in the history
  • Loading branch information
Skarlso committed Dec 18, 2024
1 parent 6aea1a0 commit aef5987
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
1 change: 1 addition & 0 deletions api/oci/extensions/repositories/ocireg/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ func (r *RepositoryImpl) getResolver(comp string) (oras.Resolver, error) {
return oras.New(oras.ClientOptions{
Client: authClient,
PlainHTTP: r.info.Scheme == "http",
Logger: logger,
}), nil
}

Expand Down
44 changes: 27 additions & 17 deletions api/tech/oras/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"sync"

"github.com/containerd/containerd/errdefs"
"github.com/mandelsoft/logging"
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
oraserr "oras.land/oras-go/v2/errdef"
"oras.land/oras-go/v2/registry/remote"
Expand All @@ -18,13 +19,15 @@ import (
type ClientOptions struct {
Client *auth.Client
PlainHTTP bool
Logger logging.Logger
}

type Client struct {
client *auth.Client
plainHTTP bool
ref string
mu sync.RWMutex
logger logging.Logger
}

var (
Expand All @@ -35,7 +38,7 @@ var (
)

func New(opts ClientOptions) *Client {
return &Client{client: opts.Client, plainHTTP: opts.PlainHTTP}
return &Client{client: opts.Client, plainHTTP: opts.PlainHTTP, logger: opts.Logger}
}

func (c *Client) Fetcher(ctx context.Context, ref string) (Fetcher, error) {
Expand Down Expand Up @@ -127,38 +130,45 @@ func (c *Client) Fetch(ctx context.Context, desc ociv1.Descriptor) (io.ReadClose
c.mu.RLock()
defer c.mu.RUnlock()

c.logger.Trace("beginning fetching descriptor", "desc", desc)

src, err := c.createRepository(c.ref)
if err != nil {
return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err)
}

// oras requires a Resolve to happen before a fetch because
// -1 is an invalid size and results in a content-length mismatch error by design.
// -1 or 0 are invalid sizes and result in a content-length mismatch error by design.
// This is a security consideration on ORAS' side.
// manifest is not set in the descriptor
// For more information (https://github.com/oras-project/oras-go/issues/822#issuecomment-2325622324)
// We explicitly call resolve on manifest first because it might be
// that the mediatype is not set at this point so we don't want ORAS to try to
// select the wrong layer to fetch from.
rdesc, err := src.Manifests().Resolve(ctx, desc.Digest.String())
if errors.Is(err, oraserr.ErrNotFound) {
rdesc, err = src.Blobs().Resolve(ctx, desc.Digest.String())
if desc.Size < 1 || desc.Digest == "" {
c.logger.Trace("description is without size or digest, resolving...", "digest", desc.Digest, "size", desc.Size)
desc, err = src.Manifests().Resolve(ctx, desc.Digest.String())
if err != nil {
return nil, fmt.Errorf("failed to resolve fetch blob %q: %w", desc.Digest.String(), err)
}
var berr error
desc, berr = src.Blobs().Resolve(ctx, desc.Digest.String())
if berr != nil {
// also display the first manifest resolve error
err = errors.Join(err, berr)

delayer := func() (io.ReadCloser, error) {
return src.Blobs().Fetch(ctx, rdesc)
}
return nil, fmt.Errorf("failed to resolve fetch blob %q: %w", desc.Digest.String(), err)
}

return newDelayedReader(delayer)
}
// blob resolve succeeded, return the delayed reader
delayer := func() (io.ReadCloser, error) {
return src.Blobs().Fetch(ctx, desc)
}

if err != nil {
return nil, fmt.Errorf("failed to resolve fetch manifest %q: %w", desc.Digest.String(), err)
return newDelayedReader(delayer)
}
}

// lastly, try a manifest fetch.
fetch, err := src.Fetch(ctx, rdesc)
// manifest resolve succeeded return the reader directly
// mediatype of the descriptor should now be set to the correct type.
fetch, err := src.Fetch(ctx, desc)
if err != nil {
return nil, fmt.Errorf("failed to fetch manifest: %w", err)
}
Expand Down

0 comments on commit aef5987

Please sign in to comment.