Переглянути джерело

Do not rely on string comparison in truncindex

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
Alexander Morozov 9 роки тому
батько
коміт
d4a8d09d1a

+ 1 - 1
api/server/router/local/image.go

@@ -242,7 +242,7 @@ func (s *router) deleteImages(ctx context.Context, w http.ResponseWriter, r *htt
 
 	name := vars["name"]
 
-	if name == "" {
+	if strings.TrimSpace(name) == "" {
 		return fmt.Errorf("image name cannot be blank")
 	}
 

+ 1 - 15
daemon/create.go

@@ -1,14 +1,10 @@
 package daemon
 
 import (
-	"strings"
-
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	derr "github.com/docker/docker/errors"
-	"github.com/docker/docker/graph/tags"
 	"github.com/docker/docker/image"
-	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/volume"
@@ -38,17 +34,7 @@ func (daemon *Daemon) ContainerCreate(params *ContainerCreateConfig) (types.Cont
 
 	container, err := daemon.create(params)
 	if err != nil {
-		if daemon.Graph().IsNotExist(err, params.Config.Image) {
-			if strings.Contains(params.Config.Image, "@") {
-				return types.ContainerCreateResponse{ID: "", Warnings: warnings}, derr.ErrorCodeNoSuchImageHash.WithArgs(params.Config.Image)
-			}
-			img, tag := parsers.ParseRepositoryTag(params.Config.Image)
-			if tag == "" {
-				tag = tags.DefaultTag
-			}
-			return types.ContainerCreateResponse{ID: "", Warnings: warnings}, derr.ErrorCodeNoSuchImageTag.WithArgs(img, tag)
-		}
-		return types.ContainerCreateResponse{ID: "", Warnings: warnings}, err
+		return types.ContainerCreateResponse{ID: "", Warnings: warnings}, daemon.graphNotExistToErrcode(params.Config.Image, err)
 	}
 
 	return types.ContainerCreateResponse{ID: container.ID, Warnings: warnings}, nil

+ 1 - 1
daemon/daemon.go

@@ -149,7 +149,7 @@ func (daemon *Daemon) Get(prefixOrName string) (*Container, error) {
 	containerID, indexError := daemon.idIndex.Get(prefixOrName)
 	if indexError != nil {
 		// When truncindex defines an error type, use that instead
-		if strings.Contains(indexError.Error(), "no such id") {
+		if indexError == truncindex.ErrNotExist {
 			return nil, derr.ErrorCodeNoSuchContainer.WithArgs(prefixOrName)
 		}
 		return nil, indexError

+ 23 - 0
daemon/errors.go

@@ -0,0 +1,23 @@
+package daemon
+
+import (
+	"strings"
+
+	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/graph/tags"
+	"github.com/docker/docker/pkg/parsers"
+)
+
+func (d *Daemon) graphNotExistToErrcode(imageName string, err error) error {
+	if d.Graph().IsNotExist(err, imageName) {
+		if strings.Contains(imageName, "@") {
+			return derr.ErrorCodeNoSuchImageHash.WithArgs(imageName)
+		}
+		img, tag := parsers.ParseRepositoryTag(imageName)
+		if tag == "" {
+			tag = tags.DefaultTag
+		}
+		return derr.ErrorCodeNoSuchImageTag.WithArgs(img, tag)
+	}
+	return err
+}

+ 1 - 1
daemon/image_delete.go

@@ -55,7 +55,7 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
 
 	img, err := daemon.repositories.LookupImage(imageRef)
 	if err != nil {
-		return nil, err
+		return nil, daemon.graphNotExistToErrcode(imageRef, err)
 	}
 
 	var removedRepositoryRef bool

+ 4 - 1
graph/graph.go

@@ -221,7 +221,10 @@ func (graph *Graph) Exists(id string) bool {
 func (graph *Graph) Get(name string) (*image.Image, error) {
 	id, err := graph.idIndex.Get(name)
 	if err != nil {
-		return nil, fmt.Errorf("could not find image: %v", err)
+		if err == truncindex.ErrNotExist {
+			return nil, fmt.Errorf("image %s does not exist", name)
+		}
+		return nil, err
 	}
 	img, err := graph.loadImage(id)
 	if err != nil {

+ 2 - 2
integration-cli/docker_cli_rmi_test.go

@@ -230,10 +230,10 @@ func (s *DockerSuite) TestRmiBlank(c *check.C) {
 	c.Assert(out, checker.Contains, "image name cannot be blank", check.Commentf("out: %s", out))
 
 	out, _, err = dockerCmdWithError("rmi", " ")
-	// Should have failed to delete '' image
+	// Should have failed to delete ' ' image
 	c.Assert(err, checker.NotNil)
 	// Expected error message not generated
-	c.Assert(out, checker.Contains, "no such id", check.Commentf("out: %s", out))
+	c.Assert(out, checker.Contains, "image name cannot be blank", check.Commentf("out: %s", out))
 }
 
 func (s *DockerSuite) TestRmiContainerImageNotFound(c *check.C) {

+ 4 - 1
pkg/truncindex/truncindex.go

@@ -22,6 +22,9 @@ var (
 
 	// ErrIllegalChar is returned when a space is in the ID
 	ErrIllegalChar = errors.New("illegal character: ' '")
+
+	// ErrNotExist is returned when ID or its prefix not found in index.
+	ErrNotExist = errors.New("ID does not exist")
 )
 
 // TruncIndex allows the retrieval of string identifiers by any of their unique prefixes.
@@ -116,7 +119,7 @@ func (idx *TruncIndex) Get(s string) (string, error) {
 	if id != "" {
 		return id, nil
 	}
-	return "", fmt.Errorf("no such id: %s", s)
+	return "", ErrNotExist
 }
 
 // Iterate iterates over all stored IDs, and passes each of them to the given handler.