mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Fixes #24696 - fixes size showing 0 in format output
Signed-off-by: Josh Horwitz <horwitz@addthis.com>
This commit is contained in:
parent
9a9fc01af8
commit
456e039659
2 changed files with 122 additions and 31 deletions
|
@ -9,9 +9,10 @@ import (
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/filters"
|
"github.com/docker/engine-api/types/filters"
|
||||||
|
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/docker/docker/utils/templates"
|
"github.com/docker/docker/utils/templates"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"io/ioutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type psOptions struct {
|
type psOptions struct {
|
||||||
|
@ -25,16 +26,6 @@ type psOptions struct {
|
||||||
filter []string
|
filter []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type preProcessor struct {
|
|
||||||
opts *types.ContainerListOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size sets the size option when called by a template execution.
|
|
||||||
func (p *preProcessor) Size() bool {
|
|
||||||
p.opts.Size = true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPsCommand creates a new cobra.Command for `docker ps`
|
// NewPsCommand creates a new cobra.Command for `docker ps`
|
||||||
func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command {
|
func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command {
|
||||||
var opts psOptions
|
var opts psOptions
|
||||||
|
@ -62,39 +53,65 @@ func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
|
type preProcessor struct {
|
||||||
ctx := context.Background()
|
types.Container
|
||||||
|
opts *types.ContainerListOptions
|
||||||
|
}
|
||||||
|
|
||||||
if opts.nLatest && opts.last == -1 {
|
// Size sets the size option when called by a template execution.
|
||||||
opts.last = 1
|
func (p *preProcessor) Size() bool {
|
||||||
}
|
p.opts.Size = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
containerFilterArgs := filters.NewArgs()
|
func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {
|
||||||
for _, f := range opts.filter {
|
|
||||||
var err error
|
|
||||||
containerFilterArgs, err = filters.ParseFlag(f, containerFilterArgs)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
options := types.ContainerListOptions{
|
options := &types.ContainerListOptions{
|
||||||
All: opts.all,
|
All: opts.all,
|
||||||
Limit: opts.last,
|
Limit: opts.last,
|
||||||
Size: opts.size,
|
Size: opts.size,
|
||||||
Filter: containerFilterArgs,
|
Filter: filters.NewArgs(),
|
||||||
}
|
}
|
||||||
|
|
||||||
pre := &preProcessor{opts: &options}
|
if opts.nLatest && opts.last == -1 {
|
||||||
|
options.Limit = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range opts.filter {
|
||||||
|
var err error
|
||||||
|
options.Filter, err = filters.ParseFlag(f, options.Filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Currently only used with Size, so we can determine if the user
|
||||||
|
// put {{.Size}} in their format.
|
||||||
|
pre := &preProcessor{opts: options}
|
||||||
tmpl, err := templates.Parse(opts.format)
|
tmpl, err := templates.Parse(opts.format)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// This shouldn't error out but swallowing the error makes it harder
|
||||||
|
// to track down if preProcessor issues come up. Ref #24696
|
||||||
|
if err := tmpl.Execute(ioutil.Discard, pre); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return options, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
listOptions, err := buildContainerListOptions(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = tmpl.Execute(ioutil.Discard, pre)
|
containers, err := dockerCli.Client().ContainerList(ctx, *listOptions)
|
||||||
|
|
||||||
containers, err := dockerCli.Client().ContainerList(ctx, options)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -115,7 +132,7 @@ func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
|
||||||
Quiet: opts.quiet,
|
Quiet: opts.quiet,
|
||||||
Trunc: !opts.noTrunc,
|
Trunc: !opts.noTrunc,
|
||||||
},
|
},
|
||||||
Size: opts.size,
|
Size: listOptions.Size,
|
||||||
Containers: containers,
|
Containers: containers,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
74
api/client/container/ps_test.go
Normal file
74
api/client/container/ps_test.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package container
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestBuildContainerListOptions(t *testing.T) {
|
||||||
|
|
||||||
|
contexts := []struct {
|
||||||
|
psOpts *psOptions
|
||||||
|
expectedAll bool
|
||||||
|
expectedSize bool
|
||||||
|
expectedLimit int
|
||||||
|
expectedFilters map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
psOpts: &psOptions{
|
||||||
|
all: true,
|
||||||
|
size: true,
|
||||||
|
last: 5,
|
||||||
|
filter: []string{"foo=bar", "baz=foo"},
|
||||||
|
},
|
||||||
|
expectedAll: true,
|
||||||
|
expectedSize: true,
|
||||||
|
expectedLimit: 5,
|
||||||
|
expectedFilters: map[string]string{
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
psOpts: &psOptions{
|
||||||
|
all: true,
|
||||||
|
size: true,
|
||||||
|
last: -1,
|
||||||
|
nLatest: true,
|
||||||
|
},
|
||||||
|
expectedAll: true,
|
||||||
|
expectedSize: true,
|
||||||
|
expectedLimit: 1,
|
||||||
|
expectedFilters: make(map[string]string),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range contexts {
|
||||||
|
options, err := buildContainerListOptions(c.psOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.expectedAll != options.All {
|
||||||
|
t.Fatalf("Expected All to be %t but got %t", c.expectedAll, options.All)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.expectedSize != options.Size {
|
||||||
|
t.Fatalf("Expected Size to be %t but got %t", c.expectedSize, options.Size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.expectedLimit != options.Limit {
|
||||||
|
t.Fatalf("Expected Limit to be %d but got %d", c.expectedLimit, options.Limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
f := options.Filter
|
||||||
|
|
||||||
|
if f.Len() != len(c.expectedFilters) {
|
||||||
|
t.Fatalf("Expected %d filters but got %d", len(c.expectedFilters), f.Len())
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range c.expectedFilters {
|
||||||
|
f := options.Filter
|
||||||
|
if !f.ExactMatch(k, v) {
|
||||||
|
t.Fatalf("Expected filter with key %s to be %s but got %s", k, v, f.Get(k))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue