Improve host fallback behaviour in docker remote
This commit improves the fallback behaviour when resolving and fetching images with multiple hosts. If an error is encountered when resolving and fetching images, and more than one host is being used, we will try the same operation on the next host. The error from the first host is preserved so that if all hosts fail, we can display the error from the first host. fixes #3850 Signed-off-by: Alex Price <aprice@atlassian.com>
This commit is contained in:
@@ -95,41 +95,49 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
|
||||
images.MediaTypeDockerSchema1Manifest,
|
||||
ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex:
|
||||
|
||||
var firstErr error
|
||||
for _, host := range r.hosts {
|
||||
req := r.request(host, http.MethodGet, "manifests", desc.Digest.String())
|
||||
|
||||
rc, err := r.open(ctx, req, desc.MediaType, offset)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
continue // try another host
|
||||
// Store the error for referencing later
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
|
||||
return nil, err
|
||||
continue // try another host
|
||||
}
|
||||
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
return nil, firstErr
|
||||
}
|
||||
|
||||
// Finally use blobs endpoints
|
||||
var firstErr error
|
||||
for _, host := range r.hosts {
|
||||
req := r.request(host, http.MethodGet, "blobs", desc.Digest.String())
|
||||
|
||||
rc, err := r.open(ctx, req, desc.MediaType, offset)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
continue // try another host
|
||||
// Store the error for referencing later
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
|
||||
return nil, err
|
||||
continue // try another host
|
||||
}
|
||||
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
return nil, errors.Wrapf(errdefs.ErrNotFound,
|
||||
"could not fetch content descriptor %v (%v) from remote",
|
||||
desc.Digest, desc.MediaType)
|
||||
if errdefs.IsNotFound(firstErr) {
|
||||
firstErr = errors.Wrapf(errdefs.ErrNotFound,
|
||||
"could not fetch content descriptor %v (%v) from remote",
|
||||
desc.Digest, desc.MediaType)
|
||||
}
|
||||
|
||||
return nil, firstErr
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user