Merge pull request #31482 from ripcurld0/add_format_to_system_df

Add format to the docker system df command
This commit is contained in:
Sebastiaan van Stijn 2017-04-13 10:08:11 -07:00 committed by GitHub
commit 0b35ab1965
4 changed files with 168 additions and 14 deletions

View file

@ -45,15 +45,33 @@ func (ctx *DiskUsageContext) startSubsection(format string) (*template.Template,
return ctx.parseFormat()
}
func (ctx *DiskUsageContext) Write() {
//
// NewDiskUsageFormat returns a format for rendering an DiskUsageContext
func NewDiskUsageFormat(source string) Format {
switch source {
case TableFormatKey:
format := defaultDiskUsageTableFormat
return Format(format)
case RawFormatKey:
format := `type: {{.Type}}
total: {{.TotalCount}}
active: {{.Active}}
size: {{.Size}}
reclaimable: {{.Reclaimable}}
`
return Format(format)
}
return Format(source)
}
func (ctx *DiskUsageContext) Write() (err error) {
if ctx.Verbose == false {
ctx.buffer = bytes.NewBufferString("")
ctx.Format = defaultDiskUsageTableFormat
ctx.preFormat()
tmpl, err := ctx.parseFormat()
if err != nil {
return
return err
}
err = ctx.contextFormat(tmpl, &diskUsageImagesContext{
@ -61,20 +79,20 @@ func (ctx *DiskUsageContext) Write() {
images: ctx.Images,
})
if err != nil {
return
return err
}
err = ctx.contextFormat(tmpl, &diskUsageContainersContext{
containers: ctx.Containers,
})
if err != nil {
return
return err
}
err = ctx.contextFormat(tmpl, &diskUsageVolumesContext{
volumes: ctx.Volumes,
})
if err != nil {
return
return err
}
diskUsageContainersCtx := diskUsageContainersContext{containers: []*types.Container{}}
@ -87,7 +105,7 @@ func (ctx *DiskUsageContext) Write() {
}
ctx.postFormat(tmpl, &diskUsageContainersCtx)
return
return err
}
// First images
@ -158,6 +176,7 @@ func (ctx *DiskUsageContext) Write() {
}
}
ctx.postFormat(tmpl, newVolumeContext())
return
}
type diskUsageImagesContext struct {

View file

@ -8,13 +8,17 @@ import (
)
func TestDiskUsageContextFormatWrite(t *testing.T) {
// Check default output format (verbose and non-verbose mode) for table headers
cases := []struct {
context DiskUsageContext
expected string
}{
// Check default output format (verbose and non-verbose mode) for table headers
{
DiskUsageContext{Verbose: false},
DiskUsageContext{
Context: Context{
Format: NewDiskUsageFormat("table"),
},
Verbose: false},
`TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 0 0 0B 0B
Containers 0 0 0B 0B
@ -34,6 +38,77 @@ CONTAINER ID IMAGE COMMAND LOCAL VOLUMES
Local Volumes space usage:
VOLUME NAME LINKS SIZE
`,
},
// Errors
{
DiskUsageContext{
Context: Context{
Format: "{{InvalidFunction}}",
},
},
`Template parsing error: template: :1: function "InvalidFunction" not defined
`,
},
{
DiskUsageContext{
Context: Context{
Format: "{{nil}}",
},
},
`Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command
`,
},
// Table Format
{
DiskUsageContext{
Context: Context{
Format: NewDiskUsageFormat("table"),
},
},
`TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 0 0 0B 0B
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
`,
},
{
DiskUsageContext{
Context: Context{
Format: NewDiskUsageFormat("table {{.Type}}\t{{.Active}}"),
},
},
`TYPE ACTIVE
Images 0
Containers 0
Local Volumes 0
`,
},
// Raw Format
{
DiskUsageContext{
Context: Context{
Format: NewDiskUsageFormat("raw"),
},
},
`type: Images
total: 0
active: 0
size: 0B
reclaimable: 0B
type: Containers
total: 0
active: 0
size: 0B
reclaimable: 0B
type: Local Volumes
total: 0
active: 0
size: 0B
reclaimable: 0B
`,
},
}
@ -41,7 +116,10 @@ VOLUME NAME LINKS SIZE
for _, testcase := range cases {
out := bytes.NewBufferString("")
testcase.context.Output = out
testcase.context.Write()
assert.Equal(t, out.String(), testcase.expected)
if err := testcase.context.Write(); err != nil {
assert.Equal(t, err.Error(), testcase.expected)
} else {
assert.Equal(t, out.String(), testcase.expected)
}
}
}

View file

@ -1,6 +1,8 @@
package system
import (
"errors"
"github.com/docker/docker/cli"
"github.com/docker/docker/cli/command"
"github.com/docker/docker/cli/command/formatter"
@ -10,6 +12,7 @@ import (
type diskUsageOptions struct {
verbose bool
format string
}
// NewDiskUsageCommand creates a new cobra.Command for `docker df`
@ -29,19 +32,30 @@ func NewDiskUsageCommand(dockerCli *command.DockerCli) *cobra.Command {
flags := cmd.Flags()
flags.BoolVarP(&opts.verbose, "verbose", "v", false, "Show detailed information on space usage")
flags.StringVar(&opts.format, "format", "", "Pretty-print images using a Go template")
return cmd
}
func runDiskUsage(dockerCli *command.DockerCli, opts diskUsageOptions) error {
if opts.verbose && len(opts.format) != 0 {
return errors.New("the verbose and the format options conflict")
}
du, err := dockerCli.Client().DiskUsage(context.Background())
if err != nil {
return err
}
format := opts.format
if len(format) == 0 {
format = formatter.TableFormatKey
}
duCtx := formatter.DiskUsageContext{
Context: formatter.Context{
Output: dockerCli.Out(),
Format: formatter.NewDiskUsageFormat(format),
},
LayersSize: du.LayersSize,
Images: du.Images,
@ -50,7 +64,5 @@ func runDiskUsage(dockerCli *command.DockerCli, opts diskUsageOptions) error {
Verbose: opts.verbose,
}
duCtx.Write()
return nil
return duCtx.Write()
}

View file

@ -86,6 +86,51 @@ volumes or in systems where some images, containers, or volumes have very large
filesystems with many files. You should also be careful not to run this command
in systems where performance is critical.
## Format the output
The formatting option (`--format`) pretty prints the disk usage output
using a Go template.
Valid placeholders for the Go template are listed below:
| Placeholder | Description |
| -------------- | ------------------------------------------ |
| `.Type` | `Images`, `Containers` and `Local Volumes` |
| `.TotalCount` | Total number of items |
| `.Active` | Number of active items |
| `.Size` | Available size |
| `.Reclaimable` | Reclaimable size |
When using the `--format` option, the `system df` command outputs
the data exactly as the template declares or, when using the
`table` directive, will include column headers as well.
The following example uses a template without headers and outputs the
`Type` and `TotalCount` entries separated by a colon:
```bash
$ docker system df --format "{{.Type}}: {{.TotalCount}}"
Images: 2
Containers: 4
Local Volumes: 1
```
To list the disk usage with size and reclaimable size in a table format you
can use:
```bash
$ docker system df --format "table {{.Type}}\t{{.Size}}\t{{.Reclaimable}}"
TYPE SIZE RECLAIMABLE
Images 2.547 GB 2.342 GB (91%)
Containers 0 B 0 B
Local Volumes 150.3 MB 150.3 MB (100%)
<Paste>
```
**Note** the format option is meaningless when verbose is true.
## Related commands
* [system prune](system_prune.md)
* [container prune](container_prune.md)