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