Selaa lähdekoodia

Merge pull request #35938 from yongtang/35931-filter-before-since

Fix `before` and `since` filter for `docker ps`
Yong Tang 7 vuotta sitten
vanhempi
commit
25e56670cf
2 muutettua tiedostoa jossa 90 lisäystä ja 2 poistoa
  1. 26 2
      daemon/list.go
  2. 64 0
      integration/container/ps_test.go

+ 26 - 2
daemon/list.go

@@ -303,7 +303,7 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis
 	var beforeContFilter, sinceContFilter *container.Snapshot
 	var beforeContFilter, sinceContFilter *container.Snapshot
 
 
 	err = psFilters.WalkValues("before", func(value string) error {
 	err = psFilters.WalkValues("before", func(value string) error {
-		beforeContFilter, err = view.Get(value)
+		beforeContFilter, err = idOrNameFilter(view, value)
 		return err
 		return err
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -311,7 +311,7 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis
 	}
 	}
 
 
 	err = psFilters.WalkValues("since", func(value string) error {
 	err = psFilters.WalkValues("since", func(value string) error {
-		sinceContFilter, err = view.Get(value)
+		sinceContFilter, err = idOrNameFilter(view, value)
 		return err
 		return err
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -365,6 +365,30 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis
 		names:                view.GetAllNames(),
 		names:                view.GetAllNames(),
 	}, nil
 	}, nil
 }
 }
+
+func idOrNameFilter(view container.View, value string) (*container.Snapshot, error) {
+	filter, err := view.Get(value)
+	switch err.(type) {
+	case container.NoSuchContainerError:
+		// Try name search instead
+		found := ""
+		for id, idNames := range view.GetAllNames() {
+			for _, eachName := range idNames {
+				if strings.TrimPrefix(value, "/") == strings.TrimPrefix(eachName, "/") {
+					if found != "" && found != id {
+						return nil, err
+					}
+					found = id
+				}
+			}
+		}
+		if found != "" {
+			filter, err = view.Get(found)
+		}
+	}
+	return filter, err
+}
+
 func portOp(key string, filter map[nat.Port]bool) func(value string) error {
 func portOp(key string, filter map[nat.Port]bool) func(value string) error {
 	return func(value string) error {
 	return func(value string) error {
 		if strings.Contains(value, ":") {
 		if strings.Contains(value, ":") {

+ 64 - 0
integration/container/ps_test.go

@@ -0,0 +1,64 @@
+package container
+
+import (
+	"context"
+	"testing"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/integration/util/request"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestPsFilter(t *testing.T) {
+	defer setupTest(t)()
+	client := request.NewAPIClient(t)
+	ctx := context.Background()
+
+	createContainerForFilter := func(ctx context.Context, name string) string {
+		body, err := client.ContainerCreate(ctx,
+			&container.Config{
+				Cmd:   []string{"top"},
+				Image: "busybox",
+			},
+			&container.HostConfig{},
+			&network.NetworkingConfig{},
+			name,
+		)
+		require.NoError(t, err)
+		return body.ID
+	}
+
+	prev := createContainerForFilter(ctx, "prev")
+	createContainerForFilter(ctx, "top")
+	next := createContainerForFilter(ctx, "next")
+
+	containerIDs := func(containers []types.Container) []string {
+		entries := []string{}
+		for _, container := range containers {
+			entries = append(entries, container.ID)
+		}
+		return entries
+	}
+
+	f1 := filters.NewArgs()
+	f1.Add("since", "top")
+	q1, err := client.ContainerList(ctx, types.ContainerListOptions{
+		All:     true,
+		Filters: f1,
+	})
+	require.NoError(t, err)
+	assert.Contains(t, containerIDs(q1), next)
+
+	f2 := filters.NewArgs()
+	f2.Add("before", "top")
+	q2, err := client.ContainerList(ctx, types.ContainerListOptions{
+		All:     true,
+		Filters: f2,
+	})
+	require.NoError(t, err)
+	assert.Contains(t, containerIDs(q2), prev)
+}