blob: 37e623fbd357621639f047c314644d70e524bd3d [file] [log] [blame]
package client
import (
"fmt"
"sort"
"text/tabwriter"
"golang.org/x/net/context"
Cli "github.com/docker/docker/cli"
"github.com/docker/docker/opts"
flag "github.com/docker/docker/pkg/mflag"
runconfigopts "github.com/docker/docker/runconfig/opts"
"github.com/docker/engine-api/types"
"github.com/docker/engine-api/types/filters"
)
// CmdVolume is the parent subcommand for all volume commands
//
// Usage: docker volume <COMMAND> <OPTS>
func (cli *DockerCli) CmdVolume(args ...string) error {
description := Cli.DockerCommands["volume"].Description + "\n\nCommands:\n"
commands := [][]string{
{"create", "Create a volume"},
{"inspect", "Return low-level information on a volume"},
{"ls", "List volumes"},
{"rm", "Remove a volume"},
}
for _, cmd := range commands {
description += fmt.Sprintf(" %-25.25s%s\n", cmd[0], cmd[1])
}
description += "\nRun 'docker volume COMMAND --help' for more information on a command"
cmd := Cli.Subcmd("volume", []string{"[COMMAND]"}, description, false)
cmd.Require(flag.Exact, 0)
err := cmd.ParseFlags(args, true)
cmd.Usage()
return err
}
// CmdVolumeLs outputs a list of Docker volumes.
//
// Usage: docker volume ls [OPTIONS]
func (cli *DockerCli) CmdVolumeLs(args ...string) error {
cmd := Cli.Subcmd("volume ls", nil, "List volumes", true)
quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display volume names")
flFilter := opts.NewListOpts(nil)
cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')")
cmd.Require(flag.Exact, 0)
cmd.ParseFlags(args, true)
volFilterArgs := filters.NewArgs()
for _, f := range flFilter.GetAll() {
var err error
volFilterArgs, err = filters.ParseFlag(f, volFilterArgs)
if err != nil {
return err
}
}
volumes, err := cli.client.VolumeList(context.Background(), volFilterArgs)
if err != nil {
return err
}
w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
if !*quiet {
for _, warn := range volumes.Warnings {
fmt.Fprintln(cli.err, warn)
}
fmt.Fprintf(w, "DRIVER \tVOLUME NAME")
fmt.Fprintf(w, "\n")
}
sort.Sort(byVolumeName(volumes.Volumes))
for _, vol := range volumes.Volumes {
if *quiet {
fmt.Fprintln(w, vol.Name)
continue
}
fmt.Fprintf(w, "%s\t%s\n", vol.Driver, vol.Name)
}
w.Flush()
return nil
}
type byVolumeName []*types.Volume
func (r byVolumeName) Len() int { return len(r) }
func (r byVolumeName) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r byVolumeName) Less(i, j int) bool {
return r[i].Name < r[j].Name
}
// CmdVolumeInspect displays low-level information on one or more volumes.
//
// Usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...]
func (cli *DockerCli) CmdVolumeInspect(args ...string) error {
cmd := Cli.Subcmd("volume inspect", []string{"VOLUME [VOLUME...]"}, "Return low-level information on a volume", true)
tmplStr := cmd.String([]string{"f", "-format"}, "", "Format the output using the given go template")
cmd.Require(flag.Min, 1)
cmd.ParseFlags(args, true)
if err := cmd.Parse(args); err != nil {
return nil
}
inspectSearcher := func(name string) (interface{}, []byte, error) {
i, err := cli.client.VolumeInspect(context.Background(), name)
return i, nil, err
}
return cli.inspectElements(*tmplStr, cmd.Args(), inspectSearcher)
}
// CmdVolumeCreate creates a new volume.
//
// Usage: docker volume create [OPTIONS]
func (cli *DockerCli) CmdVolumeCreate(args ...string) error {
cmd := Cli.Subcmd("volume create", nil, "Create a volume", true)
flDriver := cmd.String([]string{"d", "-driver"}, "local", "Specify volume driver name")
flName := cmd.String([]string{"-name"}, "", "Specify volume name")
flDriverOpts := opts.NewMapOpts(nil, nil)
cmd.Var(flDriverOpts, []string{"o", "-opt"}, "Set driver specific options")
flLabels := opts.NewListOpts(nil)
cmd.Var(&flLabels, []string{"-label"}, "Set metadata for a volume")
cmd.Require(flag.Exact, 0)
cmd.ParseFlags(args, true)
volReq := types.VolumeCreateRequest{
Driver: *flDriver,
DriverOpts: flDriverOpts.GetAll(),
Name: *flName,
Labels: runconfigopts.ConvertKVStringsToMap(flLabels.GetAll()),
}
vol, err := cli.client.VolumeCreate(context.Background(), volReq)
if err != nil {
return err
}
fmt.Fprintf(cli.out, "%s\n", vol.Name)
return nil
}
// CmdVolumeRm removes one or more volumes.
//
// Usage: docker volume rm VOLUME [VOLUME...]
func (cli *DockerCli) CmdVolumeRm(args ...string) error {
cmd := Cli.Subcmd("volume rm", []string{"VOLUME [VOLUME...]"}, "Remove a volume", true)
cmd.Require(flag.Min, 1)
cmd.ParseFlags(args, true)
var status = 0
for _, name := range cmd.Args() {
if err := cli.client.VolumeRemove(context.Background(), name); err != nil {
fmt.Fprintf(cli.err, "%s\n", err)
status = 1
continue
}
fmt.Fprintf(cli.out, "%s\n", name)
}
if status != 0 {
return Cli.StatusError{StatusCode: status}
}
return nil
}