summaryrefslogtreecommitdiffstats
path: root/src/docker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/docker.rs')
-rw-r--r--src/docker.rs147
1 files changed, 145 insertions, 2 deletions
diff --git a/src/docker.rs b/src/docker.rs
index d3faa82..c44356e 100644
--- a/src/docker.rs
+++ b/src/docker.rs
@@ -2,15 +2,15 @@
//!
//! API Reference: <https://docs.docker.com/engine/api/v1.41/>
-use std::{env, io, path::Path};
+use std::{collections::HashMap, env, io, path::Path};
use futures_util::{stream::Stream, TryStreamExt};
use hyper::{client::HttpConnector, Body, Client, Method};
use mime::Mime;
use serde_json::Value;
+use url::form_urlencoded;
use crate::{
- builder::EventsOptions,
container::Containers,
errors::{Error, Result},
image::Images,
@@ -399,6 +399,149 @@ impl Default for Docker {
}
}
+/// Options for filtering streams of Docker events
+#[derive(Default, Debug)]
+pub struct EventsOptions {
+ params: HashMap<&'static str, String>,
+}
+
+impl EventsOptions {
+ pub fn builder() -> EventsOptionsBuilder {
+ EventsOptionsBuilder::default()
+ }
+
+ /// serialize options as a string. returns None if no options are defined
+ pub fn serialize(&self) -> Option<String> {
+ if self.params.is_empty() {
+ None
+ } else {
+ Some(
+ form_urlencoded::Serializer::new(String::new())
+ .extend_pairs(&self.params)
+ .finish(),
+ )
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+pub enum EventFilterType {
+ Container,
+ Image,
+ Volume,
+ Network,
+ Daemon,
+}
+
+fn event_filter_type_to_string(filter: EventFilterType) -> &'static str {
+ match filter {
+ EventFilterType::Container => "container",
+ EventFilterType::Image => "image",
+ EventFilterType::Volume => "volume",
+ EventFilterType::Network => "network",
+ EventFilterType::Daemon => "daemon",
+ }
+}
+
+/// Filter options for image listings
+pub enum EventFilter {
+ Container(String),
+ Event(String),
+ Image(String),
+ Label(String),
+ Type(EventFilterType),
+ Volume(String),
+ Network(String),
+ Daemon(String),
+}
+
+/// Builder interface for `EventOptions`
+#[derive(Default)]
+pub struct EventsOptionsBuilder {
+ params: HashMap<&'static str, String>,
+ events: Vec<String>,
+ containers: Vec<String>,
+ images: Vec<String>,
+ labels: Vec<String>,
+ volumes: Vec<String>,
+ networks: Vec<String>,
+ daemons: Vec<String>,
+ types: Vec<String>,
+}
+
+impl EventsOptionsBuilder {
+ /// Filter events since a given timestamp
+ pub fn since(
+ &mut self,
+ ts: &u64,
+ ) -> &mut Self {
+ self.params.insert("since", ts.to_string());
+ self
+ }
+
+ /// Filter events until a given timestamp
+ pub fn until(
+ &mut self,
+ ts: &u64,
+ ) -> &mut Self {
+ self.params.insert("until", ts.to_string());
+ self
+ }
+
+ pub fn filter(
+ &mut self,
+ filters: Vec<EventFilter>,
+ ) -> &mut Self {
+ let mut params = HashMap::new();
+ for f in filters {
+ match f {
+ EventFilter::Container(n) => {
+ self.containers.push(n);
+ params.insert("container", self.containers.clone())
+ }
+ EventFilter::Event(n) => {
+ self.events.push(n);
+ params.insert("event", self.events.clone())
+ }
+ EventFilter::Image(n) => {
+ self.images.push(n);
+ params.insert("image", self.images.clone())
+ }
+ EventFilter::Label(n) => {
+ self.labels.push(n);
+ params.insert("label", self.labels.clone())
+ }
+ EventFilter::Volume(n) => {
+ self.volumes.push(n);
+ params.insert("volume", self.volumes.clone())
+ }
+ EventFilter::Network(n) => {
+ self.networks.push(n);
+ params.insert("network", self.networks.clone())
+ }
+ EventFilter::Daemon(n) => {
+ self.daemons.push(n);
+ params.insert("daemon", self.daemons.clone())
+ }
+ EventFilter::Type(n) => {
+ let event_type = event_filter_type_to_string(n).to_string();
+ self.types.push(event_type);
+ params.insert("type", self.types.clone())
+ }
+ };
+ }
+ self.params
+ .insert("filters", serde_json::to_string(&params).unwrap());
+ self
+ }
+
+ pub fn build(&self) -> EventsOptions {
+ EventsOptions {
+ params: self.params.clone(),
+ }
+ }
+}
+
#[cfg(test)]
mod tests {
#[cfg(feature = "unix-socket")]