From 3667ae716733b26526f6c16d8312bc22129430d6 Mon Sep 17 00:00:00 2001 From: "Eli W. Hunter" Date: Tue, 9 Feb 2021 10:06:44 -0500 Subject: Split up rep.rs --- src/container.rs | 247 ++++++++++++++++- src/datetime.rs | 26 ++ src/docker.rs | 80 +++++- src/exec.rs | 30 +- src/image.rs | 122 ++++++++- src/lib.rs | 29 +- src/network.rs | 99 ++++++- src/rep.rs | 822 ------------------------------------------------------- src/service.rs | 191 ++++++++++++- src/volume.rs | 38 ++- 10 files changed, 830 insertions(+), 854 deletions(-) create mode 100644 src/datetime.rs delete mode 100644 src/rep.rs (limited to 'src') diff --git a/src/container.rs b/src/container.rs index d796c73..dad0dc9 100644 --- a/src/container.rs +++ b/src/container.rs @@ -11,7 +11,7 @@ use futures_util::{ }; use hyper::Body; use mime::Mime; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::{json, Map, Value}; use url::form_urlencoded; @@ -19,13 +19,17 @@ use crate::{ docker::Docker, errors::{Error, Result}, exec::{Exec, ExecContainerOptions}, - rep::{ - Change, Container as ContainerInfo, ContainerCreateInfo, ContainerDetails, Exit, Stats, Top, - }, + image::Config, + network::{NetworkInfo, NetworkSettings}, transport::Payload, tty::{self, Multiplexer as TtyMultiPlexer}, }; +#[cfg(feature = "chrono")] +use crate::datetime::datetime_from_unix_timestamp; +#[cfg(feature = "chrono")] +use chrono::{DateTime, Utc}; + /// Interface for accessing and manipulating a docker container pub struct Container<'docker> { docker: &'docker Docker, @@ -1119,6 +1123,241 @@ impl RmContainerOptionsBuilder { } } +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ContainerInfo { + #[cfg(feature = "chrono")] + #[serde(deserialize_with = "datetime_from_unix_timestamp")] + pub created: DateTime, + #[cfg(not(feature = "chrono"))] + pub created: u64, + pub command: String, + pub id: String, + pub image: String, + #[serde(rename = "ImageID")] + pub image_id: String, + pub labels: HashMap, + pub names: Vec, + pub ports: Vec, + pub state: String, + pub status: String, + pub size_rw: Option, + pub size_root_fs: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ContainerDetails { + pub app_armor_profile: String, + pub args: Vec, + pub config: Config, + #[cfg(feature = "chrono")] + pub created: DateTime, + #[cfg(not(feature = "chrono"))] + pub created: String, + pub driver: String, + // pub ExecIDs: ?? + pub host_config: HostConfig, + pub hostname_path: String, + pub hosts_path: String, + pub log_path: String, + pub id: String, + pub image: String, + pub mount_label: String, + pub name: String, + pub network_settings: NetworkSettings, + pub path: String, + pub process_label: String, + pub resolv_conf_path: String, + pub restart_count: u64, + pub state: State, + pub mounts: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Mount { + pub source: String, + pub destination: String, + pub mode: String, + #[serde(rename = "RW")] + pub rw: bool, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct State { + pub error: String, + pub exit_code: u64, + #[cfg(feature = "chrono")] + pub finished_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub finished_at: String, + #[serde(rename = "OOMKilled")] + pub oom_killed: bool, + pub paused: bool, + pub pid: u64, + pub restarting: bool, + pub running: bool, + #[cfg(feature = "chrono")] + pub started_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub started_at: String, + pub status: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct HostConfig { + pub cgroup_parent: Option, + #[serde(rename = "ContainerIDFile")] + pub container_id_file: String, + pub cpu_shares: Option, + pub cpuset_cpus: Option, + pub memory: Option, + pub memory_swap: Option, + pub network_mode: String, + pub pid_mode: Option, + pub port_bindings: Option>>>, + pub privileged: bool, + pub publish_all_ports: bool, + pub readonly_rootfs: Option, /* pub RestartPolicy: ??? + * pub SecurityOpt: Option, + * pub Ulimits: Option + * pub VolumesFrom: Option */ +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Port { + pub ip: Option, + pub private_port: u64, + pub public_port: Option, + #[serde(rename = "Type")] + pub typ: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Stats { + pub read: String, + pub networks: HashMap, + pub memory_stats: MemoryStats, + pub blkio_stats: BlkioStats, + pub cpu_stats: CpuStats, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct MemoryStats { + pub max_usage: u64, + pub usage: u64, + pub failcnt: Option, + pub limit: u64, + pub stats: MemoryStat, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct MemoryStat { + pub total_pgmajfault: u64, + pub cache: u64, + pub mapped_file: u64, + pub total_inactive_file: u64, + pub pgpgout: u64, + pub rss: u64, + pub total_mapped_file: u64, + pub writeback: u64, + pub unevictable: u64, + pub pgpgin: u64, + pub total_unevictable: u64, + pub pgmajfault: u64, + pub total_rss: u64, + pub total_rss_huge: u64, + pub total_writeback: u64, + pub total_inactive_anon: u64, + pub rss_huge: u64, + pub hierarchical_memory_limit: u64, + pub hierarchical_memsw_limit: u64, + pub total_pgfault: u64, + pub total_active_file: u64, + pub active_anon: u64, + pub total_active_anon: u64, + pub total_pgpgout: u64, + pub total_cache: u64, + pub inactive_anon: u64, + pub active_file: u64, + pub pgfault: u64, + pub inactive_file: u64, + pub total_pgpgin: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CpuStats { + pub cpu_usage: CpuUsage, + pub system_cpu_usage: u64, + pub throttling_data: ThrottlingData, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CpuUsage { + pub percpu_usage: Vec, + pub usage_in_usermode: u64, + pub total_usage: u64, + pub usage_in_kernelmode: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ThrottlingData { + pub periods: u64, + pub throttled_periods: u64, + pub throttled_time: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BlkioStats { + pub io_service_bytes_recursive: Vec, + pub io_serviced_recursive: Vec, + pub io_queue_recursive: Vec, + pub io_service_time_recursive: Vec, + pub io_wait_time_recursive: Vec, + pub io_merged_recursive: Vec, + pub io_time_recursive: Vec, + pub sectors_recursive: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BlkioStat { + pub major: u64, + pub minor: u64, + pub op: String, + pub value: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Change { + pub kind: u64, + pub path: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Top { + pub titles: Vec, + pub processes: Vec>, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ContainerCreateInfo { + pub id: String, + pub warnings: Option>, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Exit { + pub status_code: u64, +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/datetime.rs b/src/datetime.rs new file mode 100644 index 0000000..4ee388c --- /dev/null +++ b/src/datetime.rs @@ -0,0 +1,26 @@ +use chrono::{DateTime, Utc}; +use serde::Deserialize; + +pub(crate) fn datetime_from_unix_timestamp<'de, D>( + deserializer: D +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let timestamp = chrono::NaiveDateTime::from_timestamp(i64::deserialize(deserializer)?, 0); + Ok(DateTime::::from_utc(timestamp, Utc)) +} + +pub(crate) fn datetime_from_nano_timestamp<'de, D>( + deserializer: D +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let timestamp_nano = u64::deserialize(deserializer)?; + let timestamp = chrono::NaiveDateTime::from_timestamp( + (timestamp_nano / 1_000_000_000) as i64, + (timestamp_nano % 1_000_000_000) as u32, + ); + Ok(DateTime::::from_utc(timestamp, Utc)) +} diff --git a/src/docker.rs b/src/docker.rs index c44356e..edb97e4 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -7,6 +7,7 @@ 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::{Deserialize, Serialize}; use serde_json::Value; use url::form_urlencoded; @@ -15,13 +16,17 @@ use crate::{ errors::{Error, Result}, image::Images, network::Networks, - rep::{Event, Info, Version}, service::Services, transport::{Headers, Payload, Transport}, volume::Volumes, Uri, }; +#[cfg(feature = "chrono")] +use crate::datetime::{datetime_from_nano_timestamp, datetime_from_unix_timestamp}; +#[cfg(feature = "chrono")] +use chrono::{DateTime, Utc}; + #[cfg(feature = "tls")] use hyper_openssl::HttpsConnector; #[cfg(feature = "tls")] @@ -542,6 +547,79 @@ impl EventsOptionsBuilder { } } +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Version { + pub version: String, + pub api_version: String, + pub git_commit: String, + pub go_version: String, + pub os: String, + pub arch: String, + pub kernel_version: String, + #[cfg(feature = "chrono")] + pub build_time: DateTime, + #[cfg(not(feature = "chrono"))] + pub build_time: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Info { + pub containers: u64, + pub images: u64, + pub driver: String, + pub docker_root_dir: String, + pub driver_status: Vec>, + #[serde(rename = "ID")] + pub id: String, + pub kernel_version: String, + // pub Labels: Option, + pub mem_total: u64, + pub memory_limit: bool, + #[serde(rename = "NCPU")] + pub n_cpu: u64, + pub n_events_listener: u64, + pub n_goroutines: u64, + pub name: String, + pub operating_system: String, + // pub RegistryConfig:??? + pub swap_limit: bool, + pub system_time: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Event { + #[serde(rename = "Type")] + pub typ: String, + #[serde(rename = "Action")] + pub action: String, + #[serde(rename = "Actor")] + pub actor: Actor, + pub status: Option, + pub id: Option, + pub from: Option, + #[cfg(feature = "chrono")] + #[serde(deserialize_with = "datetime_from_unix_timestamp")] + pub time: DateTime, + #[cfg(not(feature = "chrono"))] + pub time: u64, + #[cfg(feature = "chrono")] + #[serde(deserialize_with = "datetime_from_nano_timestamp", rename = "timeNano")] + pub time_nano: DateTime, + #[cfg(not(feature = "chrono"))] + #[serde(rename = "timeNano")] + pub time_nano: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Actor { + #[serde(rename = "ID")] + pub id: String, + #[serde(rename = "Attributes")] + pub attributes: HashMap, +} + #[cfg(test)] mod tests { #[cfg(feature = "unix-socket")] diff --git a/src/exec.rs b/src/exec.rs index 5642f95..f90a08a 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -10,12 +10,11 @@ use std::{ use futures_util::{stream::Stream, TryFutureExt}; use hyper::Body; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use crate::{ errors::{Error, Result}, - rep::ExecDetails, tty, Docker, }; @@ -339,3 +338,30 @@ impl ExecResizeOptionsBuilder { } } } + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ExecDetails { + pub can_remove: bool, + #[serde(rename = "ContainerID")] + pub container_id: String, + pub detach_keys: String, + pub exit_code: Option, + #[serde(rename = "ID")] + pub id: String, + pub open_stderr: bool, + pub open_stdin: bool, + pub open_stdout: bool, + pub process_config: ProcessConfig, + pub running: bool, + pub pid: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ProcessConfig { + pub arguments: Vec, + pub entrypoint: String, + pub privileged: bool, + pub tty: bool, + pub user: Option, +} diff --git a/src/image.rs b/src/image.rs index fd78e6d..45b24af 100644 --- a/src/image.rs +++ b/src/image.rs @@ -6,18 +6,17 @@ use std::{collections::HashMap, io::Read, iter}; use futures_util::{stream::Stream, TryFutureExt, TryStreamExt}; use hyper::Body; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::Value; use url::form_urlencoded; -use crate::{ - errors::Result, - rep::{History, Image as ImageRep, ImageDetails, SearchResult, Status}, - tarball, - transport::tar, -}; +use crate::{docker::Docker, errors::Result, tarball, transport::tar}; + +#[cfg(feature = "chrono")] +use crate::datetime::datetime_from_unix_timestamp; +#[cfg(feature = "chrono")] +use chrono::{DateTime, Utc}; -use crate::Docker; /// Interface for accessing and manipulating a named docker image pub struct Image<'docker> { docker: &'docker Docker, @@ -134,12 +133,14 @@ impl<'docker> Images<'docker> { pub async fn list( &self, opts: &ImageListOptions, - ) -> Result> { + ) -> Result> { let mut path = vec!["/images/json".to_owned()]; if let Some(query) = opts.serialize() { path.push(query); } - self.docker.get_json::>(&path.join("?")).await + self.docker + .get_json::>(&path.join("?")) + .await } /// Returns a reference to a set of operations available for a named image @@ -736,6 +737,107 @@ impl ImageListOptionsBuilder { } } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct SearchResult { + pub description: String, + pub is_official: bool, + pub is_automated: bool, + pub name: String, + pub star_count: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ImageInfo { + #[cfg(feature = "chrono")] + #[serde(deserialize_with = "datetime_from_unix_timestamp")] + pub created: DateTime, + #[cfg(not(feature = "chrono"))] + pub created: u64, + pub id: String, + pub parent_id: String, + pub labels: Option>, + pub repo_tags: Option>, + pub repo_digests: Option>, + pub virtual_size: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ImageDetails { + pub architecture: String, + pub author: String, + pub comment: String, + pub config: Config, + #[cfg(feature = "chrono")] + pub created: DateTime, + #[cfg(not(feature = "chrono"))] + pub created: String, + pub docker_version: String, + pub id: String, + pub os: String, + pub parent: String, + pub repo_tags: Option>, + pub repo_digests: Option>, + pub size: u64, + pub virtual_size: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Config { + pub attach_stderr: bool, + pub attach_stdin: bool, + pub attach_stdout: bool, + pub cmd: Option>, + pub domainname: String, + pub entrypoint: Option>, + pub env: Option>, + pub exposed_ports: Option>>, + pub hostname: String, + pub image: String, + pub labels: Option>, + // pub MacAddress: String, + pub on_build: Option>, + // pub NetworkDisabled: bool, + pub open_stdin: bool, + pub stdin_once: bool, + pub tty: bool, + pub user: String, + pub working_dir: String, +} + +impl Config { + pub fn env(&self) -> HashMap { + let mut map = HashMap::new(); + if let Some(ref vars) = self.env { + for e in vars { + let pair: Vec<&str> = e.split('=').collect(); + map.insert(pair[0].to_owned(), pair[1].to_owned()); + } + } + map + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct History { + pub id: String, + #[cfg(feature = "chrono")] + #[serde(deserialize_with = "datetime_from_unix_timestamp")] + pub created: DateTime, + #[cfg(not(feature = "chrono"))] + pub created: u64, + pub created_by: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum Status { + Untagged(String), + Deleted(String), +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/lib.rs b/src/lib.rs index 8f4314e..67b830e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,6 @@ //! ``` pub mod errors; -pub mod rep; pub mod transport; pub mod tty; @@ -32,6 +31,9 @@ pub mod volume; mod tarball; +#[cfg(feature = "chrono")] +mod datetime; + pub use hyper::Uri; pub use crate::{ @@ -106,3 +108,28 @@ reexport! { }; volume::{VolumeCreateOptions, VolumeCreateOptionsBuilder}; } + +reexport! { + mod rep; + container::{ + ContainerInfo as Container, ContainerDetails, Mount, State, HostConfig, Port, Stats, + MemoryStats, MemoryStat, CpuStats, CpuUsage, ThrottlingData, BlkioStats, BlkioStat, Change, + Top, ContainerCreateInfo, Exit, + }; + docker::{Version, Info, Event, Actor}; + exec::{ExecDetails, ProcessConfig}; + image::{ + SearchResult, ImageInfo as Image, ImageDetails, Config, History, Status, + }; + network::{ + NetworkSettings, NetworkEntry, NetworkInfo as Network, IPAM, NetworkDetails, + NetworkContainerDetails, NetworkCreateInfo, + }; + service::{ + ServicesInfo as Services, ServiceInfo as Service, ObjectVersion, Endpoint, EndpointSpec, + EndpointPortConfig, UpdateStatus, ServiceStatus, JobStatus, ServiceDetails, ServiceSpec, + TaskSpec, Mode, Replicated, ReplicatedJob, UpdateConfig, RollbackConfig, + NetworkAttachmentConfig, ServiceCreateInfo, + }; + volume::{VolumeCreateInfo, VolumesInfo as Volumes, VolumeInfo as Volume}; +} diff --git a/src/network.rs b/src/network.rs index cc9a62e..e274d2d 100644 --- a/src/network.rs +++ b/src/network.rs @@ -8,14 +8,13 @@ use std::{ }; use hyper::Body; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use url::form_urlencoded; use crate::{ + docker::Docker, errors::{Error, Result}, - rep::{NetworkCreateInfo, NetworkDetails as NetworkInfo}, - Docker, }; /// Interface for docker network @@ -300,3 +299,97 @@ impl ContainerConnectionOptionsBuilder { } } } + +type PortDescription = HashMap>>>; + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct NetworkSettings { + pub bridge: String, + pub gateway: String, + #[serde(rename = "IPAddress")] + pub ip_address: String, + #[serde(rename = "IPPrefixLen")] + pub ip_prefix_len: u64, + pub mac_address: String, + pub ports: Option, + pub networks: HashMap, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct NetworkEntry { + #[serde(rename = "NetworkID")] + pub network_id: String, + #[serde(rename = "EndpointID")] + pub endpoint_id: String, + pub gateway: String, + #[serde(rename = "IPAddress")] + pub ip_address: String, + #[serde(rename = "IPPrefixLen")] + pub ip_prefix_len: u64, + #[serde(rename = "IPv6Gateway")] + pub ipv6_gateway: String, + #[serde(rename = "GlobalIPv6Address")] + pub global_ipv6_address: String, + #[serde(rename = "GlobalIPv6PrefixLen")] + pub global_ipv6_prefix_len: u64, + pub mac_address: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct NetworkInfo { + pub rx_dropped: u64, + pub rx_bytes: u64, + pub rx_errors: u64, + pub tx_packets: u64, + pub tx_dropped: u64, + pub rx_packets: u64, + pub tx_errors: u64, + pub tx_bytes: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct IPAM { + pub driver: String, + pub config: Vec>, + pub options: Option>, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct NetworkDetails { + pub name: String, + pub id: String, + pub scope: String, + pub driver: String, + #[serde(rename = "EnableIPv6")] + pub enable_ipv6: bool, + #[serde(rename = "IPAM")] + pub ipam: IPAM, + pub internal: bool, + pub attachable: bool, + pub containers: HashMap, + pub options: Option>, + pub labels: Option>, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct NetworkContainerDetails { + #[serde(rename = "EndpointID")] + pub endpoint_id: String, + pub mac_address: String, + #[serde(rename = "IPv4Address")] + pub ipv4_address: String, + #[serde(rename = "IPv6Address")] + pub ipv6_address: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct NetworkCreateInfo { + pub id: String, + pub warning: String, +} diff --git a/src/rep.rs b/src/rep.rs deleted file mode 100644 index 3ad5cf1..0000000 --- a/src/rep.rs +++ /dev/null @@ -1,822 +0,0 @@ -//! Rust representations of docker json structures - -// TODO: Move structs to their corresponding modules? - -#[cfg(feature = "chrono")] -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct SearchResult { - pub description: String, - pub is_official: bool, - pub is_automated: bool, - pub name: String, - pub star_count: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Image { - #[cfg(feature = "chrono")] - #[serde(deserialize_with = "datetime_from_unix_timestamp")] - pub created: DateTime, - #[cfg(not(feature = "chrono"))] - pub created: u64, - pub id: String, - pub parent_id: String, - pub labels: Option>, - pub repo_tags: Option>, - pub repo_digests: Option>, - pub virtual_size: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ImageDetails { - pub id: String, - pub repo_tags: Option>, - pub repo_digests: Option>, - pub parent: String, - pub comment: String, - #[cfg(feature = "chrono")] - pub created: DateTime, - #[cfg(not(feature = "chrono"))] - pub created: String, - pub container: String, - pub container_config: Option, - pub docker_version: String, - pub author: String, - pub config: Option, - pub architecture: String, - pub os: String, - pub os_version: Option, - pub size: i64, - pub virtual_size: i64, - pub graph_driver: GraphDriverData, - #[serde(rename = "RootFS")] - pub root_fs: RootFS, - pub metadata: Metadata, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Container { - #[cfg(feature = "chrono")] - #[serde(deserialize_with = "datetime_from_unix_timestamp")] - pub created: DateTime, - #[cfg(not(feature = "chrono"))] - pub created: u64, - pub command: String, - pub id: String, - pub image: String, - #[serde(rename = "ImageID")] - pub image_id: String, - pub labels: HashMap, - pub names: Vec, - pub ports: Vec, - pub state: String, - pub status: String, - pub size_rw: Option, - pub size_root_fs: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ContainerDetails { - pub app_armor_profile: String, - pub args: Vec, - pub config: ContainerConfig, - #[cfg(feature = "chrono")] - pub created: DateTime, - #[cfg(not(feature = "chrono"))] - pub created: String, - pub driver: String, - // pub ExecIDs: ?? - pub host_config: HostConfig, - pub hostname_path: String, - pub hosts_path: String, - pub log_path: String, - pub id: String, - pub image: String, - pub mount_label: String, - pub name: String, - pub network_settings: NetworkSettings, - pub path: String, - pub process_label: String, - pub resolv_conf_path: String, - pub restart_count: u64, - pub state: State, - pub mounts: Vec, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Mount { - pub source: String, - pub destination: String, - pub mode: String, - #[serde(rename = "RW")] - pub rw: bool, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct State { - pub error: String, - pub exit_code: u64, - #[cfg(feature = "chrono")] - pub finished_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub finished_at: String, - #[serde(rename = "OOMKilled")] - pub oom_killed: bool, - pub paused: bool, - pub pid: u64, - pub restarting: bool, - pub running: bool, - #[cfg(feature = "chrono")] - pub started_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub started_at: String, - pub status: String, -} - -type PortDescription = HashMap>>>; - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct NetworkSettings { - pub bridge: String, - pub gateway: String, - #[serde(rename = "IPAddress")] - pub ip_address: String, - #[serde(rename = "IPPrefixLen")] - pub ip_prefix_len: u64, - pub mac_address: String, - pub ports: Option, - pub networks: HashMap, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct NetworkEntry { - #[serde(rename = "NetworkID")] - pub network_id: String, - #[serde(rename = "EndpointID")] - pub endpoint_id: String, - pub gateway: String, - #[serde(rename = "IPAddress")] - pub ip_address: String, - #[serde(rename = "IPPrefixLen")] - pub ip_prefix_len: u64, - #[serde(rename = "IPv6Gateway")] - pub ipv6_gateway: String, - #[serde(rename = "GlobalIPv6Address")] - pub global_ipv6_address: String, - #[serde(rename = "GlobalIPv6PrefixLen")] - pub global_ipv6_prefix_len: u64, - pub mac_address: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct HostConfig { - pub cgroup_parent: Option, - #[serde(rename = "ContainerIDFile")] - pub container_id_file: String, - pub cpu_shares: Option, - pub cpuset_cpus: Option, - pub memory: Option, - pub memory_swap: Option, - pub network_mode: String, - pub pid_mode: Option, - pub port_bindings: Option>>>, - pub privileged: bool, - pub publish_all_ports: bool, - pub readonly_rootfs: Option, /* pub RestartPolicy: ??? - * pub SecurityOpt: Option, - * pub Ulimits: Option - * pub VolumesFrom: Option */ -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ContainerConfig { - pub hostname: String, - pub domainname: String, - pub user: String, - pub attach_stdin: bool, - pub attach_stdout: bool, - pub attach_stderr: bool, - pub exposed_ports: Option>>, - pub tty: bool, - pub open_stdin: bool, - pub stdin_once: bool, - pub env: Option>, - pub cmd: Option>, - pub healtcheck: Option, - pub args_escaped: Option, - pub image: String, - pub volumes: Option>>, - pub working_dir: String, - pub entrypoint: Option>, - pub network_disabled: Option, - pub mac_address: Option, - pub on_build: Option>, - pub labels: Option>, - pub stop_signal: Option, - pub stop_timeout: Option, - pub shell: Option>, -} - -impl ContainerConfig { - pub fn env(&self) -> HashMap { - let mut map = HashMap::new(); - if let Some(ref vars) = self.env { - for e in vars { - let pair: Vec<&str> = e.split('=').collect(); - map.insert(pair[0].to_owned(), pair[1].to_owned()); - } - } - map - } -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct HealthConfig { - pub test: Option>, - pub interval: Option, - pub timeout: Option, - pub retries: Option, - pub start_period: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct GraphDriverData { - pub name: String, - pub data: HashMap, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct RootFS { - #[serde(rename = "Type")] - pub typ: String, - pub layers: Option>, - pub base_layer: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Metadata { - #[cfg(feature = "chrono")] - pub last_tag_time: DateTime, - #[cfg(not(feature = "chrono"))] - pub last_tag_time: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Port { - pub ip: Option, - pub private_port: u64, - pub public_port: Option, - #[serde(rename = "Type")] - pub typ: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Stats { - pub read: String, - pub networks: HashMap, - pub memory_stats: MemoryStats, - pub blkio_stats: BlkioStats, - pub cpu_stats: CpuStats, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Network { - pub rx_dropped: u64, - pub rx_bytes: u64, - pub rx_errors: u64, - pub tx_packets: u64, - pub tx_dropped: u64, - pub rx_packets: u64, - pub tx_errors: u64, - pub tx_bytes: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct IPAM { - pub driver: String, - pub config: Vec>, - pub options: Option>, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct NetworkDetails { - pub name: String, - pub id: String, - pub scope: String, - pub driver: String, - #[serde(rename = "EnableIPv6")] - pub enable_ipv6: bool, - #[serde(rename = "IPAM")] - pub ipam: IPAM, - pub internal: bool, - pub attachable: bool, - pub containers: HashMap, - pub options: Option>, - pub labels: Option>, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct NetworkContainerDetails { - #[serde(rename = "EndpointID")] - pub endpoint_id: String, - pub mac_address: String, - #[serde(rename = "IPv4Address")] - pub ipv4_address: String, - #[serde(rename = "IPv6Address")] - pub ipv6_address: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct NetworkCreateInfo { - pub id: String, - pub warning: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct MemoryStats { - pub max_usage: u64, - pub usage: u64, - pub failcnt: Option, - pub limit: u64, - pub stats: MemoryStat, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct MemoryStat { - pub total_pgmajfault: u64, - pub cache: u64, - pub mapped_file: u64, - pub total_inactive_file: u64, - pub pgpgout: u64, - pub rss: u64, - pub total_mapped_file: u64, - pub writeback: u64, - pub unevictable: u64, - pub pgpgin: u64, - pub total_unevictable: u64, - pub pgmajfault: u64, - pub total_rss: u64, - pub total_rss_huge: u64, - pub total_writeback: u64, - pub total_inactive_anon: u64, - pub rss_huge: u64, - pub hierarchical_memory_limit: u64, - pub hierarchical_memsw_limit: u64, - pub total_pgfault: u64, - pub total_active_file: u64, - pub active_anon: u64, - pub total_active_anon: u64, - pub total_pgpgout: u64, - pub total_cache: u64, - pub inactive_anon: u64, - pub active_file: u64, - pub pgfault: u64, - pub inactive_file: u64, - pub total_pgpgin: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct CpuStats { - pub cpu_usage: CpuUsage, - pub system_cpu_usage: u64, - pub throttling_data: ThrottlingData, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct CpuUsage { - pub percpu_usage: Vec, - pub usage_in_usermode: u64, - pub total_usage: u64, - pub usage_in_kernelmode: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct ThrottlingData { - pub periods: u64, - pub throttled_periods: u64, - pub throttled_time: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct BlkioStats { - pub io_service_bytes_recursive: Vec, - pub io_serviced_recursive: Vec, - pub io_queue_recursive: Vec, - pub io_service_time_recursive: Vec, - pub io_wait_time_recursive: Vec, - pub io_merged_recursive: Vec, - pub io_time_recursive: Vec, - pub sectors_recursive: Vec, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct BlkioStat { - pub major: u64, - pub minor: u64, - pub op: String, - pub value: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Change { - pub kind: u64, - pub path: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Top { - pub titles: Vec, - pub processes: Vec>, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Version { - pub version: String, - pub api_version: String, - pub git_commit: String, - pub go_version: String, - pub os: String, - pub arch: String, - pub kernel_version: String, - #[cfg(feature = "chrono")] - pub build_time: DateTime, - #[cfg(not(feature = "chrono"))] - pub build_time: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Info { - pub containers: u64, - pub images: u64, - pub driver: String, - pub docker_root_dir: String, - pub driver_status: Vec>, - #[serde(rename = "ID")] - pub id: String, - pub kernel_version: String, - // pub Labels: Option, - pub mem_total: u64, - pub memory_limit: bool, - #[serde(rename = "NCPU")] - pub n_cpu: u64, - pub n_events_listener: u64, - pub n_goroutines: u64, - pub name: String, - pub operating_system: String, - // pub RegistryConfig:??? - pub swap_limit: bool, - pub system_time: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ContainerCreateInfo { - pub id: String, - pub warnings: Option>, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct History { - pub id: String, - #[cfg(feature = "chrono")] - #[serde(deserialize_with = "datetime_from_unix_timestamp")] - pub created: DateTime, - #[cfg(not(feature = "chrono"))] - pub created: i64, - pub created_by: String, - pub tags: Option>, - pub size: i64, - pub comment: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Exit { - pub status_code: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Event { - #[serde(rename = "Type")] - pub typ: String, - #[serde(rename = "Action")] - pub action: String, - #[serde(rename = "Actor")] - pub actor: Actor, - pub status: Option, - pub id: Option, - pub from: Option, - #[cfg(feature = "chrono")] - #[serde(deserialize_with = "datetime_from_unix_timestamp")] - pub time: DateTime, - #[cfg(not(feature = "chrono"))] - pub time: u64, - #[cfg(feature = "chrono")] - #[serde(deserialize_with = "datetime_from_nano_timestamp", rename = "timeNano")] - pub time_nano: DateTime, - #[cfg(not(feature = "chrono"))] - #[serde(rename = "timeNano")] - pub time_nano: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ExecDetails { - pub can_remove: bool, - #[serde(rename = "ContainerID")] - pub container_id: String, - pub detach_keys: String, - pub exit_code: Option, - #[serde(rename = "ID")] - pub id: String, - pub open_stderr: bool, - pub open_stdin: bool, - pub open_stdout: bool, - pub process_config: ProcessConfig, - pub running: bool, - pub pid: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct ProcessConfig { - pub arguments: Vec, - pub entrypoint: String, - pub privileged: bool, - pub tty: bool, - pub user: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Actor { - #[serde(rename = "ID")] - pub id: String, - #[serde(rename = "Attributes")] - pub attributes: HashMap, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum Status { - Untagged(String), - Deleted(String), -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct VolumeCreateInfo { - pub name: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Volumes { - pub volumes: Option>, - pub warnings: Option>, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Volume { - #[cfg(feature = "chrono")] - pub created_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub created_at: String, - pub driver: String, - pub labels: Option>, - pub name: String, - pub mountpoint: String, - pub options: Option>, - pub scope: String, -} - -//################################################################################ -// SERVICES -//################################################################################ - -pub type Services = Vec; - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Service { - #[serde(rename = "ID")] - pub id: String, - pub version: ObjectVersion, - #[cfg(feature = "chrono")] - pub created_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub created_at: String, - #[cfg(feature = "chrono")] - pub updated_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub updated_at: String, - pub endpoint: Endpoint, - pub update_status: Option, - pub service_status: Option, - pub job_status: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ObjectVersion { - pub index: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Endpoint { - pub spec: EndpointSpec, - pub ports: Option>, - #[serde(rename = "VirtualIPs")] - pub virtual_ips: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct EndpointSpec { - pub mode: Option, - pub ports: Option>, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct EndpointPortConfig { - pub name: Option, - pub protocol: String, - pub publish_mode: String, - pub published_port: Option, - pub target_port: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct UpdateStatus { - pub state: String, - #[cfg(feature = "chrono")] - pub started_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub started_at: String, - #[cfg(feature = "chrono")] - pub completed_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub completed_at: String, - pub message: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ServiceStatus { - pub running_tasks: u64, - pub desired_tasks: u64, - pub completed_tasks: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct JobStatus { - pub job_iteration: ObjectVersion, - #[cfg(feature = "chrono")] - pub last_execution: DateTime, - #[cfg(not(feature = "chrono"))] - pub last_execution: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ServiceDetails { - #[serde(rename = "ID")] - pub id: String, - pub version: ObjectVersion, - #[cfg(feature = "chrono")] - pub created_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub created_at: String, - #[cfg(feature = "chrono")] - pub updated_at: DateTime, - #[cfg(not(feature = "chrono"))] - pub updated_at: String, - pub spec: ServiceSpec, - pub endpoint: Endpoint, - pub update_status: Option, - pub service_status: Option, - pub job_status: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ServiceSpec { - pub name: String, - pub labels: Option, - pub task_template: TaskSpec, - pub mode: Mode, - pub update_config: Option, - pub rollback_config: Option, - pub networks: Option>, - pub endpoint_spec: EndpointSpec, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -// #TODO: Add missing fields... -pub struct TaskSpec {} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Mode { - pub replicated: Option, - pub global: Option, - pub replicated_job: Option, - pub global_job: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct Replicated { - pub replicas: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct ReplicatedJob { - pub max_concurrent: u64, - pub total_completions: u64, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct UpdateConfig { - pub parallelism: u64, - pub delay: u64, - pub failure_action: String, - pub monitor: u64, - pub max_failure_ratio: usize, - pub order: String, -} - -pub type RollbackConfig = UpdateConfig; - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "PascalCase")] -pub struct NetworkAttachmentConfig { - pub target: String, - pub aliases: Vec, - pub driver_opts: Option, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct ServiceCreateInfo { - #[serde(rename = "ID")] - pub id: String, - #[serde(rename = "Warning")] - pub warning: Option, -} - -//################################################################################ - -#[cfg(feature = "chrono")] -fn datetime_from_unix_timestamp<'de, D>(deserializer: D) -> Result, D::Error> -where - D: serde::Deserializer<'de>, -{ - let timestamp = chrono::NaiveDateTime::from_timestamp(i64::deserialize(deserializer)?, 0); - Ok(DateTime::::from_utc(timestamp, Utc)) -} - -#[cfg(feature = "chrono")] -fn datetime_from_nano_timestamp<'de, D>(deserializer: D) -> Result, D::Error> -where - D: serde::Deserializer<'de>, -{ - let timestamp_nano = u64::deserialize(deserializer)?; - let timestamp = chrono::NaiveDateTime::from_timestamp( - (timestamp_nano / 1_000_000_000) as i64, - (timestamp_nano % 1_000_000_000) as u32, - ); - Ok(DateTime::::from_utc(timestamp, Utc)) -} diff --git a/src/service.rs b/src/service.rs index fd31a51..8a2796b 100644 --- a/src/service.rs +++ b/src/service.rs @@ -6,20 +6,21 @@ use std::{collections::HashMap, iter}; use futures_util::stream::Stream; use hyper::Body; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use url::form_urlencoded; use crate::{ + container::LogsOptions, + docker::Docker, errors::{Error, Result}, image::RegistryAuth, - rep::{ - EndpointSpec, Mode, NetworkAttachmentConfig, RollbackConfig, Service as ServiceInfo, - ServiceCreateInfo, ServiceDetails, TaskSpec, UpdateConfig, - }, - tty, Docker, LogsOptions, + tty, }; +#[cfg(feature = "chrono")] +use chrono::{DateTime, Utc}; + /// Interface for docker services pub struct Services<'docker> { docker: &'docker Docker, @@ -40,7 +41,6 @@ impl<'docker> Services<'docker> { if let Some(query) = opts.serialize() { path.push(query); } - self.docker .get_json::>(&path.join("?")) .await @@ -345,3 +345,180 @@ where { Ok(serde_json::to_value(value)?) } + +pub type ServicesInfo = Vec; + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ServiceInfo { + #[serde(rename = "ID")] + pub id: String, + pub version: ObjectVersion, + #[cfg(feature = "chrono")] + pub created_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub created_at: String, + #[cfg(feature = "chrono")] + pub updated_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub updated_at: String, + pub endpoint: Endpoint, + pub update_status: Option, + pub service_status: Option, + pub job_status: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ObjectVersion { + pub index: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Endpoint { + pub spec: EndpointSpec, + pub ports: Option>, + #[serde(rename = "VirtualIPs")] + pub virtual_ips: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct EndpointSpec { + pub mode: Option, + pub ports: Option>, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct EndpointPortConfig { + pub name: Option, + pub protocol: String, + pub publish_mode: String, + pub published_port: Option, + pub target_port: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct UpdateStatus { + pub state: String, + #[cfg(feature = "chrono")] + pub started_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub started_at: String, + #[cfg(feature = "chrono")] + pub completed_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub completed_at: String, + pub message: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ServiceStatus { + pub running_tasks: u64, + pub desired_tasks: u64, + pub completed_tasks: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct JobStatus { + pub job_iteration: ObjectVersion, + #[cfg(feature = "chrono")] + pub last_execution: DateTime, + #[cfg(not(feature = "chrono"))] + pub last_execution: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ServiceDetails { + #[serde(rename = "ID")] + pub id: String, + pub version: ObjectVersion, + #[cfg(feature = "chrono")] + pub created_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub created_at: String, + #[cfg(feature = "chrono")] + pub updated_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub updated_at: String, + pub spec: ServiceSpec, + pub endpoint: Endpoint, + pub update_status: Option, + pub service_status: Option, + pub job_status: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ServiceSpec { + pub name: String, + pub labels: Option, + pub task_template: TaskSpec, + pub mode: Mode, + pub update_config: Option, + pub rollback_config: Option, + pub networks: Option>, + pub endpoint_spec: EndpointSpec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +// #TODO: Add missing fields... +pub struct TaskSpec {} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Mode { + pub replicated: Option, + pub global: Option, + pub replicated_job: Option, + pub global_job: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Replicated { + pub replicas: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ReplicatedJob { + pub max_concurrent: u64, + pub total_completions: u64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct UpdateConfig { + pub parallelism: u64, + pub delay: u64, + pub failure_action: String, + pub monitor: u64, + pub max_failure_ratio: usize, + pub order: String, +} + +pub type RollbackConfig = UpdateConfig; + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct NetworkAttachmentConfig { + pub target: String, + pub aliases: Vec, + pub driver_opts: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ServiceCreateInfo { + #[serde(rename = "ID")] + pub id: String, + #[serde(rename = "Warning")] + pub warning: Option, +} diff --git a/src/volume.rs b/src/volume.rs index 8290e2b..cbd4d91 100644 --- a/src/volume.rs +++ b/src/volume.rs @@ -8,15 +8,17 @@ use std::{ }; use hyper::Body; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use crate::{ errors::{Error, Result}, - rep::{Volume as VolumeRep, VolumeCreateInfo, Volumes as VolumesRep}, Docker, }; +#[cfg(feature = "chrono")] +use chrono::{DateTime, Utc}; + /// Interface for docker volumes pub struct Volumes<'docker> { docker: &'docker Docker, @@ -41,10 +43,10 @@ impl<'docker> Volumes<'docker> { } /// Lists the docker volumes on the current docker host - pub async fn list(&self) -> Result> { + pub async fn list(&self) -> Result> { let path = vec!["/volumes".to_owned()]; - let volumes_rep = self.docker.get_json::(&path.join("?")).await?; + let volumes_rep = self.docker.get_json::(&path.join("?")).await?; Ok(match volumes_rep.volumes { Some(volumes) => volumes, None => vec![], @@ -158,3 +160,31 @@ impl VolumeCreateOptionsBuilder { } } } + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct VolumeCreateInfo { + pub name: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct VolumesInfo { + pub volumes: Option>, + pub warnings: Option>, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct VolumeInfo { + #[cfg(feature = "chrono")] + pub created_at: DateTime, + #[cfg(not(feature = "chrono"))] + pub created_at: String, + pub driver: String, + pub labels: Option>, + pub name: String, + pub mountpoint: String, + pub options: Option>, + pub scope: String, +} -- cgit v1.2.3