Fix `before` and `since` filter for `docker ps`
| ... | ... |
@@ -303,7 +303,7 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis |
| 303 | 303 |
var beforeContFilter, sinceContFilter *container.Snapshot |
| 304 | 304 |
|
| 305 | 305 |
err = psFilters.WalkValues("before", func(value string) error {
|
| 306 |
- beforeContFilter, err = view.Get(value) |
|
| 306 |
+ beforeContFilter, err = idOrNameFilter(view, value) |
|
| 307 | 307 |
return err |
| 308 | 308 |
}) |
| 309 | 309 |
if err != nil {
|
| ... | ... |
@@ -311,7 +311,7 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis |
| 311 | 311 |
} |
| 312 | 312 |
|
| 313 | 313 |
err = psFilters.WalkValues("since", func(value string) error {
|
| 314 |
- sinceContFilter, err = view.Get(value) |
|
| 314 |
+ sinceContFilter, err = idOrNameFilter(view, value) |
|
| 315 | 315 |
return err |
| 316 | 316 |
}) |
| 317 | 317 |
if err != nil {
|
| ... | ... |
@@ -365,6 +365,30 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis |
| 365 | 365 |
names: view.GetAllNames(), |
| 366 | 366 |
}, nil |
| 367 | 367 |
} |
| 368 |
+ |
|
| 369 |
+func idOrNameFilter(view container.View, value string) (*container.Snapshot, error) {
|
|
| 370 |
+ filter, err := view.Get(value) |
|
| 371 |
+ switch err.(type) {
|
|
| 372 |
+ case container.NoSuchContainerError: |
|
| 373 |
+ // Try name search instead |
|
| 374 |
+ found := "" |
|
| 375 |
+ for id, idNames := range view.GetAllNames() {
|
|
| 376 |
+ for _, eachName := range idNames {
|
|
| 377 |
+ if strings.TrimPrefix(value, "/") == strings.TrimPrefix(eachName, "/") {
|
|
| 378 |
+ if found != "" && found != id {
|
|
| 379 |
+ return nil, err |
|
| 380 |
+ } |
|
| 381 |
+ found = id |
|
| 382 |
+ } |
|
| 383 |
+ } |
|
| 384 |
+ } |
|
| 385 |
+ if found != "" {
|
|
| 386 |
+ filter, err = view.Get(found) |
|
| 387 |
+ } |
|
| 388 |
+ } |
|
| 389 |
+ return filter, err |
|
| 390 |
+} |
|
| 391 |
+ |
|
| 368 | 392 |
func portOp(key string, filter map[nat.Port]bool) func(value string) error {
|
| 369 | 393 |
return func(value string) error {
|
| 370 | 394 |
if strings.Contains(value, ":") {
|
| 371 | 395 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,64 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "testing" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/docker/docker/api/types" |
|
| 7 |
+ "github.com/docker/docker/api/types/container" |
|
| 8 |
+ "github.com/docker/docker/api/types/filters" |
|
| 9 |
+ "github.com/docker/docker/api/types/network" |
|
| 10 |
+ "github.com/docker/docker/integration/util/request" |
|
| 11 |
+ "github.com/stretchr/testify/assert" |
|
| 12 |
+ "github.com/stretchr/testify/require" |
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+func TestPsFilter(t *testing.T) {
|
|
| 16 |
+ defer setupTest(t)() |
|
| 17 |
+ client := request.NewAPIClient(t) |
|
| 18 |
+ ctx := context.Background() |
|
| 19 |
+ |
|
| 20 |
+ createContainerForFilter := func(ctx context.Context, name string) string {
|
|
| 21 |
+ body, err := client.ContainerCreate(ctx, |
|
| 22 |
+ &container.Config{
|
|
| 23 |
+ Cmd: []string{"top"},
|
|
| 24 |
+ Image: "busybox", |
|
| 25 |
+ }, |
|
| 26 |
+ &container.HostConfig{},
|
|
| 27 |
+ &network.NetworkingConfig{},
|
|
| 28 |
+ name, |
|
| 29 |
+ ) |
|
| 30 |
+ require.NoError(t, err) |
|
| 31 |
+ return body.ID |
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 34 |
+ prev := createContainerForFilter(ctx, "prev") |
|
| 35 |
+ createContainerForFilter(ctx, "top") |
|
| 36 |
+ next := createContainerForFilter(ctx, "next") |
|
| 37 |
+ |
|
| 38 |
+ containerIDs := func(containers []types.Container) []string {
|
|
| 39 |
+ entries := []string{}
|
|
| 40 |
+ for _, container := range containers {
|
|
| 41 |
+ entries = append(entries, container.ID) |
|
| 42 |
+ } |
|
| 43 |
+ return entries |
|
| 44 |
+ } |
|
| 45 |
+ |
|
| 46 |
+ f1 := filters.NewArgs() |
|
| 47 |
+ f1.Add("since", "top")
|
|
| 48 |
+ q1, err := client.ContainerList(ctx, types.ContainerListOptions{
|
|
| 49 |
+ All: true, |
|
| 50 |
+ Filters: f1, |
|
| 51 |
+ }) |
|
| 52 |
+ require.NoError(t, err) |
|
| 53 |
+ assert.Contains(t, containerIDs(q1), next) |
|
| 54 |
+ |
|
| 55 |
+ f2 := filters.NewArgs() |
|
| 56 |
+ f2.Add("before", "top")
|
|
| 57 |
+ q2, err := client.ContainerList(ctx, types.ContainerListOptions{
|
|
| 58 |
+ All: true, |
|
| 59 |
+ Filters: f2, |
|
| 60 |
+ }) |
|
| 61 |
+ require.NoError(t, err) |
|
| 62 |
+ assert.Contains(t, containerIDs(q2), prev) |
|
| 63 |
+} |