mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Sort output of docker ps --filter
with order by creation time
This fix tries to address the issue raised in 25374 where the output of `docker ps --filter` is in random order and not deterministic. This fix sorts the list of containers by creation time so that the output is deterministic. An integration test has been added. This fix fixes 25374. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
parent
9513aa3a48
commit
3f97133546
2 changed files with 49 additions and 0 deletions
|
@ -3,6 +3,7 @@ package daemon
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -86,6 +87,15 @@ type listContext struct {
|
||||||
*types.ContainerListOptions
|
*types.ContainerListOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// byContainerCreated is a temporary type used to sort a list of containers by creation time.
|
||||||
|
type byContainerCreated []*container.Container
|
||||||
|
|
||||||
|
func (r byContainerCreated) Len() int { return len(r) }
|
||||||
|
func (r byContainerCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||||
|
func (r byContainerCreated) Less(i, j int) bool {
|
||||||
|
return r[i].Created.UnixNano() < r[j].Created.UnixNano()
|
||||||
|
}
|
||||||
|
|
||||||
// Containers returns the list of containers to show given the user's filtering.
|
// Containers returns the list of containers to show given the user's filtering.
|
||||||
func (daemon *Daemon) Containers(config *types.ContainerListOptions) ([]*types.Container, error) {
|
func (daemon *Daemon) Containers(config *types.ContainerListOptions) ([]*types.Container, error) {
|
||||||
return daemon.reduceContainers(config, daemon.transformContainer)
|
return daemon.reduceContainers(config, daemon.transformContainer)
|
||||||
|
@ -149,6 +159,11 @@ func (daemon *Daemon) filterByNameIDMatches(ctx *listContext) []*container.Conta
|
||||||
for id := range matches {
|
for id := range matches {
|
||||||
cntrs = append(cntrs, daemon.containers.Get(id))
|
cntrs = append(cntrs, daemon.containers.Get(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore sort-order after filtering
|
||||||
|
// Created gives us nanosec resolution for sorting
|
||||||
|
sort.Sort(sort.Reverse(byContainerCreated(cntrs)))
|
||||||
|
|
||||||
return cntrs
|
return cntrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -864,3 +864,37 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) {
|
||||||
|
|
||||||
c.Assert(containerOut, checker.Contains, "onbridgenetwork")
|
c.Assert(containerOut, checker.Contains, "onbridgenetwork")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestPsByOrder(c *check.C) {
|
||||||
|
name1 := "xyz-abc"
|
||||||
|
out, err := runSleepingContainer(c, "--name", name1)
|
||||||
|
c.Assert(err, checker.NotNil)
|
||||||
|
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||||
|
container1 := strings.TrimSpace(out)
|
||||||
|
|
||||||
|
name2 := "xyz-123"
|
||||||
|
out, err = runSleepingContainer(c, "--name", name2)
|
||||||
|
c.Assert(err, checker.NotNil)
|
||||||
|
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||||
|
container2 := strings.TrimSpace(out)
|
||||||
|
|
||||||
|
name3 := "789-abc"
|
||||||
|
out, err = runSleepingContainer(c, "--name", name3)
|
||||||
|
c.Assert(err, checker.NotNil)
|
||||||
|
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||||
|
|
||||||
|
name4 := "789-123"
|
||||||
|
out, err = runSleepingContainer(c, "--name", name4)
|
||||||
|
c.Assert(err, checker.NotNil)
|
||||||
|
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
||||||
|
|
||||||
|
// Run multiple time should have the same result
|
||||||
|
out, err = dockerCmd(c, "ps", "--no-trunc", "-q", "-f", "name=xyz")
|
||||||
|
c.Assert(err, checker.NotNil)
|
||||||
|
c.Assert(strings.TrimSpace(out), checker.Equals, fmt.Sprintf("%s\n%s", container2, container1))
|
||||||
|
|
||||||
|
// Run multiple time should have the same result
|
||||||
|
out, err = dockerCmd(c, "ps", "--no-trunc", "-q", "-f", "name=xyz")
|
||||||
|
c.Assert(err, checker.NotNil)
|
||||||
|
c.Assert(strings.TrimSpace(out), checker.Equals, fmt.Sprintf("%s\n%s", container2, container1))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue