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 }