Revert reporting of multiple pull errors

Revert the portions of #17617 that report all errors when a pull
falls back, and go back to just reporting the last error. This was nice
to have, but causes some UX issues because nonexistent images show
additional "unauthorized" errors.

Keep the part of the PR that handled ENOSPC, as this appears to work
even without tracking multiple errors.

Fixes #19419

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Aaron Lehmann 2016-01-18 14:17:39 -08:00
parent a495c148a5
commit 87338bf0fa
3 changed files with 12 additions and 31 deletions

View File

@ -3,7 +3,6 @@ package distribution
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/docker/docker/api" "github.com/docker/docker/api"
@ -97,13 +96,12 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
} }
var ( var (
// use a slice to append the error strings and return a joined string to caller lastErr error
errors []string
// discardNoSupportErrors is used to track whether an endpoint encountered an error of type registry.ErrNoSupport // discardNoSupportErrors is used to track whether an endpoint encountered an error of type registry.ErrNoSupport
// By default it is false, which means that if a ErrNoSupport error is encountered, it will be saved in errors. // By default it is false, which means that if a ErrNoSupport error is encountered, it will be saved in lastErr.
// As soon as another kind of error is encountered, discardNoSupportErrors is set to true, avoiding the saving of // As soon as another kind of error is encountered, discardNoSupportErrors is set to true, avoiding the saving of
// any subsequent ErrNoSupport errors in errors. // any subsequent ErrNoSupport errors in lastErr.
// It's needed for pull-by-digest on v1 endpoints: if there are only v1 endpoints configured, the error should be // It's needed for pull-by-digest on v1 endpoints: if there are only v1 endpoints configured, the error should be
// returned and displayed, but if there was a v2 endpoint which supports pull-by-digest, then the last relevant // returned and displayed, but if there was a v2 endpoint which supports pull-by-digest, then the last relevant
// error is the ones from v2 endpoints not v1. // error is the ones from v2 endpoints not v1.
@ -123,7 +121,7 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
puller, err := newPuller(endpoint, repoInfo, imagePullConfig) puller, err := newPuller(endpoint, repoInfo, imagePullConfig)
if err != nil { if err != nil {
errors = append(errors, err.Error()) lastErr = err
continue continue
} }
if err := puller.Pull(ctx, ref); err != nil { if err := puller.Pull(ctx, ref); err != nil {
@ -144,34 +142,28 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
// Because we found an error that's not ErrNoSupport, discard all subsequent ErrNoSupport errors. // Because we found an error that's not ErrNoSupport, discard all subsequent ErrNoSupport errors.
discardNoSupportErrors = true discardNoSupportErrors = true
// append subsequent errors // append subsequent errors
errors = append(errors, err.Error()) lastErr = err
} else if !discardNoSupportErrors { } else if !discardNoSupportErrors {
// Save the ErrNoSupport error, because it's either the first error or all encountered errors // Save the ErrNoSupport error, because it's either the first error or all encountered errors
// were also ErrNoSupport errors. // were also ErrNoSupport errors.
// append subsequent errors // append subsequent errors
errors = append(errors, err.Error()) lastErr = err
} }
continue continue
} }
errors = append(errors, err.Error()) logrus.Debugf("Not continuing with error: %v", err)
logrus.Debugf("Not continuing with error: %v", fmt.Errorf(strings.Join(errors, "\n"))) return err
if len(errors) > 0 {
return fmt.Errorf(strings.Join(errors, "\n"))
}
} }
imagePullConfig.ImageEventLogger(ref.String(), repoInfo.Name(), "pull") imagePullConfig.ImageEventLogger(ref.String(), repoInfo.Name(), "pull")
return nil return nil
} }
if len(errors) == 0 { if lastErr == nil {
return fmt.Errorf("no endpoints found for %s", ref.String()) lastErr = fmt.Errorf("no endpoints found for %s", ref.String())
} }
if len(errors) > 0 { return lastErr
return fmt.Errorf(strings.Join(errors, "\n"))
}
return nil
} }
// writeStatus writes a status message to out. If layersDownloaded is true, the // writeStatus writes a status message to out. If layersDownloaded is true, the

View File

@ -279,18 +279,6 @@ func (s *DockerSchema1RegistrySuite) TestPullIDStability(c *check.C) {
testPullIDStability(c) testPullIDStability(c)
} }
// TestPullFallbackOn404 tries to pull a nonexistent manifest and confirms that
// the pull falls back to the v1 protocol.
//
// Ref: docker/docker#18832
func (s *DockerRegistrySuite) TestPullFallbackOn404(c *check.C) {
repoName := fmt.Sprintf("%v/does/not/exist", privateRegistryURL)
out, _, _ := dockerCmdWithError("pull", repoName)
c.Assert(out, checker.Contains, "v1 ping attempt")
}
func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) { func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) {
pushDigest, err := setupImage(c) pushDigest, err := setupImage(c)
c.Assert(err, checker.IsNil, check.Commentf("error setting up image")) c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))

View File

@ -62,6 +62,7 @@ func (s *DockerHubPullSuite) TestPullNonExistingImage(c *check.C) {
out, err := s.CmdWithError("pull", "-a", e.Alias) out, err := s.CmdWithError("pull", "-a", e.Alias)
c.Assert(err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", out)) c.Assert(err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", out))
c.Assert(out, checker.Contains, fmt.Sprintf("Error: image %s not found", e.Repo), check.Commentf("expected image not found error messages")) c.Assert(out, checker.Contains, fmt.Sprintf("Error: image %s not found", e.Repo), check.Commentf("expected image not found error messages"))
c.Assert(out, checker.Not(checker.Contains), "unauthorized", check.Commentf(`message should not contain "unauthorized"`))
} }
} }