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