diff --git a/Cargo.lock b/Cargo.lock index 8af8478..ab191d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,9 +129,9 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bollard" -version = "0.18.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ccca1260af6a459d75994ad5acc1651bcabcbdbc41467cc9786519ab854c30" +checksum = "899ca34eb6924d6ec2a77c6f7f5c7339e60fd68235eaf91edd5a15f12958bb06" dependencies = [ "base64", "bollard-stubs", @@ -162,11 +162,12 @@ dependencies = [ [[package]] name = "bollard-stubs" -version = "1.47.1-rc.27.3.1" +version = "1.48.3-rc.28.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f179cfbddb6e77a5472703d4b30436bff32929c0aa8a9008ecf23d1d3cdd0da" +checksum = "64ea257e555d16a2c01e5593f40b73865cdf12efbceda33c6d14a2d8d1490368" dependencies = [ "serde", + "serde_json", "serde_repr", "serde_with", ] @@ -471,6 +472,12 @@ dependencies = [ "litrs", ] +[[package]] +name = "dyn-clone" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" + [[package]] name = "either" version = "1.15.0" @@ -1017,9 +1024,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.173" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libredox" @@ -1297,9 +1304,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" @@ -1371,6 +1378,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "rustc-demangle" version = "0.1.25" @@ -1415,6 +1442,18 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1498,15 +1537,16 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +checksum = "bf65a400f8f66fb7b0552869ad70157166676db75ed8181f8104ea91cf9d0b42" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", "indexmap 2.9.0", + "schemars", "serde", "serde_derive", "serde_json", @@ -1566,12 +1606,9 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" @@ -1816,9 +1853,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index ee17cf0..1369123 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ similar_names = "allow" [dependencies] anyhow = "1.0" -bollard = "0.18" +bollard = "0.19" cansi = "2.2" clap = { version = "4.5", features = ["color", "derive", "unicode"] } crossterm = "0.29" diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs index 7a0e9bb..7250182 100644 --- a/src/app_data/container_state.rs +++ b/src/app_data/container_state.rs @@ -342,6 +342,54 @@ impl From<(&str, &ContainerStatus)> for State { } } +/// Need status, to check if container is unhealthy or not +impl + From<( + &bollard::secret::ContainerSummaryStateEnum, + &ContainerStatus, + )> for State +{ + fn from( + (input, status): ( + &bollard::secret::ContainerSummaryStateEnum, + &ContainerStatus, + ), + ) -> Self { + match input { + bollard::secret::ContainerSummaryStateEnum::DEAD => Self::Dead, + bollard::secret::ContainerSummaryStateEnum::EXITED => Self::Exited, + bollard::secret::ContainerSummaryStateEnum::PAUSED => Self::Paused, + bollard::secret::ContainerSummaryStateEnum::REMOVING => Self::Removing, + bollard::secret::ContainerSummaryStateEnum::RESTARTING => Self::Restarting, + bollard::secret::ContainerSummaryStateEnum::RUNNING => { + if status.unhealthy() { + Self::Running(RunningState::Unhealthy) + } else { + Self::Running(RunningState::Healthy) + } + } + _ => Self::Unknown, + } + } +} + +/// Again, need status, to check if container is unhealthy or not +impl + From<( + Option<&bollard::secret::ContainerSummaryStateEnum>, + &ContainerStatus, + )> for State +{ + fn from( + (input, status): ( + Option<&bollard::secret::ContainerSummaryStateEnum>, + &ContainerStatus, + ), + ) -> Self { + input.map_or(Self::Unknown, |input| Self::from((input, status))) + } +} + /// Again, need status, to check if container is unhealthy or not impl From<(Option, &ContainerStatus)> for State { fn from((input, status): (Option, &ContainerStatus)) -> Self { @@ -589,7 +637,6 @@ impl Logs { /// Get the logs vec, but instead of cloning to whole vec, only clone items with x of the currently selected index /// Where x is the abs different of the index plus the panel height & a padding /// The rest can be just empty list items - /// TODO test me, pass in 1000 lines of "something", expect response to be different! pub fn to_vec(&self, height: usize, padding: usize) -> Vec> { let current_index = self.logs.state.selected().unwrap_or_default(); self.logs diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs index 943f67d..5fc9f7a 100644 --- a/src/app_data/mod.rs +++ b/src/app_data/mod.rs @@ -882,7 +882,12 @@ impl AppData { .map_or(String::new(), std::clone::Clone::clone), ); - let state = State::from((i.state.as_ref().map_or("dead", |z| z), &status)); + let state = State::from(( + i.state + .as_ref() + .map_or(&bollard::secret::ContainerSummaryStateEnum::DEAD, |z| z), + &status, + )); let image = i .image .as_ref() diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index 499a647..18025f9 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -1,9 +1,7 @@ use bollard::{ Docker, - container::{ - ListContainersOptions, LogsOptions, MemoryStatsStats, RemoveContainerOptions, - StartContainerOptions, Stats, StatsOptions, - }, + query_parameters::{ListContainersOptions, LogsOptions, RemoveContainerOptions, StatsOptions}, + secret::ContainerStatsResponse, service::ContainerSummary, }; use futures_util::StreamExt; @@ -75,31 +73,44 @@ pub struct DockerData { impl DockerData { /// Use docker stats to calculate current cpu usage #[allow(clippy::cast_precision_loss)] - fn calculate_usage(stats: &Stats) -> f64 { + fn calculate_usage(stats: &ContainerStatsResponse) -> f64 { let mut cpu_percentage = 0.0; - let cpu_delta = stats - .cpu_stats - .cpu_usage - .total_usage - .saturating_sub(stats.precpu_stats.cpu_usage.total_usage) - as f64; - if let (Some(cpu_stats_usage), Some(precpu_stats_usage)) = ( - stats.cpu_stats.system_cpu_usage, - stats.precpu_stats.system_cpu_usage, + let total_usage = stats.precpu_stats.as_ref().map_or(0, |i| { + i.cpu_usage + .as_ref() + .map_or(0, |i| i.total_usage.unwrap_or_default()) + }); + + let cpu_delta = stats.cpu_stats.as_ref().map_or(0, |i| { + i.cpu_usage.as_ref().map_or(0, |i| { + i.total_usage + .unwrap_or_default() + .saturating_sub(total_usage) + }) + }) as f64; + + if let (Some(Some(cpu_stats_usage)), Some(Some(precpu_stats_usage))) = ( + stats.cpu_stats.as_ref().map(|i| i.system_cpu_usage), + stats.precpu_stats.as_ref().map(|i| i.system_cpu_usage), ) { let system_delta = cpu_stats_usage.saturating_sub(precpu_stats_usage) as f64; - let online_cpus = stats.cpu_stats.online_cpus.unwrap_or_else(|| { - u64::try_from( - stats - .cpu_stats - .cpu_usage - .percpu_usage - .as_ref() - .map_or(0, std::vec::Vec::len), - ) - .unwrap_or_default() - }) as f64; + let online_cpus = f64::from(stats.cpu_stats.as_ref().map_or(0, |i| { + i.online_cpus.unwrap_or_else(|| { + u32::try_from( + stats + .cpu_stats + .clone() + .unwrap_or_default() + .cpu_usage + .unwrap_or_default() + .percpu_usage + .as_ref() + .map_or(0, std::vec::Vec::len), + ) + .unwrap_or_default() + }) + })); if system_delta > 0.0 && cpu_delta > 0.0 { cpu_percentage = (cpu_delta / system_delta) * online_cpus * 100.0; } @@ -107,6 +118,9 @@ impl DockerData { cpu_percentage } + /// Get a single docker stat in order to update mem and cpu usage + /// don't take &self, so that can tokio::spawn into it's own thread + /// remove if from spawns hashmap when complete /// Get a single docker stat in order to update mem and cpu usage /// don't take &self, so that can tokio::spawn into it's own thread /// remove if from spawns hashmap when complete @@ -128,20 +142,23 @@ impl DockerData { ) .take(1); + // some err here while let Some(Ok(stats)) = stream.next().await { // Memory stats are only collected if the container is alive - is this the behaviour we want? + let (mem_stat, cpu_stats) = if state.is_alive() { - let mem_cache = stats.memory_stats.stats.map_or(0, |i| match i { - MemoryStatsStats::V1(x) => x.inactive_file, - MemoryStatsStats::V2(x) => x.inactive_file, + let mem_cache = stats.memory_stats.as_ref().map_or(&0, |i| { + i.stats + .as_ref() + .map_or(&0, |i| i.get("inactive_file").unwrap_or(&0)) }); ( Some( stats .memory_stats - .usage - .unwrap_or_default() - .saturating_sub(mem_cache), + .as_ref() + .map_or(0, |i| i.usage.unwrap_or_default()) + .saturating_sub(*mem_cache), ), Some(Self::calculate_usage(&stats)), ) @@ -149,26 +166,22 @@ impl DockerData { (None, None) }; - let op_key = stats - .networks - .as_ref() - .and_then(|networks| networks.keys().next().cloned()); - - let (rx, tx) = if let Some(key) = op_key { - stats - .networks - .unwrap_or_default() - .get(&key) - .map_or((0, 0), |f| (f.rx_bytes, f.tx_bytes)) - } else { - (0, 0) - }; + let (rx, tx) = stats.networks.as_ref().map_or((0, 0), |i| { + ( + i.rx_bytes.unwrap_or_default(), + i.tx_bytes.unwrap_or_default(), + ) + }); app_data.lock().update_stats_by_id( id, cpu_stats, mem_stat, - stats.memory_stats.limit.unwrap_or_default(), + stats + .memory_stats + .unwrap_or_default() + .limit + .unwrap_or_default(), rx, tx, ); @@ -203,7 +216,7 @@ impl DockerData { async fn update_all_containers(&self) { let containers = self .docker - .list_containers(Some(ListContainersOptions:: { + .list_containers(Some(ListContainersOptions { all: true, ..Default::default() })) @@ -242,11 +255,11 @@ impl DockerData { spawns: Arc>>>, stderr: bool, ) { - let options = Some(LogsOptions:: { + let options = Some(LogsOptions { stdout: true, stderr, timestamps: true, - since: i64::try_from(since).unwrap_or_default(), + since: i32::try_from(since).unwrap_or_default(), ..Default::default() }); @@ -363,14 +376,31 @@ impl DockerData { .await } DockerCommand::Pause => docker.pause_container(id.get()).await, - DockerCommand::Restart => docker.restart_container(id.get(), None).await, + DockerCommand::Restart => { + docker + .restart_container( + id.get(), + None::, + ) + .await + } DockerCommand::Resume => docker.unpause_container(id.get()).await, DockerCommand::Start => { docker - .start_container(id.get(), None::>) + .start_container( + id.get(), + None::, + ) + .await + } + DockerCommand::Stop => { + docker + .stop_container( + id.get(), + None::, + ) .await } - DockerCommand::Stop => docker.stop_container(id.get(), None).await, } .is_err() { @@ -445,119 +475,73 @@ impl DockerData { #[cfg(test)] #[allow(clippy::float_cmp)] mod tests { - use bollard::container::{ - BlkioStats, CPUStats, CPUUsage, MemoryStats, PidsStats, Stats, StorageStats, ThrottlingData, - }; + + use bollard::secret::{ContainerCpuStats, ContainerCpuUsage}; use super::*; - fn gen_stats() -> Stats { - Stats { - read: String::new(), - preread: String::new(), - num_procs: 1, - pids_stats: PidsStats { - current: None, - limit: None, - }, - network: None, + fn gen_stats() -> ContainerStatsResponse { + ContainerStatsResponse { + read: None, + preread: None, + num_procs: Some(1), + pids_stats: None, networks: None, - memory_stats: MemoryStats { - stats: None, - max_usage: None, - usage: None, - failcnt: None, - limit: None, - commit: None, - commit_peak: None, - commitbytes: None, - commitpeakbytes: None, - privateworkingset: None, - }, - blkio_stats: BlkioStats { - io_service_bytes_recursive: None, - io_serviced_recursive: None, - io_queue_recursive: None, - io_service_time_recursive: None, - io_wait_time_recursive: None, - io_merged_recursive: None, - io_time_recursive: None, - sectors_recursive: None, - }, - cpu_stats: CPUStats { - cpu_usage: CPUUsage { + memory_stats: None, + blkio_stats: None, + cpu_stats: Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![50]), - usage_in_usermode: 10, - total_usage: 100, - usage_in_kernelmode: 20, - }, + usage_in_usermode: Some(10), + total_usage: Some(100), + usage_in_kernelmode: Some(20), + }), system_cpu_usage: Some(400), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }, - precpu_stats: CPUStats { - cpu_usage: CPUUsage { + throttling_data: None, + }), + precpu_stats: Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![50]), - usage_in_usermode: 10, - total_usage: 100, - usage_in_kernelmode: 20, - }, + usage_in_usermode: Some(10), + total_usage: Some(100), + usage_in_kernelmode: Some(20), + }), system_cpu_usage: Some(400), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }, - storage_stats: StorageStats { - read_count_normalized: None, - read_size_bytes: None, - write_count_normalized: None, - write_size_bytes: None, - }, - name: String::new(), - id: String::new(), + throttling_data: None, + }), + storage_stats: None, + name: None, + id: None, } } #[test] fn test_calculate_usage_50() { let mut stats = gen_stats(); - stats.precpu_stats = CPUStats { - cpu_usage: CPUUsage { + stats.precpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![50]), - usage_in_usermode: 10, - total_usage: 100, - usage_in_kernelmode: 20, - }, + usage_in_usermode: Some(10), + total_usage: Some(100), + usage_in_kernelmode: Some(20), + }), system_cpu_usage: Some(400), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - stats.cpu_stats = CPUStats { - cpu_usage: CPUUsage { + throttling_data: None, + }); + stats.cpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![150]), - usage_in_usermode: 20, - total_usage: 150, - usage_in_kernelmode: 30, - }, + usage_in_usermode: Some(20), + total_usage: Some(150), + usage_in_kernelmode: Some(30), + }), system_cpu_usage: Some(500), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; + throttling_data: None, + }); let cpu_percentage = DockerData::calculate_usage(&stats); assert_eq!(50.0, cpu_percentage); } @@ -565,37 +549,28 @@ mod tests { #[test] fn test_calculate_usage_25() { let mut stats = gen_stats(); - stats.precpu_stats = CPUStats { - cpu_usage: CPUUsage { + stats.precpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![50]), - usage_in_usermode: 10, - total_usage: 100, - usage_in_kernelmode: 20, - }, + usage_in_usermode: Some(10), + total_usage: Some(100), + usage_in_kernelmode: Some(20), + }), system_cpu_usage: Some(400), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - stats.cpu_stats = CPUStats { - cpu_usage: CPUUsage { + throttling_data: None, + }); + stats.cpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![75]), - usage_in_usermode: 20, - total_usage: 125, - usage_in_kernelmode: 30, - }, + usage_in_usermode: Some(20), + total_usage: Some(125), + usage_in_kernelmode: Some(30), + }), system_cpu_usage: Some(500), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - + throttling_data: None, + }); let cpu_percentage = DockerData::calculate_usage(&stats); assert_eq!(25.0, cpu_percentage); } @@ -603,38 +578,28 @@ mod tests { #[test] fn test_calculate_usage_75() { let mut stats = gen_stats(); - stats.precpu_stats = CPUStats { - cpu_usage: CPUUsage { + stats.precpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![50]), - usage_in_usermode: 10, - total_usage: 100, - usage_in_kernelmode: 20, - }, + usage_in_usermode: Some(10), + total_usage: Some(100), + usage_in_kernelmode: Some(20), + }), system_cpu_usage: Some(400), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - - stats.cpu_stats = CPUStats { - cpu_usage: CPUUsage { + throttling_data: None, + }); + stats.cpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![175]), - usage_in_usermode: 20, - total_usage: 175, - usage_in_kernelmode: 30, - }, + usage_in_usermode: Some(20), + total_usage: Some(175), + usage_in_kernelmode: Some(30), + }), system_cpu_usage: Some(500), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - + throttling_data: None, + }); let cpu_percentage = DockerData::calculate_usage(&stats); assert_eq!(75.0, cpu_percentage); } @@ -642,36 +607,28 @@ mod tests { #[test] fn test_calculate_usage_100() { let mut stats = gen_stats(); - stats.precpu_stats = CPUStats { - cpu_usage: CPUUsage { + stats.precpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![50]), - usage_in_usermode: 10, - total_usage: 100, - usage_in_kernelmode: 20, - }, + usage_in_usermode: Some(10), + total_usage: Some(100), + usage_in_kernelmode: Some(20), + }), system_cpu_usage: Some(400), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - stats.cpu_stats = CPUStats { - cpu_usage: CPUUsage { + throttling_data: None, + }); + stats.cpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![200]), - usage_in_usermode: 20, - total_usage: 200, - usage_in_kernelmode: 30, - }, + usage_in_usermode: Some(20), + total_usage: Some(200), + usage_in_kernelmode: Some(30), + }), system_cpu_usage: Some(500), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; + throttling_data: None, + }); let cpu_percentage = DockerData::calculate_usage(&stats); assert_eq!(100.0, cpu_percentage); } @@ -679,38 +636,28 @@ mod tests { #[test] fn test_calculate_usage_175() { let mut stats = gen_stats(); - stats.precpu_stats = CPUStats { - cpu_usage: CPUUsage { + stats.precpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![50]), - usage_in_usermode: 10, - total_usage: 100, - usage_in_kernelmode: 20, - }, + usage_in_usermode: Some(10), + total_usage: Some(100), + usage_in_kernelmode: Some(20), + }), system_cpu_usage: Some(400), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - - stats.cpu_stats = CPUStats { - cpu_usage: CPUUsage { + throttling_data: None, + }); + stats.cpu_stats = Some(ContainerCpuStats { + cpu_usage: Some(ContainerCpuUsage { percpu_usage: Some(vec![275]), - usage_in_usermode: 20, - total_usage: 275, - usage_in_kernelmode: 30, - }, + usage_in_usermode: Some(20), + total_usage: Some(275), + usage_in_kernelmode: Some(30), + }), system_cpu_usage: Some(500), online_cpus: Some(1), - throttling_data: ThrottlingData { - periods: 0, - throttled_periods: 0, - throttled_time: 0, - }, - }; - + throttling_data: None, + }); let cpu_percentage = DockerData::calculate_usage(&stats); assert_eq!(175.0, cpu_percentage); } diff --git a/src/input_handler/mod.rs b/src/input_handler/mod.rs index 4abd32d..4c17a9a 100644 --- a/src/input_handler/mod.rs +++ b/src/input_handler/mod.rs @@ -5,7 +5,8 @@ use std::{ time::SystemTime, }; -use bollard::container::LogsOptions; +use bollard::query_parameters::LogsOptions; +// use bollard::container::LogsOptions; use cansi::v3::categorise_text; use crossterm::{ event::{DisableMouseCapture, KeyCode, KeyModifiers, MouseButton, MouseEvent, MouseEventKind}, @@ -187,7 +188,7 @@ impl InputHandler { let path = log_path.join(format!("{name}_{now}.log")); - let options = Some(LogsOptions:: { + let options = Some(LogsOptions { stderr: true, stdout: true, timestamps: args.show_timestamp, diff --git a/src/main.rs b/src/main.rs index 66c642b..64ed988 100644 --- a/src/main.rs +++ b/src/main.rs @@ -149,7 +149,7 @@ async fn main() { #[allow(clippy::unwrap_used)] mod tests { - use std::sync::Arc; + use std::{str::FromStr, sync::Arc}; use bollard::service::{ContainerSummary, Port}; @@ -228,6 +228,7 @@ mod tests { pub fn gen_container_summary(index: usize, state: &str) -> ContainerSummary { ContainerSummary { + image_manifest_descriptor: None, id: Some(format!("{index}")), names: Some(vec![format!("container_{}", index)]), image: Some(format!("image_{index}")), @@ -243,7 +244,7 @@ mod tests { size_rw: None, size_root_fs: None, labels: None, - state: Some(state.to_owned()), + state: Some(bollard::secret::ContainerSummaryStateEnum::from_str(state).unwrap()), status: Some(format!("Up {index} hour")), host_config: None, network_settings: None,