1 //! Container API: run docker containers and manage their lifecycle
2 
3 use arrayvec::ArrayVec;
4 use chrono::{DateTime, Utc};
5 use futures_core::Stream;
6 use http::header::CONTENT_TYPE;
7 use http::request::Builder;
8 use hyper::{body::Bytes, Body, Method};
9 use serde::Serialize;
10 use serde_json;
11 
12 use std::cmp::Eq;
13 use std::collections::HashMap;
14 use std::fmt;
15 use std::hash::Hash;
16 
17 use super::Docker;
18 use crate::docker::{FALSE_STR, TRUE_STR};
19 use crate::errors::Error;
20 use crate::errors::ErrorKind::JsonSerializeError;
21 
22 use crate::models::*;
23 
24 /// Parameters used in the [List Container API](../struct.Docker.html#method.list_containers)
25 ///
26 /// ## Examples
27 ///
28 /// ```rust
29 /// use bollard::container::ListContainersOptions;
30 ///
31 /// use std::collections::HashMap;
32 /// use std::default::Default;
33 ///
34 /// let mut filters = HashMap::new();
35 /// filters.insert("health", vec!("unhealthy"));
36 ///
37 /// ListContainersOptions{
38 ///     all: true,
39 ///     filters: filters,
40 ///     ..Default::default()
41 /// };
42 /// ```
43 ///
44 /// ```rust
45 /// # use bollard::container::ListContainersOptions;
46 /// # use std::default::Default;
47 /// ListContainersOptions::<String>{
48 ///     ..Default::default()
49 /// };
50 /// ```
51 #[derive(Debug, Clone, Default)]
52 pub struct ListContainersOptions<T>
53 where
54     T: AsRef<str> + Eq + Hash,
55 {
56     /// Return all containers. By default, only running containers are shown
57     pub all: bool,
58     /// Return this number of most recently created containers, including non-running ones
59     pub limit: Option<isize>,
60     /// Return the size of container as fields `SizeRw` and `SizeRootFs`
61     pub size: bool,
62     /// Filters to process on the container list, encoded as JSON. Available filters:
63     ///  - `ancestor`=`(<image-name>[:<tag>]`, `<image id>`, or `<image@digest>`)
64     ///  - `before`=(`<container id>` or `<container name>`)
65     ///  - `expose`=(`<port>[/<proto>]`|`<startport-endport>`/`[<proto>]`)
66     ///  - `exited`=`<int>` containers with exit code of `<int>`
67     ///  - `health`=(`starting`|`healthy`|`unhealthy`|`none`)
68     ///  - `id`=`<ID>` a container's ID
69     ///  - `isolation`=(`default`|`process`|`hyperv`) (Windows daemon only)
70     ///  - `is-task`=`(true`|`false`)
71     ///  - `label`=`key` or `label`=`"key=value"` of a container label
72     ///  - `name`=`<name>` a container's name
73     ///  - `network`=(`<network id>` or `<network name>`)
74     ///  - `publish`=(`<port>[/<proto>]`|`<startport-endport>`/`[<proto>]`)
75     ///  - `since`=(`<container id>` or `<container name>`)
76     ///  - `status`=(`created`|`restarting`|`running`|`removing`|`paused`|`exited`|`dead`)
77     ///  - `volume`=(`<volume name>` or `<mount point destination>`)
78     pub filters: HashMap<T, Vec<T>>,
79 }
80 
81 #[allow(missing_docs)]
82 /// Trait providing implementations for [List Containers Options](struct.ListContainersOptions.html)
83 /// struct.
84 pub trait ListContainersQueryParams<K, V>
85 where
86     K: AsRef<str>,
87     V: AsRef<str>,
88 {
into_array(self) -> Result<ArrayVec<[(K, V); 4]>, Error>89     fn into_array(self) -> Result<ArrayVec<[(K, V); 4]>, Error>;
90 }
91 
92 impl<'a, T: AsRef<str> + Eq + Hash> ListContainersQueryParams<&'a str, String>
93     for ListContainersOptions<T>
94 where
95     T: ::serde::Serialize,
96 {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 4]>, Error>97     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 4]>, Error> {
98         Ok(ArrayVec::from([
99             ("all", self.all.to_string()),
100             (
101                 "limit",
102                 self.limit
103                     .map(|l| l.to_string())
104                     .unwrap_or_else(|| String::new()),
105             ),
106             ("size", self.size.to_string()),
107             (
108                 "filters",
109                 serde_json::to_string(&self.filters).map_err(|e| JsonSerializeError { err: e })?,
110             ),
111         ]))
112     }
113 }
114 
115 /// Parameters used in the [Create Container API](../struct.Docker.html#method.create_container)
116 ///
117 /// ## Examples
118 ///
119 /// ```rust
120 /// use bollard::container::CreateContainerOptions;
121 ///
122 /// CreateContainerOptions{
123 ///     name: "my-new-container",
124 /// };
125 /// ```
126 #[derive(Debug, Clone, Default)]
127 pub struct CreateContainerOptions<T>
128 where
129     T: AsRef<str>,
130 {
131     /// Assign the specified name to the container.
132     pub name: T,
133 }
134 
135 /// Trait providing implementations for [Create Container Options](struct.CreateContainerOptions.html)
136 /// struct.
137 #[allow(missing_docs)]
138 pub trait CreateContainerQueryParams<K, V>
139 where
140     K: AsRef<str>,
141     V: AsRef<str>,
142 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>143     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
144 }
145 
146 impl<'a, T: AsRef<str>> CreateContainerQueryParams<&'a str, T> for CreateContainerOptions<T> {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error>147     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error> {
148         Ok(ArrayVec::from([("name", self.name)]))
149     }
150 }
151 
152 /// This container's networking configuration.
153 #[derive(Debug, Clone, Serialize, Deserialize)]
154 #[serde(rename_all = "PascalCase")]
155 #[allow(missing_docs)]
156 pub struct NetworkingConfig<T: Into<String> + Hash + Eq> {
157     pub endpoints_config: HashMap<T, EndpointSettings>,
158 }
159 
160 /// Container to create.
161 #[derive(Debug, Clone, Default, Serialize)]
162 pub struct Config<T>
163 where
164     T: Into<String> + Eq + Hash,
165 {
166     /// The hostname to use for the container, as a valid RFC 1123 hostname.
167     #[serde(rename = "Hostname")]
168     #[serde(skip_serializing_if = "Option::is_none")]
169     pub hostname: Option<T>,
170 
171     /// The domain name to use for the container.
172     #[serde(rename = "Domainname")]
173     #[serde(skip_serializing_if = "Option::is_none")]
174     pub domainname: Option<T>,
175 
176     /// The user that commands are run as inside the container.
177     #[serde(rename = "User")]
178     #[serde(skip_serializing_if = "Option::is_none")]
179     pub user: Option<T>,
180 
181     /// Whether to attach to `stdin`.
182     #[serde(rename = "AttachStdin")]
183     #[serde(skip_serializing_if = "Option::is_none")]
184     pub attach_stdin: Option<bool>,
185 
186     /// Whether to attach to `stdout`.
187     #[serde(rename = "AttachStdout")]
188     #[serde(skip_serializing_if = "Option::is_none")]
189     pub attach_stdout: Option<bool>,
190 
191     /// Whether to attach to `stderr`.
192     #[serde(rename = "AttachStderr")]
193     #[serde(skip_serializing_if = "Option::is_none")]
194     pub attach_stderr: Option<bool>,
195 
196     /// An object mapping ports to an empty object in the form:  `{\"<port>/<tcp|udp|sctp>\": {}}`
197     #[serde(rename = "ExposedPorts")]
198     #[serde(skip_serializing_if = "Option::is_none")]
199     pub exposed_ports: Option<HashMap<T, HashMap<(), ()>>>,
200 
201     /// Attach standard streams to a TTY, including `stdin` if it is not closed.
202     #[serde(rename = "Tty")]
203     #[serde(skip_serializing_if = "Option::is_none")]
204     pub tty: Option<bool>,
205 
206     /// Open `stdin`
207     #[serde(rename = "OpenStdin")]
208     #[serde(skip_serializing_if = "Option::is_none")]
209     pub open_stdin: Option<bool>,
210 
211     /// Close `stdin` after one attached client disconnects
212     #[serde(rename = "StdinOnce")]
213     #[serde(skip_serializing_if = "Option::is_none")]
214     pub stdin_once: Option<bool>,
215 
216     /// A list of environment variables to set inside the container in the form `[\"VAR=value\", ...]`. A variable without `=` is removed from the environment, rather than to have an empty value.
217     #[serde(rename = "Env")]
218     #[serde(skip_serializing_if = "Option::is_none")]
219     pub env: Option<Vec<T>>,
220 
221     /// Command to run specified as a string or an array of strings.
222     #[serde(rename = "Cmd")]
223     #[serde(skip_serializing_if = "Option::is_none")]
224     pub cmd: Option<Vec<T>>,
225 
226     /// A TEST to perform TO Check that the container is healthy.
227     #[serde(rename = "Healthcheck")]
228     #[serde(skip_serializing_if = "Option::is_none")]
229     pub healthcheck: Option<HealthConfig>,
230 
231     /// Command is already escaped (Windows only)
232     #[serde(rename = "ArgsEscaped")]
233     #[serde(skip_serializing_if = "Option::is_none")]
234     pub args_escaped: Option<bool>,
235 
236     /// The name of the image to use when creating the container
237     #[serde(rename = "Image")]
238     #[serde(skip_serializing_if = "Option::is_none")]
239     pub image: Option<T>,
240 
241     /// An object mapping mount point paths inside the container to empty objects.
242     #[serde(rename = "Volumes")]
243     #[serde(skip_serializing_if = "Option::is_none")]
244     pub volumes: Option<HashMap<T, HashMap<(), ()>>>,
245 
246     /// The working directory for commands to run in.
247     #[serde(rename = "WorkingDir")]
248     #[serde(skip_serializing_if = "Option::is_none")]
249     pub working_dir: Option<T>,
250 
251     /// The entry point for the container as a string or an array of strings.  If the array consists of exactly one empty string (`[\"\"]`) then the entry point is reset to system default (i.e., the entry point used by docker when there is no `ENTRYPOINT` instruction in the `Dockerfile`).
252     #[serde(rename = "Entrypoint")]
253     #[serde(skip_serializing_if = "Option::is_none")]
254     pub entrypoint: Option<Vec<T>>,
255 
256     /// Disable networking for the container.
257     #[serde(rename = "NetworkDisabled")]
258     #[serde(skip_serializing_if = "Option::is_none")]
259     pub network_disabled: Option<bool>,
260 
261     /// MAC address of the container.
262     #[serde(rename = "MacAddress")]
263     #[serde(skip_serializing_if = "Option::is_none")]
264     pub mac_address: Option<T>,
265 
266     /// `ONBUILD` metadata that were defined in the image's `Dockerfile`.
267     #[serde(rename = "OnBuild")]
268     #[serde(skip_serializing_if = "Option::is_none")]
269     pub on_build: Option<Vec<T>>,
270 
271     /// User-defined key/value metadata.
272     #[serde(rename = "Labels")]
273     #[serde(skip_serializing_if = "Option::is_none")]
274     pub labels: Option<HashMap<T, T>>,
275 
276     /// Signal to stop a container as a string or unsigned integer.
277     #[serde(rename = "StopSignal")]
278     #[serde(skip_serializing_if = "Option::is_none")]
279     pub stop_signal: Option<T>,
280 
281     /// Timeout to stop a container in seconds.
282     #[serde(rename = "StopTimeout")]
283     #[serde(skip_serializing_if = "Option::is_none")]
284     pub stop_timeout: Option<i64>,
285 
286     /// Shell for when `RUN`, `CMD`, and `ENTRYPOINT` uses a shell.
287     #[serde(rename = "Shell")]
288     #[serde(skip_serializing_if = "Option::is_none")]
289     pub shell: Option<Vec<T>>,
290 
291     /// Container configuration that depends on the host we are running on.
292     /// Shell for when `RUN`, `CMD`, and `ENTRYPOINT` uses a shell.
293     #[serde(rename = "HostConfig")]
294     #[serde(skip_serializing_if = "Option::is_none")]
295     pub host_config: Option<HostConfig>,
296 
297     /// This container's networking configuration.
298     #[serde(rename = "NetworkingConfig")]
299     #[serde(skip_serializing_if = "Option::is_none")]
300     pub networking_config: Option<NetworkingConfig<T>>,
301 }
302 
303 impl From<ContainerConfig> for Config<String> {
from(container: ContainerConfig) -> Self304     fn from(container: ContainerConfig) -> Self {
305         Config {
306             hostname: container.hostname,
307             domainname: container.domainname,
308             user: container.user,
309             attach_stdin: container.attach_stdin,
310             attach_stdout: container.attach_stdout,
311             attach_stderr: container.attach_stderr,
312             exposed_ports: container.exposed_ports,
313             tty: container.tty,
314             open_stdin: container.open_stdin,
315             stdin_once: container.stdin_once,
316             env: container.env,
317             cmd: container.cmd,
318             healthcheck: container.healthcheck,
319             args_escaped: container.args_escaped,
320             image: container.image,
321             volumes: container.volumes,
322             working_dir: container.working_dir,
323             entrypoint: container.entrypoint,
324             network_disabled: container.network_disabled,
325             mac_address: container.mac_address,
326             on_build: container.on_build,
327             labels: container.labels,
328             stop_signal: container.stop_signal,
329             stop_timeout: container.stop_timeout,
330             shell: container.shell,
331             host_config: None,
332             networking_config: None,
333         }
334     }
335 }
336 
337 /// Result type for the [Create Container API](../struct.Docker.html#method.create_container)
338 #[derive(Debug, Clone, Serialize, Deserialize)]
339 #[serde(rename_all = "PascalCase")]
340 #[allow(missing_docs)]
341 pub struct CreateContainerResults {
342     pub id: String,
343     pub warnings: Option<Vec<String>>,
344 }
345 
346 /// Parameters used in the [Stop Container API](../struct.Docker.html#method.stop_container)
347 ///
348 /// ## Examples
349 ///
350 /// use bollard::container::StopContainerOptions;
351 ///
352 /// StopContainerOptions{
353 ///     t: 30,
354 /// };
355 #[derive(Debug, Copy, Clone, Default)]
356 pub struct StopContainerOptions {
357     /// Number of seconds to wait before killing the container
358     pub t: i64,
359 }
360 
361 /// Trait providing implementations for [Stop Container Options](struct.StopContainerOptions.html).
362 #[allow(missing_docs)]
363 pub trait StopContainerQueryParams<K>
364 where
365     K: AsRef<str>,
366 {
into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>367     fn into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>;
368 }
369 
370 impl<'a> StopContainerQueryParams<&'a str> for StopContainerOptions {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error>371     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error> {
372         Ok(ArrayVec::from([("t", self.t.to_string())]))
373     }
374 }
375 
376 /// Parameters used in the [Start Container API](../struct.Docker.html#method.start_container)
377 ///
378 /// ## Examples
379 ///
380 /// ```rust
381 /// use bollard::container::StartContainerOptions;
382 ///
383 /// StartContainerOptions{
384 ///     detach_keys: "ctrl-^"
385 /// };
386 /// ```
387 #[derive(Debug, Clone, Default)]
388 pub struct StartContainerOptions<T>
389 where
390     T: AsRef<str>,
391 {
392     /// Override the key sequence for detaching a container. Format is a single character `[a-Z]` or
393     /// `ctrl-<value>` where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.
394     pub detach_keys: T,
395 }
396 
397 /// Trait providing implementations for [Start Container Options](struct.StartContainerOptions.html).
398 #[allow(missing_docs)]
399 pub trait StartContainerQueryParams<K, V>
400 where
401     K: AsRef<str>,
402     V: AsRef<str>,
403 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>404     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
405 }
406 
407 impl<'a, T: AsRef<str>> StartContainerQueryParams<&'a str, T> for StartContainerOptions<T> {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error>408     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error> {
409         Ok(ArrayVec::from([("detachKeys", self.detach_keys)]))
410     }
411 }
412 
413 /// Parameters used in the [Remove Container API](../struct.Docker.html#method.remove_container)
414 ///
415 /// ## Examples
416 ///
417 /// ```rust
418 /// use bollard::container::RemoveContainerOptions;
419 ///
420 /// use std::default::Default;
421 ///
422 /// RemoveContainerOptions{
423 ///     force: true,
424 ///     ..Default::default()
425 /// };
426 /// ```
427 #[derive(Debug, Copy, Clone, Default)]
428 pub struct RemoveContainerOptions {
429     /// Remove the volumes associated with the container.
430     pub v: bool,
431     /// If the container is running, kill it before removing it.
432     pub force: bool,
433     /// Remove the specified link associated with the container.
434     pub link: bool,
435 }
436 
437 /// Trait providing implementations for [Remove Container Options](struct.RemoveContainerOptions.html).
438 #[allow(missing_docs)]
439 pub trait RemoveContainerQueryParams<K, V>
440 where
441     K: AsRef<str>,
442     V: AsRef<str>,
443 {
into_array(self) -> Result<ArrayVec<[(K, V); 3]>, Error>444     fn into_array(self) -> Result<ArrayVec<[(K, V); 3]>, Error>;
445 }
446 
447 impl<'a> RemoveContainerQueryParams<&'a str, &'a str> for RemoveContainerOptions {
into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 3]>, Error>448     fn into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 3]>, Error> {
449         Ok(ArrayVec::from([
450             ("v", if self.v { TRUE_STR } else { FALSE_STR }),
451             ("force", if self.force { TRUE_STR } else { FALSE_STR }),
452             ("link", if self.link { TRUE_STR } else { FALSE_STR }),
453         ]))
454     }
455 }
456 
457 /// Parameters used in the [Wait Container API](../struct.Docker.html#method.wait_container)
458 ///
459 /// ## Examples
460 ///
461 /// ```rust
462 /// use bollard::container::WaitContainerOptions;
463 ///
464 /// WaitContainerOptions{
465 ///     condition: "not-running",
466 /// };
467 /// ```
468 #[derive(Debug, Clone, Default)]
469 pub struct WaitContainerOptions<T>
470 where
471     T: AsRef<str>,
472 {
473     /// Wait until a container state reaches the given condition, either 'not-running' (default),
474     /// 'next-exit', or 'removed'.
475     pub condition: T,
476 }
477 
478 /// Trait providing implementations for [Wait Container Options](struct.WaitContainerOptions.html).
479 #[allow(missing_docs)]
480 pub trait WaitContainerQueryParams<K, V>
481 where
482     K: AsRef<str>,
483     V: AsRef<str>,
484 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>485     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
486 }
487 
488 impl<'a, T: AsRef<str>> WaitContainerQueryParams<&'a str, T> for WaitContainerOptions<T> {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error>489     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error> {
490         Ok(ArrayVec::from([("condition", self.condition)]))
491     }
492 }
493 
494 /// Error messages returned in the [Wait Container API](../struct.Docker.html#method.wait_container)
495 #[derive(Debug, Clone, Serialize, Deserialize)]
496 #[serde(rename_all = "PascalCase")]
497 #[allow(missing_docs)]
498 pub struct WaitContainerResultsError {
499     pub message: String,
500 }
501 
502 /// Result type for the [Wait Container API](../struct.Docker.html#method.wait_container)
503 #[derive(Debug, Clone, Serialize, Deserialize)]
504 #[serde(rename_all = "PascalCase")]
505 #[allow(missing_docs)]
506 pub struct WaitContainerResults {
507     pub status_code: u64,
508     pub error: Option<WaitContainerResultsError>,
509 }
510 
511 /// Parameters used in the [Restart Container API](../struct.Docker.html#method.restart_container)
512 ///
513 /// ## Example
514 ///
515 /// ```rust
516 /// use bollard::container::RestartContainerOptions;
517 ///
518 /// RestartContainerOptions{
519 ///     t: 30,
520 /// };
521 /// ```
522 #[derive(Debug, Copy, Clone, Default)]
523 pub struct RestartContainerOptions {
524     /// Number of seconds to wait before killing the container.
525     pub t: isize,
526 }
527 
528 /// Trait providing implementations for [Restart Container Options](struct.RestartContainerOptions.html).
529 #[allow(missing_docs)]
530 pub trait RestartContainerQueryParams<K>
531 where
532     K: AsRef<str>,
533 {
into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>534     fn into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>;
535 }
536 
537 impl<'a> RestartContainerQueryParams<&'a str> for RestartContainerOptions {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error>538     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error> {
539         Ok(ArrayVec::from([("t", self.t.to_string())]))
540     }
541 }
542 
543 /// Parameters used in the [Inspect Container API](../struct.Docker.html#method.inspect_container)
544 ///
545 /// ## Examples
546 ///
547 /// ```rust
548 /// use bollard::container::InspectContainerOptions;
549 ///
550 /// InspectContainerOptions{
551 ///     size: false,
552 /// };
553 /// ```
554 #[derive(Debug, Copy, Clone, Default)]
555 pub struct InspectContainerOptions {
556     /// Return the size of container as fields `SizeRw` and `SizeRootFs`
557     pub size: bool,
558 }
559 
560 /// Trait providing implementations for [Inspect Container Options](struct.InspectContainerOptions.html).
561 #[allow(missing_docs)]
562 pub trait InspectContainerQueryParams<K, V>
563 where
564     K: AsRef<str>,
565     V: AsRef<str>,
566 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>567     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
568 }
569 
570 impl<'a> InspectContainerQueryParams<&'a str, &'a str> for InspectContainerOptions {
into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 1]>, Error>571     fn into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 1]>, Error> {
572         Ok(ArrayVec::from([(
573             "size",
574             if self.size { TRUE_STR } else { FALSE_STR },
575         )]))
576     }
577 }
578 
579 /// Parameters used in the [Top Processes API](../struct.Docker.html#method.top_processes)
580 ///
581 /// ## Examples
582 ///
583 /// ```rust
584 /// use bollard::container::TopOptions;
585 ///
586 /// TopOptions{
587 ///     ps_args: "aux",
588 /// };
589 /// ```
590 #[derive(Debug, Clone, Default)]
591 pub struct TopOptions<T>
592 where
593     T: AsRef<str>,
594 {
595     /// The arguments to pass to `ps`. For example, `aux`
596     pub ps_args: T,
597 }
598 
599 /// ## Top Query Params
600 ///
601 /// Trait providing implementations for [Top Options](struct.TopOptions.html).
602 #[allow(missing_docs)]
603 pub trait TopQueryParams<K, V>
604 where
605     K: AsRef<str>,
606     V: AsRef<str>,
607 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>608     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
609 }
610 
611 impl<'a, T: AsRef<str>> TopQueryParams<&'a str, T> for TopOptions<T> {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error>612     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error> {
613         Ok(ArrayVec::from([("ps_args", self.ps_args)]))
614     }
615 }
616 
617 /// Result type for the [Top Processes API](../struct.Docker.html#method.top_processes)
618 #[derive(Debug, Clone, Serialize, Deserialize)]
619 #[serde(rename_all = "PascalCase")]
620 #[allow(missing_docs)]
621 pub struct TopResult {
622     pub titles: Vec<String>,
623     pub processes: Option<Vec<Vec<String>>>,
624 }
625 
626 /// Parameters used in the [Logs API](../struct.Docker.html#method.logs)
627 ///
628 /// ## Examples
629 ///
630 /// ```rust
631 /// use bollard::container::LogsOptions;
632 ///
633 /// use std::default::Default;
634 ///
635 /// LogsOptions{
636 ///     stdout: true,
637 ///     ..Default::default()
638 /// };
639 /// ```
640 #[derive(Debug, Clone, Default)]
641 pub struct LogsOptions {
642     /// Return the logs as a finite stream.
643     pub follow: bool,
644     /// Return logs from `stdout`.
645     pub stdout: bool,
646     /// Return logs from `stderr`.
647     pub stderr: bool,
648     /// Only return logs since this time, as a UNIX timestamp.
649     pub since: i64,
650     /// Only return logs before this time, as a UNIX timestamp.
651     pub until: i64,
652     /// Add timestamps to every log line.
653     pub timestamps: bool,
654     /// Only return this number of log lines from the end of the logs. Specify as an integer or all
655     /// to output `all` log lines.
656     pub tail: String,
657 }
658 
659 /// Trait providing implementations for [Logs Options](struct.LogsOptions.html).
660 #[allow(missing_docs)]
661 pub trait LogsQueryParams<K>
662 where
663     K: AsRef<str>,
664 {
into_array(self) -> Result<ArrayVec<[(K, String); 7]>, Error>665     fn into_array(self) -> Result<ArrayVec<[(K, String); 7]>, Error>;
666 }
667 
668 impl<'a> LogsQueryParams<&'a str> for LogsOptions {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 7]>, Error>669     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 7]>, Error> {
670         Ok(ArrayVec::from([
671             ("follow", self.follow.to_string()),
672             ("stdout", self.stdout.to_string()),
673             ("stderr", self.stderr.to_string()),
674             ("since", self.since.to_string()),
675             ("until", self.until.to_string()),
676             ("timestamps", self.timestamps.to_string()),
677             ("tail", self.tail),
678         ]))
679     }
680 }
681 
682 /// Result type for the [Logs API](../struct.Docker.html#method.logs)
683 #[derive(Debug, Clone)]
684 #[allow(missing_docs)]
685 pub enum LogOutput {
686     StdErr { message: Bytes },
687     StdOut { message: Bytes },
688     StdIn { message: Bytes },
689     Console { message: Bytes },
690 }
691 
692 impl fmt::Display for LogOutput {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result693     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
694         let message = match &self {
695             LogOutput::StdErr { message } => message,
696             LogOutput::StdOut { message } => message,
697             LogOutput::StdIn { message } => message,
698             LogOutput::Console { message } => message,
699         };
700         write!(f, "{}", String::from_utf8_lossy(&message))
701     }
702 }
703 
704 /// Parameters used in the [Stats API](../struct.Docker.html#method.stats)
705 ///
706 /// ## Examples
707 ///
708 /// ```rust
709 /// use bollard::container::StatsOptions;
710 ///
711 /// StatsOptions{
712 ///     stream: false,
713 /// };
714 /// ```
715 #[derive(Debug, Copy, Clone, Default)]
716 pub struct StatsOptions {
717     /// Stream the output. If false, the stats will be output once and then it will disconnect.
718     pub stream: bool,
719 }
720 
721 /// Trait providing implementations for [Stats Options](struct.StatsOptions.html).
722 #[allow(missing_docs)]
723 pub trait StatsQueryParams<K, V>
724 where
725     K: AsRef<str>,
726     V: AsRef<str>,
727 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>728     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
729 }
730 
731 impl<'a> StatsQueryParams<&'a str, &'a str> for StatsOptions {
into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 1]>, Error>732     fn into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 1]>, Error> {
733         Ok(ArrayVec::from([(
734             "stream",
735             if self.stream { TRUE_STR } else { FALSE_STR },
736         )]))
737     }
738 }
739 
740 /// Granular memory statistics for the container.
741 #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
742 #[allow(missing_docs)]
743 pub struct MemoryStatsStats {
744     pub cache: u64,
745     pub dirty: u64,
746     pub mapped_file: u64,
747     pub total_inactive_file: u64,
748     pub pgpgout: u64,
749     pub rss: u64,
750     pub total_mapped_file: u64,
751     pub writeback: u64,
752     pub unevictable: u64,
753     pub pgpgin: u64,
754     pub total_unevictable: u64,
755     pub pgmajfault: u64,
756     pub total_rss: u64,
757     pub total_rss_huge: u64,
758     pub total_writeback: u64,
759     pub total_inactive_anon: u64,
760     pub rss_huge: u64,
761     pub hierarchical_memory_limit: u64,
762     pub total_pgfault: u64,
763     pub total_active_file: u64,
764     pub active_anon: u64,
765     pub total_active_anon: u64,
766     pub total_pgpgout: u64,
767     pub total_cache: u64,
768     pub total_dirty: u64,
769     pub inactive_anon: u64,
770     pub active_file: u64,
771     pub pgfault: u64,
772     pub inactive_file: u64,
773     pub total_pgmajfault: u64,
774     pub total_pgpgin: u64,
775     pub hierarchical_memsw_limit: Option<u64>,
776 }
777 
778 /// General memory statistics for the container.
779 #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
780 #[allow(missing_docs)]
781 pub struct MemoryStats {
782     pub stats: Option<MemoryStatsStats>,
783     pub max_usage: Option<u64>,
784     pub usage: Option<u64>,
785     pub failcnt: Option<u64>,
786     pub limit: Option<u64>,
787     pub commit: Option<u64>,
788     pub commit_peak: Option<u64>,
789     pub commitbytes: Option<u64>,
790     pub commitpeakbytes: Option<u64>,
791     pub privateworkingset: Option<u64>,
792 }
793 
794 /// Process ID statistics for the container.
795 #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
796 #[allow(missing_docs)]
797 pub struct PidsStats {
798     pub current: Option<u64>,
799     pub limit: Option<u64>,
800 }
801 
802 /// I/O statistics for the container.
803 #[derive(Debug, Clone, Serialize, Deserialize)]
804 #[allow(missing_docs)]
805 pub struct BlkioStats {
806     pub io_service_bytes_recursive: Option<Vec<BlkioStatsEntry>>,
807     pub io_serviced_recursive: Option<Vec<BlkioStatsEntry>>,
808     pub io_queue_recursive: Option<Vec<BlkioStatsEntry>>,
809     pub io_service_time_recursive: Option<Vec<BlkioStatsEntry>>,
810     pub io_wait_time_recursive: Option<Vec<BlkioStatsEntry>>,
811     pub io_merged_recursive: Option<Vec<BlkioStatsEntry>>,
812     pub io_time_recursive: Option<Vec<BlkioStatsEntry>>,
813     pub sectors_recursive: Option<Vec<BlkioStatsEntry>>,
814 }
815 
816 /// File I/O statistics for the container.
817 #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
818 #[allow(missing_docs)]
819 pub struct StorageStats {
820     pub read_count_normalized: Option<u64>,
821     pub read_size_bytes: Option<u64>,
822     pub write_count_normalized: Option<u64>,
823     pub write_size_bytes: Option<u64>,
824 }
825 
826 /// Statistics for the container.
827 #[derive(Debug, Clone, Serialize, Deserialize)]
828 #[allow(missing_docs)]
829 pub struct Stats {
830     pub read: DateTime<Utc>,
831     pub preread: DateTime<Utc>,
832     pub num_procs: u32,
833     pub pids_stats: PidsStats,
834     pub network: Option<NetworkStats>,
835     pub networks: Option<HashMap<String, NetworkStats>>,
836     pub memory_stats: MemoryStats,
837     pub blkio_stats: BlkioStats,
838     pub cpu_stats: CPUStats,
839     pub precpu_stats: CPUStats,
840     pub storage_stats: StorageStats,
841     pub name: String,
842     pub id: String,
843 }
844 
845 /// Network statistics for the container.
846 #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
847 #[allow(missing_docs)]
848 pub struct NetworkStats {
849     pub rx_dropped: u64,
850     pub rx_bytes: u64,
851     pub rx_errors: u64,
852     pub tx_packets: u64,
853     pub tx_dropped: u64,
854     pub rx_packets: u64,
855     pub tx_errors: u64,
856     pub tx_bytes: u64,
857 }
858 
859 /// CPU usage statistics for the container.
860 #[derive(Debug, Clone, Serialize, Deserialize)]
861 #[allow(missing_docs)]
862 pub struct CPUUsage {
863     pub percpu_usage: Option<Vec<u64>>,
864     pub usage_in_usermode: u64,
865     pub total_usage: u64,
866     pub usage_in_kernelmode: u64,
867 }
868 
869 /// CPU throttling statistics.
870 #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
871 #[allow(missing_docs)]
872 pub struct ThrottlingData {
873     pub periods: u64,
874     pub throttled_periods: u64,
875     pub throttled_time: u64,
876 }
877 
878 /// General CPU statistics for the container.
879 #[derive(Debug, Clone, Serialize, Deserialize)]
880 #[allow(missing_docs)]
881 pub struct CPUStats {
882     pub cpu_usage: CPUUsage,
883     pub system_cpu_usage: Option<u64>,
884     pub online_cpus: Option<u64>,
885     pub throttling_data: ThrottlingData,
886 }
887 
888 #[derive(Debug, Clone, Serialize, Deserialize)]
889 #[allow(missing_docs)]
890 pub struct BlkioStatsEntry {
891     pub major: u64,
892     pub minor: u64,
893     pub op: String,
894     pub value: u64,
895 }
896 
897 /// Parameters used in the [Kill Container API](../struct.Docker.html#method.kill_container)
898 ///
899 /// ## Examples
900 ///
901 /// ```rust
902 /// use bollard::container::KillContainerOptions;
903 ///
904 /// KillContainerOptions{
905 ///     signal: "SIGINT",
906 /// };
907 /// ```
908 #[derive(Debug, Clone, Default)]
909 pub struct KillContainerOptions<T>
910 where
911     T: AsRef<str>,
912 {
913     /// Signal to send to the container as an integer or string (e.g. `SIGINT`)
914     pub signal: T,
915 }
916 
917 /// Trait providing implementations for [Kill Container Options](struct.KillContainerOptions.html).
918 #[allow(missing_docs)]
919 pub trait KillContainerQueryParams<K, V>
920 where
921     K: AsRef<str>,
922     V: AsRef<str>,
923 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>924     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
925 }
926 
927 impl<'a, T: AsRef<str>> KillContainerQueryParams<&'a str, T> for KillContainerOptions<T> {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error>928     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error> {
929         Ok(ArrayVec::from([("signal", self.signal)]))
930     }
931 }
932 
933 /// Configuration for the [Update Container API](../struct.Docker.html#method.update_container)
934 ///
935 /// ## Examples
936 ///
937 /// ```rust
938 /// use bollard::container::UpdateContainerOptions;
939 /// use std::default::Default;
940 ///
941 /// UpdateContainerOptions::<String> {
942 ///     memory: Some(314572800),
943 ///     memory_swap: Some(314572800),
944 ///     ..Default::default()
945 /// };
946 /// ```
947 #[derive(Debug, Clone, Default, Serialize)]
948 #[serde(rename_all = "PascalCase")]
949 pub struct UpdateContainerOptions<T>
950 where
951     T: Into<String> + Eq + Hash,
952 {
953     /// An integer value representing this container's relative CPU weight versus other containers.
954     #[serde(rename = "CpuShares")]
955     #[serde(skip_serializing_if = "Option::is_none")]
956     pub cpu_shares: Option<isize>,
957 
958     /// Memory limit in bytes.
959     #[serde(rename = "Memory")]
960     #[serde(skip_serializing_if = "Option::is_none")]
961     pub memory: Option<i64>,
962 
963     /// Path to `cgroups` under which the container's `cgroup` is created. If the path is not absolute, the path is considered to be relative to the `cgroups` path of the init process. Cgroups are created if they do not already exist.
964     #[serde(rename = "CgroupParent")]
965     #[serde(skip_serializing_if = "Option::is_none")]
966     pub cgroup_parent: Option<T>,
967 
968     /// Block IO weight (relative weight).
969     #[serde(rename = "BlkioWeight")]
970     #[serde(skip_serializing_if = "Option::is_none")]
971     pub blkio_weight: Option<u16>,
972 
973     /// Block IO weight (relative device weight) in the form `[{\"Path\": \"device_path\", \"Weight\": weight}]`.
974     #[serde(rename = "BlkioWeightDevice")]
975     #[serde(skip_serializing_if = "Option::is_none")]
976     pub blkio_weight_device: Option<Vec<ResourcesBlkioWeightDevice>>,
977 
978     /// Limit read rate (bytes per second) from a device, in the form `[{\"Path\": \"device_path\", \"Rate\": rate}]`.
979     #[serde(rename = "BlkioDeviceReadBps")]
980     #[serde(skip_serializing_if = "Option::is_none")]
981     pub blkio_device_read_bps: Option<Vec<ThrottleDevice>>,
982 
983     /// Limit write rate (bytes per second) to a device, in the form `[{\"Path\": \"device_path\", \"Rate\": rate}]`.
984     #[serde(rename = "BlkioDeviceWriteBps")]
985     #[serde(skip_serializing_if = "Option::is_none")]
986     pub blkio_device_write_bps: Option<Vec<ThrottleDevice>>,
987 
988     /// Limit read rate (IO per second) from a device, in the form `[{\"Path\": \"device_path\", \"Rate\": rate}]`.
989     #[serde(rename = "BlkioDeviceReadIOps")]
990     #[serde(skip_serializing_if = "Option::is_none")]
991     pub blkio_device_read_i_ops: Option<Vec<ThrottleDevice>>,
992 
993     /// Limit write rate (IO per second) to a device, in the form `[{\"Path\": \"device_path\", \"Rate\": rate}]`.
994     #[serde(rename = "BlkioDeviceWriteIOps")]
995     #[serde(skip_serializing_if = "Option::is_none")]
996     pub blkio_device_write_i_ops: Option<Vec<ThrottleDevice>>,
997 
998     /// The length of a CPU period in microseconds.
999     #[serde(rename = "CpuPeriod")]
1000     #[serde(skip_serializing_if = "Option::is_none")]
1001     pub cpu_period: Option<i64>,
1002 
1003     /// Microseconds of CPU time that the container can get in a CPU period.
1004     #[serde(rename = "CpuQuota")]
1005     #[serde(skip_serializing_if = "Option::is_none")]
1006     pub cpu_quota: Option<i64>,
1007 
1008     /// The length of a CPU real-time period in microseconds. Set to 0 to allocate no time allocated to real-time tasks.
1009     #[serde(rename = "CpuRealtimePeriod")]
1010     #[serde(skip_serializing_if = "Option::is_none")]
1011     pub cpu_realtime_period: Option<i64>,
1012 
1013     /// The length of a CPU real-time runtime in microseconds. Set to 0 to allocate no time allocated to real-time tasks.
1014     #[serde(rename = "CpuRealtimeRuntime")]
1015     #[serde(skip_serializing_if = "Option::is_none")]
1016     pub cpu_realtime_runtime: Option<i64>,
1017 
1018     /// CPUs in which to allow execution (e.g., `0-3`, `0,1`)
1019     #[serde(rename = "CpusetCpus")]
1020     #[serde(skip_serializing_if = "Option::is_none")]
1021     pub cpuset_cpus: Option<T>,
1022 
1023     /// Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
1024     #[serde(rename = "CpusetMems")]
1025     #[serde(skip_serializing_if = "Option::is_none")]
1026     pub cpuset_mems: Option<T>,
1027 
1028     /// A list of devices to add to the container.
1029     #[serde(rename = "Devices")]
1030     #[serde(skip_serializing_if = "Option::is_none")]
1031     pub devices: Option<Vec<DeviceMapping>>,
1032 
1033     /// a list of cgroup rules to apply to the container
1034     #[serde(rename = "DeviceCgroupRules")]
1035     #[serde(skip_serializing_if = "Option::is_none")]
1036     pub device_cgroup_rules: Option<Vec<T>>,
1037 
1038     /// a list of requests for devices to be sent to device drivers
1039     #[serde(rename = "DeviceRequests")]
1040     #[serde(skip_serializing_if = "Option::is_none")]
1041     pub device_requests: Option<Vec<DeviceRequest>>,
1042 
1043     /// Kernel memory limit in bytes.
1044     #[serde(rename = "KernelMemory")]
1045     #[serde(skip_serializing_if = "Option::is_none")]
1046     pub kernel_memory: Option<i64>,
1047 
1048     /// Hard limit for kernel TCP buffer memory (in bytes).
1049     #[serde(rename = "KernelMemoryTCP")]
1050     #[serde(skip_serializing_if = "Option::is_none")]
1051     pub kernel_memory_tcp: Option<i64>,
1052 
1053     /// Memory soft limit in bytes.
1054     #[serde(rename = "MemoryReservation")]
1055     #[serde(skip_serializing_if = "Option::is_none")]
1056     pub memory_reservation: Option<i64>,
1057 
1058     /// Total memory limit (memory + swap). Set as `-1` to enable unlimited swap.
1059     #[serde(rename = "MemorySwap")]
1060     #[serde(skip_serializing_if = "Option::is_none")]
1061     pub memory_swap: Option<i64>,
1062 
1063     /// Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
1064     #[serde(rename = "MemorySwappiness")]
1065     #[serde(skip_serializing_if = "Option::is_none")]
1066     pub memory_swappiness: Option<i64>,
1067 
1068     /// CPU quota in units of 10<sup>-9</sup> CPUs.
1069     #[serde(rename = "NanoCPUs")]
1070     #[serde(skip_serializing_if = "Option::is_none")]
1071     pub nano_cp_us: Option<i64>,
1072 
1073     /// Disable OOM Killer for the container.
1074     #[serde(rename = "OomKillDisable")]
1075     #[serde(skip_serializing_if = "Option::is_none")]
1076     pub oom_kill_disable: Option<bool>,
1077 
1078     /// Run an init inside the container that forwards signals and reaps processes. This field is omitted if empty, and the default (as configured on the daemon) is used.
1079     #[serde(rename = "Init")]
1080     #[serde(skip_serializing_if = "Option::is_none")]
1081     pub init: Option<bool>,
1082 
1083     /// Tune a container's PIDs limit. Set `0` or `-1` for unlimited, or `null` to not change.
1084     #[serde(rename = "PidsLimit")]
1085     #[serde(skip_serializing_if = "Option::is_none")]
1086     pub pids_limit: Option<i64>,
1087 
1088     /// A list of resource limits to set in the container. For example: `{\"Name\": \"nofile\", \"Soft\": 1024, \"Hard\": 2048}`\"
1089     #[serde(rename = "Ulimits")]
1090     #[serde(skip_serializing_if = "Option::is_none")]
1091     pub ulimits: Option<Vec<ResourcesUlimits>>,
1092 
1093     /// The number of usable CPUs (Windows only).  On Windows Server containers, the processor resource controls are mutually exclusive. The order of precedence is `CPUCount` first, then `CPUShares`, and `CPUPercent` last.
1094     #[serde(rename = "CpuCount")]
1095     #[serde(skip_serializing_if = "Option::is_none")]
1096     pub cpu_count: Option<i64>,
1097 
1098     /// The usable percentage of the available CPUs (Windows only).  On Windows Server containers, the processor resource controls are mutually exclusive. The order of precedence is `CPUCount` first, then `CPUShares`, and `CPUPercent` last.
1099     #[serde(rename = "CpuPercent")]
1100     #[serde(skip_serializing_if = "Option::is_none")]
1101     pub cpu_percent: Option<i64>,
1102 
1103     /// Maximum IOps for the container system drive (Windows only)
1104     #[serde(rename = "IOMaximumIOps")]
1105     #[serde(skip_serializing_if = "Option::is_none")]
1106     pub io_maximum_i_ops: Option<i64>,
1107 
1108     /// Maximum IO in bytes per second for the container system drive (Windows only)
1109     #[serde(rename = "IOMaximumBandwidth")]
1110     #[serde(skip_serializing_if = "Option::is_none")]
1111     pub io_maximum_bandwidth: Option<i64>,
1112 
1113     /// The behavior to apply when the container exits. The default is not to restart.
1114     ///
1115     /// An ever increasing delay (double the previous delay, starting at 100ms) is added before
1116     /// each restart to prevent flooding the server.
1117     pub restart_policy: Option<RestartPolicy>,
1118 }
1119 
1120 /// Parameters used in the [Rename Container API](../struct.Docker.html#method.rename_container)
1121 ///
1122 /// ## Examples
1123 ///
1124 /// ```rust
1125 /// use bollard::container::RenameContainerOptions;
1126 ///
1127 /// RenameContainerOptions {
1128 ///     name: "my_new_container_name"
1129 /// };
1130 /// ```
1131 #[derive(Debug, Clone, Default)]
1132 pub struct RenameContainerOptions<T>
1133 where
1134     T: AsRef<str>,
1135 {
1136     /// New name for the container.
1137     pub name: T,
1138 }
1139 
1140 /// Trait providing implementations for [Rename Container Options](struct.RenameContainerOptions.html).
1141 #[allow(missing_docs)]
1142 pub trait RenameContainerQueryParams<K, V>
1143 where
1144     K: AsRef<str>,
1145     V: AsRef<str>,
1146 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>1147     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
1148 }
1149 
1150 impl<'a, T: AsRef<str>> RenameContainerQueryParams<&'a str, T> for RenameContainerOptions<T> {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error>1151     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error> {
1152         Ok(ArrayVec::from([("name", self.name)]))
1153     }
1154 }
1155 
1156 /// Parameters used in the [Prune Containers API](../struct.Docker.html#method.prune_containers)
1157 ///
1158 /// ## Examples
1159 ///
1160 /// ```rust
1161 /// use bollard::container::PruneContainersOptions;
1162 ///
1163 /// use std::collections::HashMap;
1164 ///
1165 /// let mut filters = HashMap::new();
1166 /// filters.insert("until", vec!("10m"));
1167 ///
1168 /// PruneContainersOptions{
1169 ///     filters: filters
1170 /// };
1171 /// ```
1172 #[derive(Debug, Clone, Default)]
1173 pub struct PruneContainersOptions<T>
1174 where
1175     T: AsRef<str> + Eq + Hash,
1176 {
1177     /// Filters to process on the prune list, encoded as JSON.
1178     ///
1179     /// Available filters:
1180     ///  - `until=<timestamp>` Prune containers created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine's time.
1181     ///  - label (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune containers with (or without, in case `label!=...` is used) the specified labels.
1182     pub filters: HashMap<T, Vec<T>>,
1183 }
1184 
1185 /// Trait providing implementations for [Prune Containers Options](struct.PruneContainersOptions.html).
1186 #[allow(missing_docs)]
1187 pub trait PruneContainersQueryParams<K>
1188 where
1189     K: AsRef<str>,
1190 {
into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>1191     fn into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>;
1192 }
1193 
1194 impl<'a, T: AsRef<str> + Eq + Hash + Serialize> PruneContainersQueryParams<&'a str>
1195     for PruneContainersOptions<T>
1196 {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error>1197     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error> {
1198         Ok(ArrayVec::from([(
1199             "filters",
1200             serde_json::to_string(&self.filters)
1201                 .map_err::<Error, _>(|e| JsonSerializeError { err: e }.into())?,
1202         )]))
1203     }
1204 }
1205 
1206 /// Result type for the [Prune Containers API](../struct.Docker.html#method.prune_containers)
1207 #[derive(Debug, Clone, Serialize, Deserialize)]
1208 #[serde(rename_all = "PascalCase")]
1209 #[allow(missing_docs)]
1210 pub struct PruneContainersResults {
1211     pub containers_deleted: Option<Vec<String>>,
1212     pub space_reclaimed: u64,
1213 }
1214 
1215 /// Parameters used in the [Upload To Container
1216 /// API](../struct.Docker.html#method.upload_to_container)
1217 ///
1218 /// ## Examples
1219 ///
1220 /// ```rust
1221 /// use bollard::container::UploadToContainerOptions;
1222 ///
1223 /// use std::default::Default;
1224 ///
1225 /// UploadToContainerOptions{
1226 ///     path: "/opt",
1227 ///     ..Default::default()
1228 /// };
1229 /// ```
1230 #[derive(Debug, Clone, Default)]
1231 pub struct UploadToContainerOptions<T>
1232 where
1233     T: AsRef<str>,
1234 {
1235     /// Path to a directory in the container to extract the archive’s contents into.
1236     pub path: T,
1237     /// If “1”, “true”, or “True” then it will be an error if unpacking the given content would
1238     /// cause an existing directory to be replaced with a non-directory and vice versa.
1239     pub no_overwrite_dir_non_dir: T,
1240 }
1241 
1242 /// Trait providing implementations for [Upload To Container Options](struct.UploadToContainerOptions.html).
1243 #[allow(missing_docs)]
1244 pub trait UploadToContainerQueryParams<K, V>
1245 where
1246     K: AsRef<str>,
1247     V: AsRef<str>,
1248 {
into_array(self) -> Result<ArrayVec<[(K, V); 2]>, Error>1249     fn into_array(self) -> Result<ArrayVec<[(K, V); 2]>, Error>;
1250 }
1251 
1252 impl<'a, T: AsRef<str>> UploadToContainerQueryParams<&'a str, T> for UploadToContainerOptions<T> {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 2]>, Error>1253     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 2]>, Error> {
1254         Ok(ArrayVec::from([
1255             ("path", self.path),
1256             ("noOverwriteDirNonDir", self.no_overwrite_dir_non_dir),
1257         ]))
1258     }
1259 }
1260 
1261 /// Parameters used in the [Download From Container
1262 /// API](../struct.Docker.html#method.download_from_container)
1263 ///
1264 /// ## Examples
1265 ///
1266 /// ```rust
1267 /// use bollard::container::DownloadFromContainerOptions;
1268 ///
1269 /// DownloadFromContainerOptions{
1270 ///     path: "/opt",
1271 /// };
1272 /// ```
1273 #[derive(Debug, Clone, Default)]
1274 pub struct DownloadFromContainerOptions<T>
1275 where
1276     T: AsRef<str>,
1277 {
1278     /// Resource in the container’s filesystem to archive.
1279     pub path: T,
1280 }
1281 
1282 /// Trait providing implementations for [Download From Container Options](struct.DownloadFromContainerOptions.html).
1283 #[allow(missing_docs)]
1284 pub trait DownloadFromContainerQueryParams<K, V>
1285 where
1286     K: AsRef<str>,
1287     V: AsRef<str>,
1288 {
into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>1289     fn into_array(self) -> Result<ArrayVec<[(K, V); 1]>, Error>;
1290 }
1291 
1292 impl<'a, T: AsRef<str>> DownloadFromContainerQueryParams<&'a str, T>
1293     for DownloadFromContainerOptions<T>
1294 {
into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error>1295     fn into_array(self) -> Result<ArrayVec<[(&'a str, T); 1]>, Error> {
1296         Ok(ArrayVec::from([("path", self.path)]))
1297     }
1298 }
1299 
1300 impl Docker {
1301     /// ---
1302     ///
1303     /// # List Containers
1304     ///
1305     /// Returns a list of containers.
1306     ///
1307     /// # Arguments
1308     ///
1309     ///  - Optional [ListContainersOptions](container/struct.ListContainersOptions.html) struct.
1310     ///
1311     /// # Returns
1312     ///
1313     ///  - Vector of [ContainerSummaryInner](models/struct.ContainerSummaryInner.html), wrapped in a Future.
1314     ///
1315     /// # Examples
1316     ///
1317     /// ```rust
1318     /// # use bollard::Docker;
1319     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1320     /// use bollard::container::{ListContainersOptions};
1321     ///
1322     /// use std::collections::HashMap;
1323     /// use std::default::Default;
1324     ///
1325     /// let mut filters = HashMap::new();
1326     /// filters.insert("health", vec!("unhealthy"));
1327     ///
1328     /// let options = Some(ListContainersOptions{
1329     ///     all: true,
1330     ///     filters: filters,
1331     ///     ..Default::default()
1332     /// });
1333     ///
1334     /// docker.list_containers(options);
1335     /// ```
list_containers<'de, T, K>( &self, options: Option<T>, ) -> Result<Vec<ContainerSummaryInner>, Error> where T: ListContainersQueryParams<K, String>, K: AsRef<str>,1336     pub async fn list_containers<'de, T, K>(
1337         &self,
1338         options: Option<T>,
1339     ) -> Result<Vec<ContainerSummaryInner>, Error>
1340     where
1341         T: ListContainersQueryParams<K, String>,
1342         K: AsRef<str>,
1343     {
1344         let url = "/containers/json";
1345 
1346         let req = self.build_request(
1347             url,
1348             Builder::new().method(Method::GET),
1349             Docker::transpose_option(options.map(|o| o.into_array())),
1350             Ok(Body::empty()),
1351         );
1352 
1353         self.process_into_value(req).await
1354     }
1355 
1356     /// ---
1357     ///
1358     /// # Create Container
1359     ///
1360     /// Prepares a container for a subsequent start operation.
1361     ///
1362     /// # Arguments
1363     ///
1364     ///  - Optional [Create Container Options](container/struct.CreateContainerOptions.html) struct.
1365     ///  - Container [Config](container/struct.Config.html) struct.
1366     ///
1367     /// # Returns
1368     ///
1369     ///  - [ContainerCreateResponse](models/struct.ContainerCreateResponse.html), wrapped in a Future.
1370     ///
1371     /// # Examples
1372     ///
1373     /// ```rust
1374     /// # use bollard::Docker;
1375     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1376     /// use bollard::container::{CreateContainerOptions, Config};
1377     ///
1378     /// use std::default::Default;
1379     ///
1380     /// let options = Some(CreateContainerOptions{
1381     ///     name: "my-new-container",
1382     /// });
1383     ///
1384     /// let config = Config {
1385     ///     image: Some("hello-world"),
1386     ///     cmd: Some(vec!["/hello"]),
1387     ///     ..Default::default()
1388     /// };
1389     ///
1390     /// docker.create_container(options, config);
1391     /// ```
create_container<T, K, V, Z>( &self, options: Option<T>, config: Config<Z>, ) -> Result<ContainerCreateResponse, Error> where T: CreateContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>, Z: Into<String> + Hash + Eq + Serialize,1392     pub async fn create_container<T, K, V, Z>(
1393         &self,
1394         options: Option<T>,
1395         config: Config<Z>,
1396     ) -> Result<ContainerCreateResponse, Error>
1397     where
1398         T: CreateContainerQueryParams<K, V>,
1399         K: AsRef<str>,
1400         V: AsRef<str>,
1401         Z: Into<String> + Hash + Eq + Serialize,
1402     {
1403         let url = "/containers/create";
1404         let req = self.build_request(
1405             url,
1406             Builder::new().method(Method::POST),
1407             Docker::transpose_option(options.map(|o| o.into_array())),
1408             Docker::serialize_payload(Some(config)),
1409         );
1410 
1411         self.process_into_value(req).await
1412     }
1413 
1414     /// ---
1415     ///
1416     /// # Start Container
1417     ///
1418     /// Starts a container, after preparing it with the [Create Container
1419     /// API](struct.Docker.html#method.create_container).
1420     ///
1421     /// # Arguments
1422     ///
1423     ///  - Container name as a string slice.
1424     ///  - Optional [Start Container Options](container/struct.StartContainerOptions.html) struct.
1425     ///
1426     /// # Returns
1427     ///
1428     ///  - unit type `()`, wrapped in a Future.
1429     ///
1430     /// # Examples
1431     ///
1432     /// ```rust
1433     /// # use bollard::Docker;
1434     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1435     /// use bollard::container::StartContainerOptions;
1436     ///
1437     /// docker.start_container("hello-world", None::<StartContainerOptions<String>>);
1438     /// ```
start_container<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> Result<(), Error> where T: StartContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,1439     pub async fn start_container<T, K, V>(
1440         &self,
1441         container_name: &str,
1442         options: Option<T>,
1443     ) -> Result<(), Error>
1444     where
1445         T: StartContainerQueryParams<K, V>,
1446         K: AsRef<str>,
1447         V: AsRef<str>,
1448     {
1449         let url = format!("/containers/{}/start", container_name);
1450 
1451         let req = self.build_request(
1452             &url,
1453             Builder::new().method(Method::POST),
1454             Docker::transpose_option(options.map(|o| o.into_array())),
1455             Ok(Body::empty()),
1456         );
1457 
1458         self.process_into_unit(req).await
1459     }
1460 
1461     /// ---
1462     ///
1463     /// # Stop Container
1464     ///
1465     /// Stops a container.
1466     ///
1467     /// # Arguments
1468     ///
1469     /// - Container name as string slice.
1470     /// - Optional [Stop Container Options](container/struct.StopContainerOptions.html) struct.
1471     ///
1472     /// # Returns
1473     ///
1474     ///  - unit type `()`, wrapped in a Future.
1475     ///
1476     /// # Examples
1477     ///
1478     /// ```rust
1479     /// # use bollard::Docker;
1480     /// use bollard::container::StopContainerOptions;
1481     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1482     ///
1483     /// let options = Some(StopContainerOptions{
1484     ///     t: 30,
1485     /// });
1486     ///
1487     /// docker.stop_container("hello-world", options);
1488     /// ```
stop_container<T, K>( &self, container_name: &str, options: Option<T>, ) -> Result<(), Error> where T: StopContainerQueryParams<K>, K: AsRef<str>,1489     pub async fn stop_container<T, K>(
1490         &self,
1491         container_name: &str,
1492         options: Option<T>,
1493     ) -> Result<(), Error>
1494     where
1495         T: StopContainerQueryParams<K>,
1496         K: AsRef<str>,
1497     {
1498         let url = format!("/containers/{}/stop", container_name);
1499 
1500         let req = self.build_request(
1501             &url,
1502             Builder::new().method(Method::POST),
1503             Docker::transpose_option(options.map(|o| o.into_array())),
1504             Ok(Body::empty()),
1505         );
1506 
1507         self.process_into_unit(req).await
1508     }
1509 
1510     /// ---
1511     ///
1512     /// # Remove Container
1513     ///
1514     /// Remove a container.
1515     ///
1516     /// # Arguments
1517     ///
1518     /// - Container name as a string slice.
1519     /// - Optional [Remove Container Options](container/struct.RemoveContainerOptions.html) struct.
1520     ///
1521     /// # Returns
1522     ///
1523     ///  - unit type `()`, wrapped in a Future.
1524     ///
1525     /// # Examples
1526     ///
1527     /// ```rust
1528     /// # use bollard::Docker;
1529     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1530     ///
1531     /// use bollard::container::RemoveContainerOptions;
1532     ///
1533     /// use std::default::Default;
1534     ///
1535     /// let options = Some(RemoveContainerOptions{
1536     ///     force: true,
1537     ///     ..Default::default()
1538     /// });
1539     ///
1540     /// docker.remove_container("hello-world", options);
1541     /// ```
remove_container<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> Result<(), Error> where T: RemoveContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,1542     pub async fn remove_container<T, K, V>(
1543         &self,
1544         container_name: &str,
1545         options: Option<T>,
1546     ) -> Result<(), Error>
1547     where
1548         T: RemoveContainerQueryParams<K, V>,
1549         K: AsRef<str>,
1550         V: AsRef<str>,
1551     {
1552         let url = format!("/containers/{}", container_name);
1553 
1554         let req = self.build_request(
1555             &url,
1556             Builder::new().method(Method::DELETE),
1557             Docker::transpose_option(options.map(|o| o.into_array())),
1558             Ok(Body::empty()),
1559         );
1560 
1561         self.process_into_unit(req).await
1562     }
1563 
1564     /// ---
1565     ///
1566     /// # Wait Container
1567     ///
1568     /// Wait for a container to stop. This is a non-blocking operation, the resulting stream will
1569     /// end when the container stops.
1570     ///
1571     /// # Arguments
1572     ///
1573     /// - Container name as string slice.
1574     /// - Optional [Wait Container Options](container/struct.WaitContainerOptions.html) struct.
1575     ///
1576     /// # Returns
1577     ///
1578     ///  - [ContainerWaitResponse](models/struct.ContainerWaitResponse.html), wrapped in a
1579     ///  Stream.
1580     ///
1581     /// # Examples
1582     ///
1583     /// ```rust
1584     /// # use bollard::Docker;
1585     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1586     ///
1587     /// use bollard::container::WaitContainerOptions;
1588     ///
1589     /// let options = Some(WaitContainerOptions{
1590     ///     condition: "not-running",
1591     /// });
1592     ///
1593     /// docker.wait_container("hello-world", options);
1594     /// ```
wait_container<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> impl Stream<Item = Result<ContainerWaitResponse, Error>> where T: WaitContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,1595     pub fn wait_container<T, K, V>(
1596         &self,
1597         container_name: &str,
1598         options: Option<T>,
1599     ) -> impl Stream<Item = Result<ContainerWaitResponse, Error>>
1600     where
1601         T: WaitContainerQueryParams<K, V>,
1602         K: AsRef<str>,
1603         V: AsRef<str>,
1604     {
1605         let url = format!("/containers/{}/wait", container_name);
1606 
1607         let req = self.build_request(
1608             &url,
1609             Builder::new().method(Method::POST),
1610             Docker::transpose_option(options.map(|o| o.into_array())),
1611             Ok(Body::empty()),
1612         );
1613 
1614         self.process_into_stream(req)
1615     }
1616 
1617     /// ---
1618     ///
1619     /// # Restart Container
1620     ///
1621     /// Restart a container.
1622     ///
1623     /// # Arguments
1624     ///
1625     ///  - Container name as string slice.
1626     ///  - Optional [Restart Container Options](container/struct.RestartContainerOptions.html) struct.
1627     ///
1628     /// # Returns
1629     ///
1630     ///  - unit type `()`, wrapped in a Future.
1631     ///
1632     /// # Examples
1633     ///
1634     /// ```rust
1635     /// # use bollard::Docker;
1636     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1637     ///
1638     /// use bollard::container::RestartContainerOptions;
1639     ///
1640     /// let options = Some(RestartContainerOptions{
1641     ///     t: 30,
1642     /// });
1643     ///
1644     /// docker.restart_container("postgres", options);
1645     /// ```
restart_container<T, K>( &self, container_name: &str, options: Option<T>, ) -> Result<(), Error> where T: RestartContainerQueryParams<K>, K: AsRef<str>,1646     pub async fn restart_container<T, K>(
1647         &self,
1648         container_name: &str,
1649         options: Option<T>,
1650     ) -> Result<(), Error>
1651     where
1652         T: RestartContainerQueryParams<K>,
1653         K: AsRef<str>,
1654     {
1655         let url = format!("/containers/{}/restart", container_name);
1656 
1657         let req = self.build_request(
1658             &url,
1659             Builder::new().method(Method::POST),
1660             Docker::transpose_option(options.map(|o| o.into_array())),
1661             Ok(Body::empty()),
1662         );
1663 
1664         self.process_into_unit(req).await
1665     }
1666 
1667     /// ---
1668     ///
1669     /// # Inspect Container
1670     ///
1671     /// Inspect a container.
1672     ///
1673     /// # Arguments
1674     ///
1675     ///  - Container name as a string slice.
1676     ///  - Optional [Inspect Container Options](container/struct.InspectContainerOptions.html) struct.
1677     ///
1678     /// # Returns
1679     ///
1680     ///  - [ContainerInspectResponse](models/struct.ContainerInspectResponse.html), wrapped in a Future.
1681     ///
1682     /// # Examples
1683     ///
1684     /// ```rust
1685     /// # use bollard::Docker;
1686     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1687     /// use bollard::container::InspectContainerOptions;
1688     ///
1689     /// let options = Some(InspectContainerOptions{
1690     ///     size: false,
1691     /// });
1692     ///
1693     /// docker.inspect_container("hello-world", options);
1694     /// ```
inspect_container<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> Result<ContainerInspectResponse, Error> where T: InspectContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,1695     pub async fn inspect_container<T, K, V>(
1696         &self,
1697         container_name: &str,
1698         options: Option<T>,
1699     ) -> Result<ContainerInspectResponse, Error>
1700     where
1701         T: InspectContainerQueryParams<K, V>,
1702         K: AsRef<str>,
1703         V: AsRef<str>,
1704     {
1705         let url = format!("/containers/{}/json", container_name);
1706 
1707         let req = self.build_request(
1708             &url,
1709             Builder::new().method(Method::GET),
1710             Docker::transpose_option(options.map(|o| o.into_array())),
1711             Ok(Body::empty()),
1712         );
1713 
1714         self.process_into_value(req).await
1715     }
1716 
1717     /// ---
1718     ///
1719     /// # Top Processes
1720     ///
1721     /// List processes running inside a container.
1722     ///
1723     /// # Arguments
1724     ///
1725     ///  - Container name as string slice.
1726     ///  - Optional [Top Options](container/struct.TopOptions.html) struct.
1727     ///
1728     /// # Returns
1729     ///
1730     ///  - [ContainerTopResponse](models/struct.ContainerTopResponse.html), wrapped in a Future.
1731     ///
1732     /// # Examples
1733     ///
1734     /// ```rust
1735     /// # use bollard::Docker;
1736     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1737     /// use bollard::container::TopOptions;
1738     ///
1739     /// let options = Some(TopOptions{
1740     ///     ps_args: "aux",
1741     /// });
1742     ///
1743     /// docker.top_processes("fussybeaver/uhttpd", options);
1744     /// ```
top_processes<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> Result<ContainerTopResponse, Error> where T: TopQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,1745     pub async fn top_processes<T, K, V>(
1746         &self,
1747         container_name: &str,
1748         options: Option<T>,
1749     ) -> Result<ContainerTopResponse, Error>
1750     where
1751         T: TopQueryParams<K, V>,
1752         K: AsRef<str>,
1753         V: AsRef<str>,
1754     {
1755         let url = format!("/containers/{}/top", container_name);
1756 
1757         let req = self.build_request(
1758             &url,
1759             Builder::new().method(Method::GET),
1760             Docker::transpose_option(options.map(|o| o.into_array())),
1761             Ok(Body::empty()),
1762         );
1763 
1764         self.process_into_value(req).await
1765     }
1766 
1767     /// ---
1768     ///
1769     /// # Logs
1770     ///
1771     /// Get container logs.
1772     ///
1773     /// # Arguments
1774     ///
1775     ///  - Container name as string slice.
1776     ///  - Optional [Logs Options](container/struct.LogsOptions.html) struct.
1777     ///
1778     /// # Returns
1779     ///
1780     ///  - [Log Output](container/enum.LogOutput.html) enum, wrapped in a
1781     ///  Stream.
1782     ///
1783     /// # Examples
1784     ///
1785     /// ```rust
1786     /// # use bollard::Docker;
1787     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1788     ///
1789     /// use bollard::container::LogsOptions;
1790     ///
1791     /// use std::default::Default;
1792     ///
1793     /// let options = Some(LogsOptions{
1794     ///     stdout: true,
1795     ///     ..Default::default()
1796     /// });
1797     ///
1798     /// docker.logs("hello-world", options);
1799     /// ```
logs<T, K>( &self, container_name: &str, options: Option<T>, ) -> impl Stream<Item = Result<LogOutput, Error>> where T: LogsQueryParams<K>, K: AsRef<str>,1800     pub fn logs<T, K>(
1801         &self,
1802         container_name: &str,
1803         options: Option<T>,
1804     ) -> impl Stream<Item = Result<LogOutput, Error>>
1805     where
1806         T: LogsQueryParams<K>,
1807         K: AsRef<str>,
1808     {
1809         let url = format!("/containers/{}/logs", container_name);
1810 
1811         let req = self.build_request(
1812             &url,
1813             Builder::new().method(Method::GET),
1814             Docker::transpose_option(options.map(|o| o.into_array())),
1815             Ok(Body::empty()),
1816         );
1817 
1818         self.process_into_stream_string(req)
1819     }
1820 
1821     /// ---
1822     ///
1823     /// # Container Changes
1824     ///
1825     /// Get changes on a container's filesystem.
1826     ///
1827     /// # Arguments
1828     ///
1829     ///  - Container name as string slice.
1830     ///
1831     /// # Returns
1832     ///
1833     ///  - An Option of Vector of [Container Change Response Item](models/struct.ContainerChangeResponseItem.html) structs, wrapped in a
1834     ///  Future.
1835     ///
1836     /// # Examples
1837     ///
1838     /// ```rust
1839     /// # use bollard::Docker;
1840     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1841     ///
1842     /// docker.container_changes("hello-world");
1843     /// ```
container_changes( &self, container_name: &str, ) -> Result<Option<Vec<ContainerChangeResponseItem>>, Error>1844     pub async fn container_changes(
1845         &self,
1846         container_name: &str,
1847     ) -> Result<Option<Vec<ContainerChangeResponseItem>>, Error> {
1848         let url = format!("/containers/{}/changes", container_name);
1849 
1850         let req = self.build_request::<_, String, String>(
1851             &url,
1852             Builder::new().method(Method::GET),
1853             Ok(None::<ArrayVec<[(_, _); 0]>>),
1854             Ok(Body::empty()),
1855         );
1856 
1857         self.process_into_value(req).await
1858     }
1859 
1860     /// ---
1861     ///
1862     /// # Stats
1863     ///
1864     /// Get container stats based on resource usage.
1865     ///
1866     /// # Arguments
1867     ///
1868     /// - Container name as string slice.
1869     /// - Optional [Stats Options](container/struct.StatsOptions.html) struct.
1870     ///
1871     /// # Returns
1872     ///
1873     ///  - [Stats](container/struct.Stats.html) struct, wrapped in a
1874     ///  Stream.
1875     ///
1876     /// # Examples
1877     ///
1878     /// ```rust
1879     /// # use bollard::Docker;
1880     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1881     ///
1882     /// use bollard::container::StatsOptions;
1883     ///
1884     /// let options = Some(StatsOptions{
1885     ///     stream: false,
1886     /// });
1887     ///
1888     /// docker.stats("hello-world", options);
1889     /// ```
stats<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> impl Stream<Item = Result<Stats, Error>> where T: StatsQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,1890     pub fn stats<T, K, V>(
1891         &self,
1892         container_name: &str,
1893         options: Option<T>,
1894     ) -> impl Stream<Item = Result<Stats, Error>>
1895     where
1896         T: StatsQueryParams<K, V>,
1897         K: AsRef<str>,
1898         V: AsRef<str>,
1899     {
1900         let url = format!("/containers/{}/stats", container_name);
1901 
1902         let req = self.build_request(
1903             &url,
1904             Builder::new().method(Method::GET),
1905             Docker::transpose_option(options.map(|o| o.into_array())),
1906             Ok(Body::empty()),
1907         );
1908 
1909         self.process_into_stream(req)
1910     }
1911 
1912     /// ---
1913     ///
1914     /// # Kill Container
1915     ///
1916     /// Kill a container.
1917     ///
1918     /// # Arguments
1919     ///
1920     /// - Container name as string slice.
1921     /// - Optional [Kill Container Options](container/struct.KillContainerOptions.html) struct.
1922     ///
1923     /// # Returns
1924     ///
1925     ///  - unit type `()`, wrapped in a Future.
1926     ///
1927     /// # Examples
1928     ///
1929     /// ```rust
1930     /// # use bollard::Docker;
1931     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1932     ///
1933     /// use bollard::container::KillContainerOptions;
1934     ///
1935     /// let options = Some(KillContainerOptions{
1936     ///     signal: "SIGINT",
1937     /// });
1938     ///
1939     /// docker.kill_container("postgres", options);
1940     /// ```
kill_container<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> Result<(), Error> where T: KillContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,1941     pub async fn kill_container<T, K, V>(
1942         &self,
1943         container_name: &str,
1944         options: Option<T>,
1945     ) -> Result<(), Error>
1946     where
1947         T: KillContainerQueryParams<K, V>,
1948         K: AsRef<str>,
1949         V: AsRef<str>,
1950     {
1951         let url = format!("/containers/{}/kill", container_name);
1952 
1953         let req = self.build_request(
1954             &url,
1955             Builder::new().method(Method::POST),
1956             Docker::transpose_option(options.map(|o| o.into_array())),
1957             Ok(Body::empty()),
1958         );
1959 
1960         self.process_into_unit(req).await
1961     }
1962 
1963     /// ---
1964     ///
1965     /// # Update Container
1966     ///
1967     /// Update a container.
1968     ///
1969     /// # Arguments
1970     ///
1971     ///  - Container name as string slice.
1972     ///  - [Update Container Options](container/struct.UpdateContainerOptions.html) struct.
1973     ///
1974     /// # Returns
1975     ///
1976     ///  - unit type `()`, wrapped in a Future.
1977     ///
1978     /// # Examples
1979     ///
1980     /// ```rust
1981     /// # use bollard::Docker;
1982     /// # let docker = Docker::connect_with_http_defaults().unwrap();
1983     ///
1984     /// use bollard::container::UpdateContainerOptions;
1985     /// use std::default::Default;
1986     ///
1987     /// let config = UpdateContainerOptions::<String> {
1988     ///     memory: Some(314572800),
1989     ///     memory_swap: Some(314572800),
1990     ///     ..Default::default()
1991     /// };
1992     ///
1993     /// docker.update_container("postgres", config);
1994     /// ```
update_container<T: Into<String> + Eq + Hash + Serialize>( &self, container_name: &str, config: UpdateContainerOptions<T>, ) -> Result<(), Error>1995     pub async fn update_container<T: Into<String> + Eq + Hash + Serialize>(
1996         &self,
1997         container_name: &str,
1998         config: UpdateContainerOptions<T>,
1999     ) -> Result<(), Error> {
2000         let url = format!("/containers/{}/update", container_name);
2001 
2002         let req = self.build_request::<_, String, String>(
2003             &url,
2004             Builder::new().method(Method::POST),
2005             Ok(None::<ArrayVec<[(_, _); 0]>>),
2006             Docker::serialize_payload(Some(config)),
2007         );
2008 
2009         self.process_into_unit(req).await
2010     }
2011 
2012     /// ---
2013     ///
2014     /// # Rename Container
2015     ///
2016     /// Rename a container.
2017     ///
2018     /// # Arguments
2019     ///
2020     ///  - Container name as string slice.
2021     ///  - [Rename Container Options](container/struct.RenameContainerOptions.html) struct
2022     ///
2023     /// # Returns
2024     ///
2025     ///  - unit type `()`, wrapped in a Future.
2026     ///
2027     /// # Examples
2028     ///
2029     /// ```rust
2030     /// # use bollard::Docker;
2031     /// # let docker = Docker::connect_with_http_defaults().unwrap();
2032     ///
2033     /// use bollard::container::RenameContainerOptions;
2034     ///
2035     /// let required = RenameContainerOptions {
2036     ///     name: "my_new_container_name"
2037     /// };
2038     ///
2039     /// docker.rename_container("hello-world", required);
2040     /// ```
rename_container<T, K, V>( &self, container_name: &str, options: T, ) -> Result<(), Error> where T: RenameContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,2041     pub async fn rename_container<T, K, V>(
2042         &self,
2043         container_name: &str,
2044         options: T,
2045     ) -> Result<(), Error>
2046     where
2047         T: RenameContainerQueryParams<K, V>,
2048         K: AsRef<str>,
2049         V: AsRef<str>,
2050     {
2051         let url = format!("/containers/{}/rename", container_name);
2052 
2053         let req = self.build_request(
2054             &url,
2055             Builder::new().method(Method::POST),
2056             Docker::transpose_option(Some(options.into_array())),
2057             Ok(Body::empty()),
2058         );
2059 
2060         self.process_into_unit(req).await
2061     }
2062 
2063     /// ---
2064     ///
2065     /// # Pause Container
2066     ///
2067     /// Use the cgroups freezer to suspend all processes in a container.
2068     ///
2069     /// # Arguments
2070     ///
2071     ///  - Container name as a string slice.
2072     ///
2073     /// # Returns
2074     ///
2075     ///  - unit type `()`, wrapped in a Future.
2076     ///
2077     /// # Examples
2078     ///
2079     /// ```rust
2080     /// # use bollard::Docker;
2081     /// # let docker = Docker::connect_with_http_defaults().unwrap();
2082     ///
2083     /// docker.pause_container("postgres");
2084     /// ```
pause_container(&self, container_name: &str) -> Result<(), Error>2085     pub async fn pause_container(&self, container_name: &str) -> Result<(), Error> {
2086         let url = format!("/containers/{}/pause", container_name);
2087 
2088         let req = self.build_request::<_, String, String>(
2089             &url,
2090             Builder::new().method(Method::POST),
2091             Ok(None::<ArrayVec<[(_, _); 0]>>),
2092             Ok(Body::empty()),
2093         );
2094 
2095         self.process_into_unit(req).await
2096     }
2097 
2098     /// ---
2099     ///
2100     /// # Unpause Container
2101     ///
2102     /// Resume a container which has been paused.
2103     ///
2104     /// # Arguments
2105     ///
2106     ///  - Container name as a string slice.
2107     ///
2108     /// # Returns
2109     ///
2110     ///  - unit type `()`, wrapped in a Future.
2111     ///
2112     /// # Examples
2113     ///
2114     /// ```rust
2115     /// # use bollard::Docker;
2116     /// # let docker = Docker::connect_with_http_defaults().unwrap();
2117     ///
2118     /// docker.unpause_container("postgres");
2119     /// ```
unpause_container(&self, container_name: &str) -> Result<(), Error>2120     pub async fn unpause_container(&self, container_name: &str) -> Result<(), Error> {
2121         let url = format!("/containers/{}/unpause", container_name);
2122 
2123         let req = self.build_request::<_, String, String>(
2124             &url,
2125             Builder::new().method(Method::POST),
2126             Ok(None::<ArrayVec<[(_, _); 0]>>),
2127             Ok(Body::empty()),
2128         );
2129 
2130         self.process_into_unit(req).await
2131     }
2132 
2133     /// ---
2134     ///
2135     /// # Prune Containers
2136     ///
2137     /// Delete stopped containers.
2138     ///
2139     /// # Arguments
2140     ///
2141     ///  - Optional [Prune Containers Options](container/struct.PruneContainersOptions.html) struct.
2142     ///
2143     /// # Returns
2144     ///
2145     ///  - [Container Prune Response](models/struct.ContainerPruneResponse.html) struct, wrapped in a Future.
2146     ///
2147     /// # Examples
2148     ///
2149     /// ```rust
2150     /// # use bollard::Docker;
2151     /// # let docker = Docker::connect_with_http_defaults().unwrap();
2152     /// use bollard::container::PruneContainersOptions;
2153     ///
2154     /// use std::collections::HashMap;
2155     ///
2156     /// let mut filters = HashMap::new();
2157     /// filters.insert("until", vec!("10m"));
2158     ///
2159     /// let options = Some(PruneContainersOptions{
2160     ///     filters: filters
2161     /// });
2162     ///
2163     /// docker.prune_containers(options);
2164     /// ```
prune_containers<T, K>( &self, options: Option<T>, ) -> Result<ContainerPruneResponse, Error> where T: PruneContainersQueryParams<K>, K: AsRef<str> + Eq + Hash,2165     pub async fn prune_containers<T, K>(
2166         &self,
2167         options: Option<T>,
2168     ) -> Result<ContainerPruneResponse, Error>
2169     where
2170         T: PruneContainersQueryParams<K>,
2171         K: AsRef<str> + Eq + Hash,
2172     {
2173         let url = "/containers/prune";
2174 
2175         let req = self.build_request(
2176             &url,
2177             Builder::new().method(Method::POST),
2178             Docker::transpose_option(options.map(|o| o.into_array())),
2179             Ok(Body::empty()),
2180         );
2181 
2182         self.process_into_value(req).await
2183     }
2184 
2185     /// ---
2186     ///
2187     /// # Upload To Container
2188     ///
2189     /// Upload a tar archive to be extracted to a path in the filesystem of container id.
2190     ///
2191     /// # Arguments
2192     ///
2193     ///  - Optional [Upload To Container Options](container/struct.UploadToContainerOptions.html) struct.
2194     ///
2195     /// # Returns
2196     ///
2197     ///  - unit type `()`, wrapped in a Future.
2198     ///
2199     /// # Examples
2200     ///
2201     /// ```rust,no_run
2202     /// # use bollard::Docker;
2203     /// # let docker = Docker::connect_with_http_defaults().unwrap();
2204     /// use bollard::container::UploadToContainerOptions;
2205     ///
2206     /// use std::default::Default;
2207     /// use std::fs::File;
2208     /// use std::io::Read;
2209     ///
2210     /// let options = Some(UploadToContainerOptions{
2211     ///     path: "/opt",
2212     ///     ..Default::default()
2213     /// });
2214     ///
2215     /// let mut file = File::open("tarball.tar.gz").unwrap();
2216     /// let mut contents = Vec::new();
2217     /// file.read_to_end(&mut contents).unwrap();
2218     ///
2219     /// docker.upload_to_container("my-container", options, contents.into());
2220     /// ```
upload_to_container<T, K, V>( &self, container_name: &str, options: Option<T>, tar: Body, ) -> Result<(), Error> where T: UploadToContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,2221     pub async fn upload_to_container<T, K, V>(
2222         &self,
2223         container_name: &str,
2224         options: Option<T>,
2225         tar: Body,
2226     ) -> Result<(), Error>
2227     where
2228         T: UploadToContainerQueryParams<K, V>,
2229         K: AsRef<str>,
2230         V: AsRef<str>,
2231     {
2232         let url = format!("/containers/{}/archive", container_name);
2233 
2234         let req = self.build_request(
2235             &url,
2236             Builder::new()
2237                 .method(Method::PUT)
2238                 .header(CONTENT_TYPE, "application/x-tar"),
2239             Docker::transpose_option(options.map(|o| o.into_array())),
2240             Ok(tar),
2241         );
2242 
2243         self.process_into_unit(req).await
2244     }
2245 
2246     /// ---
2247     ///
2248     /// # Download From Container
2249     ///
2250     /// Get a tar archive of a resource in the filesystem of container id.
2251     ///
2252     /// # Arguments
2253     ///
2254     ///  - [Download From Container Options](container/struct.DownloadFromContainerOptions.html) struct.
2255     ///
2256     /// # Returns
2257     ///
2258     ///  - Tar archive compressed with one of the following algorithms: identity (no compression),
2259     ///    gzip, bzip2, xz. [Hyper Body](https://hyper.rs/hyper/master/hyper/struct.Body.html).
2260     ///
2261     /// # Examples
2262     ///
2263     /// ```rust
2264     /// # use bollard::Docker;
2265     /// # let docker = Docker::connect_with_http_defaults().unwrap();
2266     /// use bollard::container::DownloadFromContainerOptions;
2267     ///
2268     /// let options = Some(DownloadFromContainerOptions{
2269     ///     path: "/opt",
2270     /// });
2271     ///
2272     /// docker.download_from_container("my-container", options);
2273     /// ```
download_from_container<T, K, V>( &self, container_name: &str, options: Option<T>, ) -> impl Stream<Item = Result<Bytes, Error>> where T: DownloadFromContainerQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,2274     pub fn download_from_container<T, K, V>(
2275         &self,
2276         container_name: &str,
2277         options: Option<T>,
2278     ) -> impl Stream<Item = Result<Bytes, Error>>
2279     where
2280         T: DownloadFromContainerQueryParams<K, V>,
2281         K: AsRef<str>,
2282         V: AsRef<str>,
2283     {
2284         let url = format!("/containers/{}/archive", container_name);
2285 
2286         let req = self.build_request(
2287             &url,
2288             Builder::new().method(Method::GET),
2289             Docker::transpose_option(options.map(|o| o.into_array())),
2290             Ok(Body::empty()),
2291         );
2292 
2293         self.process_into_body(req)
2294     }
2295 }
2296