bollard_next/
volume.rs

1//! Volume API: Create and manage persistent storage that can be attached to containers.
2
3use bytes::Bytes;
4use http::request::Builder;
5use http_body_util::Full;
6use hyper::Method;
7use serde_derive::{Deserialize, Serialize};
8
9use std::cmp::Eq;
10use std::collections::HashMap;
11use std::hash::Hash;
12
13use super::Docker;
14use crate::docker::BodyType;
15use crate::errors::Error;
16use crate::models::*;
17
18/// Parameters used in the [List Volume API](Docker::list_volumes())
19#[derive(Debug, Clone, Default, PartialEq, Serialize)]
20pub struct ListVolumesOptions<T>
21where
22    T: Into<String> + Eq + Hash + serde::ser::Serialize,
23{
24    /// JSON encoded value of the filters (a `map[string][]string`) to process on the volumes list. Available filters:
25    ///  - `dangling=<boolean>` When set to `true` (or `1`), returns all volumes that are not in use by a container. When set to `false` (or `0`), only volumes that are in use by one or more containers are returned.
26    ///  - `driver=<volume-driver-name>` Matches volumes based on their driver.
27    ///  - `label=<key>` or `label=<key>:<value>` Matches volumes based on the presence of a `label` alone or a `label` and a value.
28    ///  - `name=<volume-name>` Matches all or part of a volume name.
29    #[serde(serialize_with = "crate::docker::serialize_as_json")]
30    pub filters: HashMap<T, Vec<T>>,
31}
32
33/// Volume configuration used in the [Create Volume
34/// API](Docker::create_volume())
35#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
36#[serde(rename_all = "PascalCase")]
37pub struct CreateVolumeOptions<T>
38where
39    T: Into<String> + Eq + Hash + serde::ser::Serialize,
40{
41    /// The new volume's name. If not specified, Docker generates a name.
42    pub name: T,
43    /// Name of the volume driver to use.
44    pub driver: T,
45    /// A mapping of driver options and values. These options are passed directly to the driver and
46    /// are driver specific.
47    pub driver_opts: HashMap<T, T>,
48    /// User-defined key/value metadata.
49    pub labels: HashMap<T, T>,
50}
51
52/// Parameters used in the [Remove Volume API](super::Docker::remove_volume())
53#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize)]
54#[serde(rename_all = "camelCase")]
55pub struct RemoveVolumeOptions {
56    /// Force the removal of the volume.
57    pub force: bool,
58}
59
60/// Parameters used in the [Prune Volumes API](Docker::prune_volumes())
61///
62/// ## Examples
63///
64/// ```rust
65/// use bollard_next::volume::PruneVolumesOptions;
66///
67/// use std::collections::HashMap;
68///
69/// let mut filters = HashMap::new();
70/// filters.insert("label!", vec!["maintainer=some_maintainer"]);
71///
72/// PruneVolumesOptions{
73///     filters
74/// };
75/// ```
76///
77/// ```rust
78/// # use bollard_next::volume::PruneVolumesOptions;
79/// # use std::default::Default;
80///
81/// PruneVolumesOptions::<&str>{
82///     ..Default::default()
83/// };
84/// ```
85#[derive(Debug, Clone, Default, PartialEq, Serialize)]
86pub struct PruneVolumesOptions<T>
87where
88    T: Into<String> + Eq + Hash + serde::ser::Serialize,
89{
90    /// Filters to process on the prune list, encoded as JSON.
91    ///  - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or
92    ///    `label!=<key>=<value>`) Prune volumes with (or without, in case `label!=...` is used) the
93    ///    specified labels.
94    #[serde(serialize_with = "crate::docker::serialize_as_json")]
95    pub filters: HashMap<T, Vec<T>>,
96}
97
98impl Docker {
99    /// ---
100    ///
101    /// # List volumes
102    ///
103    /// # Arguments
104    ///
105    ///  - [List Volumes Options](ListVolumesOptions) struct.
106    ///
107    /// # Returns
108    ///
109    ///  - A [Volume List Response]VolumeListResponse) struct, wrapped in a
110    ///    Future.
111    ///
112    /// # Examples
113    ///
114    /// ```rust
115    /// # use bollard_next::Docker;
116    /// # let docker = Docker::connect_with_http_defaults().unwrap();
117    ///
118    /// use bollard_next::volume::ListVolumesOptions;
119    ///
120    /// use std::collections::HashMap;
121    ///
122    /// let mut filters = HashMap::new();
123    /// filters.insert("dangling", vec!("1"));
124    ///
125    /// let options = ListVolumesOptions {
126    ///     filters,
127    /// };
128    ///
129    /// docker.list_volumes(Some(options));
130    /// ```
131    pub async fn list_volumes<T>(
132        &self,
133        options: Option<ListVolumesOptions<T>>,
134    ) -> Result<VolumeListResponse, Error>
135    where
136        T: Into<String> + Eq + Hash + serde::ser::Serialize,
137    {
138        let url = "/volumes";
139
140        let req = self.build_request(
141            url,
142            Builder::new().method(Method::GET),
143            options,
144            Ok(BodyType::Left(Full::new(Bytes::new()))),
145        );
146
147        self.process_into_value(req).await
148    }
149
150    /// ---
151    ///
152    /// # Create Volume
153    ///
154    /// Create a new volume.
155    ///
156    /// # Arguments
157    ///
158    ///  - [Create Volume Options](CreateVolumeOptions) struct.
159    ///
160    /// # Returns
161    ///
162    ///  - A [Volume](Volume) struct, wrapped in a
163    ///    Future.
164    ///
165    /// # Examples
166    ///
167    /// ```rust
168    /// # use bollard_next::Docker;
169    /// # let docker = Docker::connect_with_http_defaults().unwrap();
170    ///
171    /// use bollard_next::volume::CreateVolumeOptions;
172    ///
173    /// use std::default::Default;
174    ///
175    /// let config = CreateVolumeOptions {
176    ///     name: "certs",
177    ///     ..Default::default()
178    /// };
179    ///
180    /// docker.create_volume(config);
181    /// ```
182    pub async fn create_volume<T>(&self, config: CreateVolumeOptions<T>) -> Result<Volume, Error>
183    where
184        T: Into<String> + Eq + Hash + serde::ser::Serialize,
185    {
186        let url = "/volumes/create";
187
188        let req = self.build_request(
189            url,
190            Builder::new().method(Method::POST),
191            None::<String>,
192            Docker::serialize_payload(Some(config)),
193        );
194
195        self.process_into_value(req).await
196    }
197
198    /// ---
199    ///
200    /// # Inspect a Volume
201    ///
202    /// # Arguments
203    ///
204    ///  - Volume name as a string slice.
205    ///
206    /// # Returns
207    ///
208    ///  - A [Volume](Volume) struct, wrapped in a
209    ///    Future.
210    ///
211    /// # Examples
212    ///
213    /// ```rust
214    /// # use bollard_next::Docker;
215    /// # let docker = Docker::connect_with_http_defaults().unwrap();
216    ///
217    /// docker.inspect_volume("my_volume_name");
218    /// ```
219    pub async fn inspect_volume(&self, volume_name: &str) -> Result<Volume, Error> {
220        let url = format!("/volumes/{volume_name}");
221
222        let req = self.build_request(
223            &url,
224            Builder::new().method(Method::GET),
225            None::<String>,
226            Ok(BodyType::Left(Full::new(Bytes::new()))),
227        );
228
229        self.process_into_value(req).await
230    }
231
232    /// ---
233    ///
234    /// # Remove a Volume
235    ///
236    /// # Arguments
237    ///
238    ///  - Volume name as a string slice.
239    ///
240    /// # Arguments
241    ///
242    ///  - [Remove Volume Options](RemoveVolumeOptions) struct.
243    ///
244    /// # Returns
245    ///
246    ///  - unit type `()`, wrapped in a Future.
247    ///
248    /// # Examples
249    ///
250    /// ```rust
251    /// # use bollard_next::Docker;
252    /// # let docker = Docker::connect_with_http_defaults().unwrap();
253    ///
254    /// use bollard_next::volume::RemoveVolumeOptions;
255    ///
256    /// let options = RemoveVolumeOptions {
257    ///     force: true,
258    /// };
259    ///
260    /// docker.remove_volume("my_volume_name", Some(options));
261    /// ```
262    pub async fn remove_volume(
263        &self,
264        volume_name: &str,
265        options: Option<RemoveVolumeOptions>,
266    ) -> Result<(), Error> {
267        let url = format!("/volumes/{volume_name}");
268
269        let req = self.build_request(
270            &url,
271            Builder::new().method(Method::DELETE),
272            options,
273            Ok(BodyType::Left(Full::new(Bytes::new()))),
274        );
275
276        self.process_into_unit(req).await
277    }
278
279    /// ---
280    ///
281    /// # Prune Volumes
282    ///
283    /// Delete unused volumes.
284    ///
285    /// # Arguments
286    ///
287    ///  - A [Prune Volumes Options](PruneVolumesOptions) struct.
288    ///
289    /// # Returns
290    ///
291    ///  - A [Volume Prune Response](VolumePruneResponse) struct.
292    ///
293    /// # Examples
294    ///
295    /// ```rust
296    /// # use bollard_next::Docker;
297    /// # let docker = Docker::connect_with_http_defaults().unwrap();
298    ///
299    /// use bollard_next::volume::PruneVolumesOptions;
300    ///
301    /// use std::collections::HashMap;
302    ///
303    /// let mut filters = HashMap::new();
304    /// filters.insert("label", vec!["maintainer=some_maintainer"]);
305    ///
306    /// let options = PruneVolumesOptions {
307    ///     filters,
308    /// };
309    ///
310    /// docker.prune_volumes(Some(options));
311    /// ```
312    pub async fn prune_volumes<T>(
313        &self,
314        options: Option<PruneVolumesOptions<T>>,
315    ) -> Result<VolumePruneResponse, Error>
316    where
317        T: Into<String> + Eq + Hash + serde::ser::Serialize,
318    {
319        let url = "/volumes/prune";
320
321        let req = self.build_request(
322            url,
323            Builder::new().method(Method::POST),
324            options,
325            Ok(BodyType::Left(Full::new(Bytes::new()))),
326        );
327
328        self.process_into_value(req).await
329    }
330}