github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/api/client/volume.go (about)

     1  package client
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"net/url"
     9  	"text/tabwriter"
    10  	"text/template"
    11  
    12  	"github.com/docker/docker/api/types"
    13  	Cli "github.com/docker/docker/cli"
    14  	"github.com/docker/docker/opts"
    15  	flag "github.com/docker/docker/pkg/mflag"
    16  	"github.com/docker/docker/pkg/parsers/filters"
    17  )
    18  
    19  // CmdVolume is the parent subcommand for all volume commands
    20  //
    21  // Usage: docker volume <COMMAND> <OPTS>
    22  func (cli *DockerCli) CmdVolume(args ...string) error {
    23  	description := "Manage Docker volumes\n\nCommands:\n"
    24  	commands := [][]string{
    25  		{"create", "Create a volume"},
    26  		{"inspect", "Return low-level information on a volume"},
    27  		{"ls", "List volumes"},
    28  		{"rm", "Remove a volume"},
    29  	}
    30  
    31  	for _, cmd := range commands {
    32  		description += fmt.Sprintf("  %-25.25s%s\n", cmd[0], cmd[1])
    33  	}
    34  
    35  	description += "\nRun 'docker volume COMMAND --help' for more information on a command."
    36  	cmd := Cli.Subcmd("volume", []string{"[COMMAND]"}, description, true)
    37  	cmd.ParseFlags(args, true)
    38  
    39  	return cli.CmdVolumeLs(args...)
    40  }
    41  
    42  // CmdVolumeLs outputs a list of Docker volumes.
    43  //
    44  // Usage: docker volume ls [OPTIONS]
    45  func (cli *DockerCli) CmdVolumeLs(args ...string) error {
    46  	cmd := Cli.Subcmd("volume ls", nil, "List volumes", true)
    47  
    48  	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display volume names")
    49  	flFilter := opts.NewListOpts(nil)
    50  	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')")
    51  
    52  	cmd.Require(flag.Exact, 0)
    53  	cmd.ParseFlags(args, true)
    54  
    55  	volFilterArgs := filters.Args{}
    56  	for _, f := range flFilter.GetAll() {
    57  		var err error
    58  		volFilterArgs, err = filters.ParseFlag(f, volFilterArgs)
    59  		if err != nil {
    60  			return err
    61  		}
    62  	}
    63  
    64  	v := url.Values{}
    65  	if len(volFilterArgs) > 0 {
    66  		filterJSON, err := filters.ToParam(volFilterArgs)
    67  		if err != nil {
    68  			return err
    69  		}
    70  		v.Set("filters", filterJSON)
    71  	}
    72  
    73  	resp, err := cli.call("GET", "/volumes?"+v.Encode(), nil, nil)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	var volumes types.VolumesListResponse
    79  	if err := json.NewDecoder(resp.body).Decode(&volumes); err != nil {
    80  		return err
    81  	}
    82  
    83  	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
    84  	if !*quiet {
    85  		fmt.Fprintf(w, "DRIVER \tVOLUME NAME")
    86  		fmt.Fprintf(w, "\n")
    87  	}
    88  
    89  	for _, vol := range volumes.Volumes {
    90  		if *quiet {
    91  			fmt.Fprintln(w, vol.Name)
    92  			continue
    93  		}
    94  		fmt.Fprintf(w, "%s\t%s\n", vol.Driver, vol.Name)
    95  	}
    96  	w.Flush()
    97  	return nil
    98  }
    99  
   100  // CmdVolumeInspect displays low-level information on one or more volumes.
   101  //
   102  // Usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...]
   103  func (cli *DockerCli) CmdVolumeInspect(args ...string) error {
   104  	cmd := Cli.Subcmd("volume inspect", []string{"[VOLUME NAME]"}, "Return low-level information on a volume", true)
   105  	tmplStr := cmd.String([]string{"f", "-format"}, "", "Format the output using the given go template.")
   106  	if err := cmd.Parse(args); err != nil {
   107  		return nil
   108  	}
   109  
   110  	cmd.Require(flag.Min, 1)
   111  	cmd.ParseFlags(args, true)
   112  
   113  	var tmpl *template.Template
   114  	if *tmplStr != "" {
   115  		var err error
   116  		tmpl, err = template.New("").Funcs(funcMap).Parse(*tmplStr)
   117  		if err != nil {
   118  			return err
   119  		}
   120  	}
   121  
   122  	var status = 0
   123  	var volumes []*types.Volume
   124  	for _, name := range cmd.Args() {
   125  		resp, err := cli.call("GET", "/volumes/"+name, nil, nil)
   126  		if err != nil {
   127  			return err
   128  		}
   129  
   130  		var volume types.Volume
   131  		if err := json.NewDecoder(resp.body).Decode(&volume); err != nil {
   132  			fmt.Fprintf(cli.err, "%s\n", err)
   133  			status = 1
   134  			continue
   135  		}
   136  
   137  		if tmpl == nil {
   138  			volumes = append(volumes, &volume)
   139  			continue
   140  		}
   141  
   142  		if err := tmpl.Execute(cli.out, &volume); err != nil {
   143  			if err := tmpl.Execute(cli.out, &volume); err != nil {
   144  				fmt.Fprintf(cli.err, "%s\n", err)
   145  				status = 1
   146  				continue
   147  			}
   148  		}
   149  		io.WriteString(cli.out, "\n")
   150  	}
   151  
   152  	if tmpl != nil {
   153  		return nil
   154  	}
   155  
   156  	b, err := json.MarshalIndent(volumes, "", "    ")
   157  	if err != nil {
   158  		return err
   159  	}
   160  	_, err = io.Copy(cli.out, bytes.NewReader(b))
   161  	if err != nil {
   162  		return err
   163  	}
   164  	io.WriteString(cli.out, "\n")
   165  
   166  	if status != 0 {
   167  		return Cli.StatusError{StatusCode: status}
   168  	}
   169  	return nil
   170  }
   171  
   172  // CmdVolumeCreate creates a new container from a given image.
   173  //
   174  // Usage: docker volume create [OPTIONS]
   175  func (cli *DockerCli) CmdVolumeCreate(args ...string) error {
   176  	cmd := Cli.Subcmd("volume create", nil, "Create a volume", true)
   177  	flDriver := cmd.String([]string{"d", "-driver"}, "local", "Specify volume driver name")
   178  	flName := cmd.String([]string{"-name"}, "", "Specify volume name")
   179  
   180  	flDriverOpts := opts.NewMapOpts(nil, nil)
   181  	cmd.Var(flDriverOpts, []string{"o", "-opt"}, "Set driver specific options")
   182  
   183  	cmd.Require(flag.Exact, 0)
   184  	cmd.ParseFlags(args, true)
   185  
   186  	volReq := &types.VolumeCreateRequest{
   187  		Driver:     *flDriver,
   188  		DriverOpts: flDriverOpts.GetAll(),
   189  	}
   190  
   191  	if *flName != "" {
   192  		volReq.Name = *flName
   193  	}
   194  
   195  	resp, err := cli.call("POST", "/volumes", volReq, nil)
   196  	if err != nil {
   197  		return err
   198  	}
   199  
   200  	var vol types.Volume
   201  	if err := json.NewDecoder(resp.body).Decode(&vol); err != nil {
   202  		return err
   203  	}
   204  	fmt.Fprintf(cli.out, "%s\n", vol.Name)
   205  	return nil
   206  }
   207  
   208  // CmdVolumeRm removes one or more containers.
   209  //
   210  // Usage: docker volume rm VOLUME [VOLUME...]
   211  func (cli *DockerCli) CmdVolumeRm(args ...string) error {
   212  	cmd := Cli.Subcmd("volume rm", []string{"[NAME]"}, "Remove a volume", true)
   213  	cmd.Require(flag.Min, 1)
   214  	cmd.ParseFlags(args, true)
   215  
   216  	var status = 0
   217  	for _, name := range cmd.Args() {
   218  		_, err := cli.call("DELETE", "/volumes/"+name, nil, nil)
   219  		if err != nil {
   220  			fmt.Fprintf(cli.err, "%s\n", err)
   221  			status = 1
   222  			continue
   223  		}
   224  		fmt.Fprintf(cli.out, "%s\n", name)
   225  	}
   226  
   227  	if status != 0 {
   228  		return Cli.StatusError{StatusCode: status}
   229  	}
   230  	return nil
   231  }