]>
Commit | Line | Data |
---|---|---|
9b12e4fe JC |
1 | // Copyright 2015 go-dockerclient authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style | |
3 | // license that can be found in the LICENSE file. | |
4 | ||
5 | package docker | |
6 | ||
7 | import ( | |
8 | "encoding/json" | |
9 | "errors" | |
10 | "net/http" | |
11 | ) | |
12 | ||
13 | var ( | |
14 | // ErrNoSuchVolume is the error returned when the volume does not exist. | |
15 | ErrNoSuchVolume = errors.New("no such volume") | |
16 | ||
17 | // ErrVolumeInUse is the error returned when the volume requested to be removed is still in use. | |
18 | ErrVolumeInUse = errors.New("volume in use and cannot be removed") | |
19 | ) | |
20 | ||
21 | // Volume represents a volume. | |
22 | // | |
23 | // See https://goo.gl/FZA4BK for more details. | |
24 | type Volume struct { | |
25 | Name string `json:"Name" yaml:"Name"` | |
26 | Driver string `json:"Driver,omitempty" yaml:"Driver,omitempty"` | |
27 | Mountpoint string `json:"Mountpoint,omitempty" yaml:"Mountpoint,omitempty"` | |
28 | Labels map[string]string `json:"Labels,omitempty" yaml:"Labels,omitempty"` | |
29 | } | |
30 | ||
31 | // ListVolumesOptions specify parameters to the ListVolumes function. | |
32 | // | |
33 | // See https://goo.gl/FZA4BK for more details. | |
34 | type ListVolumesOptions struct { | |
35 | Filters map[string][]string | |
36 | } | |
37 | ||
38 | // ListVolumes returns a list of available volumes in the server. | |
39 | // | |
40 | // See https://goo.gl/FZA4BK for more details. | |
41 | func (c *Client) ListVolumes(opts ListVolumesOptions) ([]Volume, error) { | |
42 | resp, err := c.do("GET", "/volumes?"+queryString(opts), doOptions{}) | |
43 | if err != nil { | |
44 | return nil, err | |
45 | } | |
46 | defer resp.Body.Close() | |
47 | m := make(map[string]interface{}) | |
48 | if err := json.NewDecoder(resp.Body).Decode(&m); err != nil { | |
49 | return nil, err | |
50 | } | |
51 | var volumes []Volume | |
52 | volumesJSON, ok := m["Volumes"] | |
53 | if !ok { | |
54 | return volumes, nil | |
55 | } | |
56 | data, err := json.Marshal(volumesJSON) | |
57 | if err != nil { | |
58 | return nil, err | |
59 | } | |
60 | if err := json.Unmarshal(data, &volumes); err != nil { | |
61 | return nil, err | |
62 | } | |
63 | return volumes, nil | |
64 | } | |
65 | ||
66 | // CreateVolumeOptions specify parameters to the CreateVolume function. | |
67 | // | |
68 | // See https://goo.gl/pBUbZ9 for more details. | |
69 | type CreateVolumeOptions struct { | |
70 | Name string | |
71 | Driver string | |
72 | DriverOpts map[string]string | |
73 | } | |
74 | ||
75 | // CreateVolume creates a volume on the server. | |
76 | // | |
77 | // See https://goo.gl/pBUbZ9 for more details. | |
78 | func (c *Client) CreateVolume(opts CreateVolumeOptions) (*Volume, error) { | |
79 | resp, err := c.do("POST", "/volumes/create", doOptions{data: opts}) | |
80 | if err != nil { | |
81 | return nil, err | |
82 | } | |
83 | defer resp.Body.Close() | |
84 | var volume Volume | |
85 | if err := json.NewDecoder(resp.Body).Decode(&volume); err != nil { | |
86 | return nil, err | |
87 | } | |
88 | return &volume, nil | |
89 | } | |
90 | ||
91 | // InspectVolume returns a volume by its name. | |
92 | // | |
93 | // See https://goo.gl/0g9A6i for more details. | |
94 | func (c *Client) InspectVolume(name string) (*Volume, error) { | |
95 | resp, err := c.do("GET", "/volumes/"+name, doOptions{}) | |
96 | if err != nil { | |
97 | if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { | |
98 | return nil, ErrNoSuchVolume | |
99 | } | |
100 | return nil, err | |
101 | } | |
102 | defer resp.Body.Close() | |
103 | var volume Volume | |
104 | if err := json.NewDecoder(resp.Body).Decode(&volume); err != nil { | |
105 | return nil, err | |
106 | } | |
107 | return &volume, nil | |
108 | } | |
109 | ||
110 | // RemoveVolume removes a volume by its name. | |
111 | // | |
112 | // See https://goo.gl/79GNQz for more details. | |
113 | func (c *Client) RemoveVolume(name string) error { | |
114 | resp, err := c.do("DELETE", "/volumes/"+name, doOptions{}) | |
115 | if err != nil { | |
116 | if e, ok := err.(*Error); ok { | |
117 | if e.Status == http.StatusNotFound { | |
118 | return ErrNoSuchVolume | |
119 | } | |
120 | if e.Status == http.StatusConflict { | |
121 | return ErrVolumeInUse | |
122 | } | |
123 | } | |
124 | return nil | |
125 | } | |
126 | defer resp.Body.Close() | |
127 | return nil | |
128 | } |