bollard_next/system.rs
1//! System API: interface for interacting with the Docker server and/or Registry.
2
3use bytes::Bytes;
4use futures_core::Stream;
5use http::request::Builder;
6use http_body_util::Full;
7use hyper::Method;
8use serde_derive::{Deserialize, Serialize};
9use serde_json::value::Value;
10
11use std::collections::HashMap;
12use std::hash::Hash;
13
14use super::Docker;
15use crate::docker::BodyType;
16use crate::errors::Error;
17use crate::models::*;
18
19/// Response of Engine API: GET \"/version\"
20#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
21#[allow(missing_docs)]
22pub struct Version {
23 #[serde(rename = "Platform")]
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub platform: Option<SystemVersionPlatform>,
26
27 /// Information about system components
28 #[serde(rename = "Components")]
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub components: Option<Vec<VersionComponents>>,
31
32 /// The version of the daemon
33 #[serde(rename = "Version")]
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub version: Option<String>,
36
37 /// The default (and highest) API version that is supported by the daemon
38 #[serde(rename = "ApiVersion")]
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub api_version: Option<String>,
41
42 /// The minimum API version that is supported by the daemon
43 #[serde(rename = "MinAPIVersion")]
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub min_api_version: Option<String>,
46
47 /// The Git commit of the source code that was used to build the daemon
48 #[serde(rename = "GitCommit")]
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub git_commit: Option<String>,
51
52 /// The version Go used to compile the daemon, and the version of the Go runtime in use.
53 #[serde(rename = "GoVersion")]
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub go_version: Option<String>,
56
57 /// The operating system that the daemon is running on (\"linux\" or \"windows\")
58 #[serde(rename = "Os")]
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub os: Option<String>,
61
62 /// The architecture that the daemon is running on
63 #[serde(rename = "Arch")]
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub arch: Option<String>,
66
67 /// The kernel version (`uname -r`) that the daemon is running on. This field is omitted when empty.
68 #[serde(rename = "KernelVersion")]
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub kernel_version: Option<String>,
71
72 /// Indicates if the daemon is started with experimental features enabled. This field is omitted when empty / false.
73 #[serde(rename = "Experimental")]
74 #[serde(skip_serializing_if = "Option::is_none")]
75 #[cfg(windows)]
76 pub experimental: Option<bool>,
77 #[cfg(not(windows))]
78 pub experimental: Option<String>,
79
80 /// The date and time that the daemon was compiled.
81 #[serde(rename = "BuildTime")]
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub build_time: Option<String>,
84}
85
86#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
87#[allow(missing_docs)]
88pub struct VersionComponents {
89 /// Name of the component
90 #[serde(rename = "Name")]
91 pub name: String,
92
93 /// Version of the component
94 #[serde(rename = "Version")]
95 pub version: String,
96
97 /// Key/value pairs of strings with additional information about the component. These values are intended for informational purposes only, and their content is not defined, and not part of the API specification. These messages can be printed by the client as information to the user.
98 #[serde(rename = "Details")]
99 #[serde(skip_serializing_if = "Option::is_none")]
100 pub details: Option<HashMap<String, Value>>,
101}
102
103/// Parameters used in the [Events API](Docker::events())
104///
105/// ## Examples
106///
107/// ```rust
108/// use bollard_next::system::EventsOptions;
109/// use time::{Duration, OffsetDateTime};
110/// use std::collections::HashMap;
111///
112/// # fn main() {
113/// EventsOptions::<String>{
114/// since: Some(OffsetDateTime::now_utc() - Duration::minutes(20)),
115/// until: Some(OffsetDateTime::now_utc()),
116/// filters: HashMap::new()
117/// };
118/// # }
119/// ```
120#[derive(Debug, Default, Clone, PartialEq, Serialize)]
121pub struct EventsOptions<T>
122where
123 T: Into<String> + Eq + Hash + serde::ser::Serialize,
124{
125 /// Show events created since this timestamp then stream new events.
126 #[cfg(all(feature = "chrono", not(feature = "time")))]
127 #[serde(serialize_with = "crate::docker::serialize_as_timestamp")]
128 pub since: Option<chrono::DateTime<chrono::Utc>>,
129 /// Show events created until this timestamp then stop streaming.
130 #[cfg(all(feature = "chrono", not(feature = "time")))]
131 #[serde(serialize_with = "crate::docker::serialize_as_timestamp")]
132 pub until: Option<chrono::DateTime<chrono::Utc>>,
133 /// Show events created since this timestamp then stream new events.
134 #[cfg(feature = "time")]
135 #[serde(serialize_with = "crate::docker::serialize_as_timestamp")]
136 pub since: Option<time::OffsetDateTime>,
137 /// Show events created until this timestamp then stop streaming.
138 #[cfg(feature = "time")]
139 #[serde(serialize_with = "crate::docker::serialize_as_timestamp")]
140 pub until: Option<time::OffsetDateTime>,
141 /// Show events created since this timestamp then stream new events.
142 #[cfg(not(any(feature = "time", feature = "chrono")))]
143 pub since: Option<String>,
144 /// Show events created until this timestamp then stop streaming.
145 #[cfg(not(any(feature = "time", feature = "chrono")))]
146 pub until: Option<String>,
147 /// A JSON encoded value of filters (a `map[string][]string`) to process on the event list. Available filters:
148 /// - `config=<string>` config name or ID
149 /// - `container=<string>` container name or ID
150 /// - `daemon=<string>` daemon name or ID
151 /// - `event=<string>` event type
152 /// - `image=<string>` image name or ID
153 /// - `label=<string>` image or container label
154 /// - `network=<string>` network name or ID
155 /// - `node=<string>` node ID
156 /// - `plugin`= plugin name or ID
157 /// - `scope`= local or swarm
158 /// - `secret=<string>` secret name or ID
159 /// - `service=<string>` service name or ID
160 /// - `type=<string>` object to filter by, one of `container`, `image`, `volume`, `network`, `daemon`, `plugin`, `node`, `service`, `secret` or `config`
161 /// - `volume=<string>` volume name
162 #[serde(serialize_with = "crate::docker::serialize_as_json")]
163 pub filters: HashMap<T, Vec<T>>,
164}
165
166impl Docker {
167 /// ---
168 ///
169 /// # Version
170 ///
171 /// Returns the version of Docker that is running and various information about the system that
172 /// Docker is running on.
173 ///
174 /// # Returns
175 ///
176 /// - [Version](Version), wrapped in a Future.
177 ///
178 /// # Examples
179 ///
180 /// ```rust
181 /// # use bollard_next::Docker;
182 /// # let docker = Docker::connect_with_http_defaults().unwrap();
183 /// docker.version();
184 /// ```
185 pub async fn version(&self) -> Result<Version, Error> {
186 let req = self.build_request(
187 "/version",
188 Builder::new().method(Method::GET),
189 None::<String>,
190 Ok(BodyType::Left(Full::new(Bytes::new()))),
191 );
192
193 self.process_into_value(req).await
194 }
195
196 /// ---
197 ///
198 /// # Info
199 ///
200 /// Returns Docker client and server information that is running.
201 ///
202 /// # Returns
203 ///
204 /// - [Info](SystemInfo), wrapped in a Future.
205 ///
206 /// # Examples
207 ///
208 /// ```rust
209 /// # use bollard_next::Docker;
210 /// # let docker = Docker::connect_with_http_defaults().unwrap();
211 /// docker.info();
212 /// ```
213 pub async fn info(&self) -> Result<SystemInfo, Error> {
214 let req = self.build_request(
215 "/info",
216 Builder::new().method(Method::GET),
217 None::<String>,
218 Ok(BodyType::Left(Full::new(Bytes::new()))),
219 );
220
221 self.process_into_value(req).await
222 }
223
224 /// ---
225 ///
226 /// # Ping
227 ///
228 /// This is a dummy endpoint you can use to test if the server is accessible.
229 /// # Returns - A [String](std::string::String), wrapped in a Future. # Examples
230 ///
231 /// ```rust
232 /// # use bollard_next::Docker;
233 /// # let docker = Docker::connect_with_http_defaults().unwrap();
234 ///
235 /// docker.ping();
236 /// ```
237 pub async fn ping(&self) -> Result<String, Error> {
238 let url = "/_ping";
239
240 let req = self.build_request(
241 url,
242 Builder::new().method(Method::GET),
243 None::<String>,
244 Ok(BodyType::Left(Full::new(Bytes::new()))),
245 );
246
247 self.process_into_string(req).await
248 }
249
250 /// ---
251 ///
252 /// # Events
253 ///
254 /// Stream real-time events from the server.
255 ///
256 /// # Returns
257 ///
258 /// - [EventMessage](crate::models::EventMessage),
259 /// wrapped in a Stream.
260 ///
261 /// # Examples
262 ///
263 /// ```rust
264 /// use bollard_next::system::EventsOptions;
265 /// use time::{Duration, OffsetDateTime};
266 /// use std::collections::HashMap;
267 ///
268 /// # use bollard_next::Docker;
269 /// # let docker = Docker::connect_with_http_defaults().unwrap();
270 ///
271 /// docker.events(Some(EventsOptions::<String> {
272 /// since: Some(OffsetDateTime::now_utc() - Duration::minutes(20)),
273 /// until: Some(OffsetDateTime::now_utc()),
274 /// filters: HashMap::new(),
275 /// }));
276 /// ```
277 pub fn events<T>(
278 &self,
279 options: Option<EventsOptions<T>>,
280 ) -> impl Stream<Item = Result<EventMessage, Error>>
281 where
282 T: Into<String> + Eq + Hash + serde::ser::Serialize,
283 {
284 let url = "/events";
285
286 let req = self.build_request(
287 url,
288 Builder::new().method(Method::GET),
289 options,
290 Ok(BodyType::Left(Full::new(Bytes::new()))),
291 );
292
293 self.process_into_stream(req)
294 }
295
296 /// ---
297 ///
298 /// # Get data usage information
299 ///
300 /// Show docker disk usage
301 ///
302 /// # Returns
303 ///
304 /// - [System Data Usage
305 /// Response](SystemDataUsageResponse), wrapped in a
306 /// Future.
307 ///
308 /// # Examples
309 ///
310 /// ```rust
311 /// # use bollard_next::Docker;
312 /// # let docker = Docker::connect_with_http_defaults().unwrap();
313 /// docker.df();
314 /// ```
315 pub async fn df(&self) -> Result<SystemDataUsageResponse, Error> {
316 let url = "/system/df";
317
318 let req = self.build_request(
319 url,
320 Builder::new().method(Method::GET),
321 None::<String>,
322 Ok(BodyType::Left(Full::new(Bytes::new()))),
323 );
324
325 self.process_into_value(req).await
326 }
327}