mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Change v1 pull 404 message to include tag
The current error message is "Error: image [name] not found". This makes sense from the perspective of the v1 pull, since we found the repository doesn't exist over the v1 protocol. However, in the vast majority of cases, this error will be produced by fallback situations, where we first try to pull the tag with the v2 protocol, and then fall back the v1 protocol, which probably isn't even supported by the server. Including the tag in the error message makes a lot more sense since the actual repository may exist on v2, but not the tag. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
1e1da2a29b
commit
745892a7b2
3 changed files with 29 additions and 16 deletions
|
@ -75,9 +75,14 @@ func (p *v1Puller) Pull(ctx context.Context, ref reference.Named) error {
|
||||||
func (p *v1Puller) pullRepository(ctx context.Context, ref reference.Named) error {
|
func (p *v1Puller) pullRepository(ctx context.Context, ref reference.Named) error {
|
||||||
progress.Message(p.config.ProgressOutput, "", "Pulling repository "+p.repoInfo.FullName())
|
progress.Message(p.config.ProgressOutput, "", "Pulling repository "+p.repoInfo.FullName())
|
||||||
|
|
||||||
|
tagged, isTagged := ref.(reference.NamedTagged)
|
||||||
|
|
||||||
repoData, err := p.session.GetRepositoryData(p.repoInfo)
|
repoData, err := p.session.GetRepositoryData(p.repoInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "HTTP code: 404") {
|
if strings.Contains(err.Error(), "HTTP code: 404") {
|
||||||
|
if isTagged {
|
||||||
|
return fmt.Errorf("Error: image %s:%s not found", p.repoInfo.RemoteName(), tagged.Tag())
|
||||||
|
}
|
||||||
return fmt.Errorf("Error: image %s not found", p.repoInfo.RemoteName())
|
return fmt.Errorf("Error: image %s not found", p.repoInfo.RemoteName())
|
||||||
}
|
}
|
||||||
// Unexpected HTTP error
|
// Unexpected HTTP error
|
||||||
|
@ -86,7 +91,6 @@ func (p *v1Puller) pullRepository(ctx context.Context, ref reference.Named) erro
|
||||||
|
|
||||||
logrus.Debugf("Retrieving the tag list")
|
logrus.Debugf("Retrieving the tag list")
|
||||||
var tagsList map[string]string
|
var tagsList map[string]string
|
||||||
tagged, isTagged := ref.(reference.NamedTagged)
|
|
||||||
if !isTagged {
|
if !isTagged {
|
||||||
tagsList, err = p.session.GetRemoteTags(repoData.Endpoints, p.repoInfo)
|
tagsList, err = p.session.GetRemoteTags(repoData.Endpoints, p.repoInfo)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -52,5 +52,5 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C)
|
||||||
// check I cannot pull anymore
|
// check I cannot pull anymore
|
||||||
out, _, err := dockerCmdWithError("--config", tmp, "pull", repoName)
|
out, _, err := dockerCmdWithError("--config", tmp, "pull", repoName)
|
||||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||||
c.Assert(out, checker.Contains, fmt.Sprintf("Error: image dockercli/busybox not found"))
|
c.Assert(out, checker.Contains, "Error: image dockercli/busybox:authtest not found")
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,17 +42,18 @@ func (s *DockerHubPullSuite) TestPullNonExistingImage(c *check.C) {
|
||||||
testRequires(c, DaemonIsLinux)
|
testRequires(c, DaemonIsLinux)
|
||||||
|
|
||||||
type entry struct {
|
type entry struct {
|
||||||
Repo string
|
repo string
|
||||||
Alias string
|
alias string
|
||||||
|
tag string
|
||||||
}
|
}
|
||||||
|
|
||||||
entries := []entry{
|
entries := []entry{
|
||||||
{"library/asdfasdf", "asdfasdf:foobar"},
|
{"library/asdfasdf", "asdfasdf", "foobar"},
|
||||||
{"library/asdfasdf", "library/asdfasdf:foobar"},
|
{"library/asdfasdf", "library/asdfasdf", "foobar"},
|
||||||
{"library/asdfasdf", "asdfasdf"},
|
{"library/asdfasdf", "asdfasdf", ""},
|
||||||
{"library/asdfasdf", "asdfasdf:latest"},
|
{"library/asdfasdf", "asdfasdf", "latest"},
|
||||||
{"library/asdfasdf", "library/asdfasdf"},
|
{"library/asdfasdf", "library/asdfasdf", ""},
|
||||||
{"library/asdfasdf", "library/asdfasdf:latest"},
|
{"library/asdfasdf", "library/asdfasdf", "latest"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// The option field indicates "-a" or not.
|
// The option field indicates "-a" or not.
|
||||||
|
@ -71,15 +72,19 @@ func (s *DockerHubPullSuite) TestPullNonExistingImage(c *check.C) {
|
||||||
group.Add(1)
|
group.Add(1)
|
||||||
go func(e entry) {
|
go func(e entry) {
|
||||||
defer group.Done()
|
defer group.Done()
|
||||||
out, err := s.CmdWithError("pull", e.Alias)
|
repoName := e.alias
|
||||||
|
if e.tag != "" {
|
||||||
|
repoName += ":" + e.tag
|
||||||
|
}
|
||||||
|
out, err := s.CmdWithError("pull", repoName)
|
||||||
recordChan <- record{e, "", out, err}
|
recordChan <- record{e, "", out, err}
|
||||||
}(e)
|
}(e)
|
||||||
if !strings.ContainsRune(e.Alias, ':') {
|
if e.tag == "" {
|
||||||
// pull -a on a nonexistent registry should fall back as well
|
// pull -a on a nonexistent registry should fall back as well
|
||||||
group.Add(1)
|
group.Add(1)
|
||||||
go func(e entry) {
|
go func(e entry) {
|
||||||
defer group.Done()
|
defer group.Done()
|
||||||
out, err := s.CmdWithError("pull", "-a", e.Alias)
|
out, err := s.CmdWithError("pull", "-a", e.alias)
|
||||||
recordChan <- record{e, "-a", out, err}
|
recordChan <- record{e, "-a", out, err}
|
||||||
}(e)
|
}(e)
|
||||||
}
|
}
|
||||||
|
@ -96,11 +101,15 @@ func (s *DockerHubPullSuite) TestPullNonExistingImage(c *check.C) {
|
||||||
// Hub returns 401 rather than 404 for nonexistent repos over
|
// Hub returns 401 rather than 404 for nonexistent repos over
|
||||||
// the v2 protocol - but we should end up falling back to v1,
|
// the v2 protocol - but we should end up falling back to v1,
|
||||||
// which does return a 404.
|
// which does return a 404.
|
||||||
c.Assert(record.out, checker.Contains, fmt.Sprintf("Error: image %s not found", record.e.Repo), check.Commentf("expected image not found error messages"))
|
tag := record.e.tag
|
||||||
|
if tag == "" {
|
||||||
|
tag = "latest"
|
||||||
|
}
|
||||||
|
c.Assert(record.out, checker.Contains, fmt.Sprintf("Error: image %s:%s not found", record.e.repo, tag), check.Commentf("expected image not found error messages"))
|
||||||
} else {
|
} else {
|
||||||
// pull -a on a nonexistent registry should fall back as well
|
// pull -a on a nonexistent registry should fall back as well
|
||||||
c.Assert(record.err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", record.out))
|
c.Assert(record.err, checker.NotNil, check.Commentf("expected non-zero exit status when pulling non-existing image: %s", record.out))
|
||||||
c.Assert(record.out, checker.Contains, fmt.Sprintf("Error: image %s not found", record.e.Repo), check.Commentf("expected image not found error messages"))
|
c.Assert(record.out, checker.Contains, fmt.Sprintf("Error: image %s not found", record.e.repo), check.Commentf("expected image not found error messages"))
|
||||||
c.Assert(record.out, checker.Not(checker.Contains), "unauthorized", check.Commentf(`message should not contain "unauthorized"`))
|
c.Assert(record.out, checker.Not(checker.Contains), "unauthorized", check.Commentf(`message should not contain "unauthorized"`))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,5 +270,5 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullNoCredentialsNotFound(c *check
|
||||||
// gives a 404 (in this case the test registry doesn't handle v1 at all)
|
// gives a 404 (in this case the test registry doesn't handle v1 at all)
|
||||||
out, _, err := dockerCmdWithError("pull", privateRegistryURL+"/busybox")
|
out, _, err := dockerCmdWithError("pull", privateRegistryURL+"/busybox")
|
||||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||||
c.Assert(out, checker.Contains, "Error: image busybox not found")
|
c.Assert(out, checker.Contains, "Error: image busybox:latest not found")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue