Skip to content

Commit c0e2f4b

Browse files
committed
Try next mirror in case of non-404 errors, too
Signed-off-by: Sebastian Hasler <[email protected]>
1 parent 4f18131 commit c0e2f4b

1 file changed

Lines changed: 23 additions & 12 deletions

File tree

remotes/docker/resolver.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,10 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
229229
}
230230

231231
var (
232-
lastErr error
233-
paths [][]string
234-
dgst = refspec.Digest()
235-
caps = HostCapabilityPull
232+
firstErr error
233+
paths [][]string
234+
dgst = refspec.Digest()
235+
caps = HostCapabilityPull
236236
)
237237

238238
if dgst != "" {
@@ -283,8 +283,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
283283
err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization")
284284
}
285285
// Store the error for referencing later
286-
if lastErr == nil {
287-
lastErr = err
286+
if firstErr == nil {
287+
firstErr = err
288288
}
289289
log.G(ctx).WithError(err).Info("trying next host")
290290
continue // try another host
@@ -296,7 +296,14 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
296296
log.G(ctx).Info("trying next host - response was http.StatusNotFound")
297297
continue
298298
}
299-
return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
299+
if resp.StatusCode > 399 {
300+
// Set firstErr when encountering the first non-404 status code.
301+
if firstErr == nil {
302+
firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status)
303+
}
304+
continue // try another host
305+
}
306+
return "", ocispec.Descriptor{}, errors.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status)
300307
}
301308
size := resp.ContentLength
302309
contentType := getManifestMediaType(resp)
@@ -359,8 +366,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
359366
}
360367
// Prevent resolving to excessively large manifests
361368
if size > MaxManifestSize {
362-
if lastErr == nil {
363-
lastErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref)
369+
if firstErr == nil {
370+
firstErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref)
364371
}
365372
continue
366373
}
@@ -376,11 +383,15 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
376383
}
377384
}
378385

379-
if lastErr == nil {
380-
lastErr = errors.Wrap(errdefs.ErrNotFound, ref)
386+
// If above loop terminates without return, then there was an error.
387+
// "firstErr" contains the first non-404 error. That is, "firstErr == nil"
388+
// means that either no registries were given or each registry returned 404.
389+
390+
if firstErr == nil {
391+
firstErr = errors.Wrap(errdefs.ErrNotFound, ref)
381392
}
382393

383-
return "", ocispec.Descriptor{}, lastErr
394+
return "", ocispec.Descriptor{}, firstErr
384395
}
385396

386397
func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {

0 commit comments

Comments
 (0)