فهرست منبع

Merge pull request #37462 from cwgem/37453_slash_prefix_removal

Remove slash prefix when matching name filters (Fixes #37453)
Sebastiaan van Stijn 7 سال پیش
والد
کامیت
7b46fbc17a
2فایلهای تغییر یافته به همراه101 افزوده شده و 2 حذف شده
  1. 2 2
      daemon/list.go
  2. 99 0
      daemon/list_test.go

+ 2 - 2
daemon/list.go

@@ -146,7 +146,7 @@ func (daemon *Daemon) filterByNameIDMatches(view container.View, ctx *listContex
 				continue
 				continue
 			}
 			}
 			for _, eachName := range idNames {
 			for _, eachName := range idNames {
-				if ctx.filters.Match("name", eachName) {
+				if ctx.filters.Match("name", strings.TrimPrefix(eachName, "/")) {
 					matches[id] = true
 					matches[id] = true
 				}
 				}
 			}
 			}
@@ -429,7 +429,7 @@ func includeContainerInList(container *container.Snapshot, ctx *listContext) ite
 	}
 	}
 
 
 	// Do not include container if the name doesn't match
 	// Do not include container if the name doesn't match
-	if !ctx.filters.Match("name", container.Name) {
+	if !ctx.filters.Match("name", strings.TrimPrefix(container.Name, "/")) {
 		return excludeContainer
 		return excludeContainer
 	}
 	}
 
 

+ 99 - 0
daemon/list_test.go

@@ -1,15 +1,82 @@
 package daemon
 package daemon
 
 
 import (
 import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
 	"testing"
 	"testing"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
+	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/image"
+	"github.com/opencontainers/go-digest"
+	"github.com/pborman/uuid"
 	"gotest.tools/assert"
 	"gotest.tools/assert"
 	is "gotest.tools/assert/cmp"
 	is "gotest.tools/assert/cmp"
 )
 )
 
 
+var root string
+
+func TestMain(m *testing.M) {
+	var err error
+	root, err = ioutil.TempDir("", "docker-container-test-")
+	if err != nil {
+		panic(err)
+	}
+	defer os.RemoveAll(root)
+
+	os.Exit(m.Run())
+}
+
+// This sets up a container with a name so that name filters
+// work against it. It takes in a pointer to Daemon so that
+// minor operations are not repeated by the caller
+func setupContainerWithName(t *testing.T, name string, daemon *Daemon) *container.Container {
+	var (
+		id              = uuid.New()
+		computedImageID = digest.FromString(id)
+		cRoot           = filepath.Join(root, id)
+	)
+	if err := os.MkdirAll(cRoot, 0755); err != nil {
+		t.Fatal(err)
+	}
+
+	c := container.NewBaseContainer(id, cRoot)
+	// these are for passing includeContainerInList
+	c.Name = name
+	c.Running = true
+	c.HostConfig = &containertypes.HostConfig{}
+
+	// these are for passing the refreshImage reducer
+	c.ImageID = image.IDFromDigest(computedImageID)
+	c.Config = &containertypes.Config{
+		Image: computedImageID.String(),
+	}
+
+	// this is done here to avoid requiring these
+	// operations n x number of containers in the
+	// calling function
+	daemon.containersReplica.Save(c)
+	daemon.reserveName(id, name)
+
+	return c
+}
+
+func containerListContainsName(containers []*types.Container, name string) bool {
+	for _, container := range containers {
+		for _, containerName := range container.Names {
+			if strings.TrimPrefix(containerName, "/") == name {
+				return true
+			}
+		}
+	}
+
+	return false
+}
+
 func TestListInvalidFilter(t *testing.T) {
 func TestListInvalidFilter(t *testing.T) {
 	db, err := container.NewViewDB()
 	db, err := container.NewViewDB()
 	assert.Assert(t, err == nil)
 	assert.Assert(t, err == nil)
@@ -24,3 +91,35 @@ func TestListInvalidFilter(t *testing.T) {
 	})
 	})
 	assert.Assert(t, is.Error(err, "Invalid filter 'invalid'"))
 	assert.Assert(t, is.Error(err, "Invalid filter 'invalid'"))
 }
 }
+
+func TestNameFilter(t *testing.T) {
+	db, err := container.NewViewDB()
+	assert.Assert(t, err == nil)
+	d := &Daemon{
+		containersReplica: db,
+	}
+
+	var (
+		one   = setupContainerWithName(t, "a1", d)
+		two   = setupContainerWithName(t, "a2", d)
+		three = setupContainerWithName(t, "b1", d)
+	)
+
+	// moby/moby #37453 - ^ regex not working due to prefix slash
+	// not being stripped
+	containerList, err := d.Containers(&types.ContainerListOptions{
+		Filters: filters.NewArgs(filters.Arg("name", "^a")),
+	})
+	assert.Assert(t, err == nil)
+	assert.Assert(t, is.Len(containerList, 2))
+	assert.Assert(t, containerListContainsName(containerList, one.Name))
+	assert.Assert(t, containerListContainsName(containerList, two.Name))
+
+	// Same as above but make sure it works for exact names
+	containerList, err = d.Containers(&types.ContainerListOptions{
+		Filters: filters.NewArgs(filters.Arg("name", "b1")),
+	})
+	assert.Assert(t, err == nil)
+	assert.Assert(t, is.Len(containerList, 1))
+	assert.Assert(t, containerListContainsName(containerList, three.Name))
+}