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 }