chore: Update to Bollard v0.19.1
This commit is contained in:
Generated
+54
-17
@@ -129,9 +129,9 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bollard"
|
name = "bollard"
|
||||||
version = "0.18.1"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97ccca1260af6a459d75994ad5acc1651bcabcbdbc41467cc9786519ab854c30"
|
checksum = "899ca34eb6924d6ec2a77c6f7f5c7339e60fd68235eaf91edd5a15f12958bb06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bollard-stubs",
|
"bollard-stubs",
|
||||||
@@ -162,11 +162,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bollard-stubs"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f179cfbddb6e77a5472703d4b30436bff32929c0aa8a9008ecf23d1d3cdd0da"
|
checksum = "64ea257e555d16a2c01e5593f40b73865cdf12efbceda33c6d14a2d8d1490368"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
]
|
]
|
||||||
@@ -471,6 +472,12 @@ dependencies = [
|
|||||||
"litrs",
|
"litrs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dyn-clone"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
@@ -1017,9 +1024,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.173"
|
version = "0.2.174"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb"
|
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
@@ -1297,9 +1304,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "r-efi"
|
name = "r-efi"
|
||||||
version = "5.2.0"
|
version = "5.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
@@ -1371,6 +1378,26 @@ dependencies = [
|
|||||||
"thiserror",
|
"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]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.25"
|
version = "0.1.25"
|
||||||
@@ -1415,6 +1442,18 @@ version = "1.0.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
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]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@@ -1498,15 +1537,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_with"
|
name = "serde_with"
|
||||||
version = "3.12.0"
|
version = "3.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa"
|
checksum = "bf65a400f8f66fb7b0552869ad70157166676db75ed8181f8104ea91cf9d0b42"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
"hex",
|
"hex",
|
||||||
"indexmap 1.9.3",
|
"indexmap 1.9.3",
|
||||||
"indexmap 2.9.0",
|
"indexmap 2.9.0",
|
||||||
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -1566,12 +1606,9 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
@@ -1816,9 +1853,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.29"
|
version = "0.1.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
|
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ similar_names = "allow"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
bollard = "0.18"
|
bollard = "0.19"
|
||||||
cansi = "2.2"
|
cansi = "2.2"
|
||||||
clap = { version = "4.5", features = ["color", "derive", "unicode"] }
|
clap = { version = "4.5", features = ["color", "derive", "unicode"] }
|
||||||
crossterm = "0.29"
|
crossterm = "0.29"
|
||||||
|
|||||||
@@ -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
|
/// Again, need status, to check if container is unhealthy or not
|
||||||
impl From<(Option<String>, &ContainerStatus)> for State {
|
impl From<(Option<String>, &ContainerStatus)> for State {
|
||||||
fn from((input, status): (Option<String>, &ContainerStatus)) -> Self {
|
fn from((input, status): (Option<String>, &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
|
/// 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
|
/// Where x is the abs different of the index plus the panel height & a padding
|
||||||
/// The rest can be just empty list items
|
/// 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<ListItem<'static>> {
|
pub fn to_vec(&self, height: usize, padding: usize) -> Vec<ListItem<'static>> {
|
||||||
let current_index = self.logs.state.selected().unwrap_or_default();
|
let current_index = self.logs.state.selected().unwrap_or_default();
|
||||||
self.logs
|
self.logs
|
||||||
|
|||||||
+6
-1
@@ -882,7 +882,12 @@ impl AppData {
|
|||||||
.map_or(String::new(), std::clone::Clone::clone),
|
.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
|
let image = i
|
||||||
.image
|
.image
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
+191
-244
@@ -1,9 +1,7 @@
|
|||||||
use bollard::{
|
use bollard::{
|
||||||
Docker,
|
Docker,
|
||||||
container::{
|
query_parameters::{ListContainersOptions, LogsOptions, RemoveContainerOptions, StatsOptions},
|
||||||
ListContainersOptions, LogsOptions, MemoryStatsStats, RemoveContainerOptions,
|
secret::ContainerStatsResponse,
|
||||||
StartContainerOptions, Stats, StatsOptions,
|
|
||||||
},
|
|
||||||
service::ContainerSummary,
|
service::ContainerSummary,
|
||||||
};
|
};
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
@@ -75,31 +73,44 @@ pub struct DockerData {
|
|||||||
impl DockerData {
|
impl DockerData {
|
||||||
/// Use docker stats to calculate current cpu usage
|
/// Use docker stats to calculate current cpu usage
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
fn calculate_usage(stats: &Stats) -> f64 {
|
fn calculate_usage(stats: &ContainerStatsResponse) -> f64 {
|
||||||
let mut cpu_percentage = 0.0;
|
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)) = (
|
let total_usage = stats.precpu_stats.as_ref().map_or(0, |i| {
|
||||||
stats.cpu_stats.system_cpu_usage,
|
i.cpu_usage
|
||||||
stats.precpu_stats.system_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 system_delta = cpu_stats_usage.saturating_sub(precpu_stats_usage) as f64;
|
||||||
let online_cpus = stats.cpu_stats.online_cpus.unwrap_or_else(|| {
|
let online_cpus = f64::from(stats.cpu_stats.as_ref().map_or(0, |i| {
|
||||||
u64::try_from(
|
i.online_cpus.unwrap_or_else(|| {
|
||||||
stats
|
u32::try_from(
|
||||||
.cpu_stats
|
stats
|
||||||
.cpu_usage
|
.cpu_stats
|
||||||
.percpu_usage
|
.clone()
|
||||||
.as_ref()
|
.unwrap_or_default()
|
||||||
.map_or(0, std::vec::Vec::len),
|
.cpu_usage
|
||||||
)
|
.unwrap_or_default()
|
||||||
.unwrap_or_default()
|
.percpu_usage
|
||||||
}) as f64;
|
.as_ref()
|
||||||
|
.map_or(0, std::vec::Vec::len),
|
||||||
|
)
|
||||||
|
.unwrap_or_default()
|
||||||
|
})
|
||||||
|
}));
|
||||||
if system_delta > 0.0 && cpu_delta > 0.0 {
|
if system_delta > 0.0 && cpu_delta > 0.0 {
|
||||||
cpu_percentage = (cpu_delta / system_delta) * online_cpus * 100.0;
|
cpu_percentage = (cpu_delta / system_delta) * online_cpus * 100.0;
|
||||||
}
|
}
|
||||||
@@ -107,6 +118,9 @@ impl DockerData {
|
|||||||
cpu_percentage
|
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
|
/// 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
|
/// don't take &self, so that can tokio::spawn into it's own thread
|
||||||
/// remove if from spawns hashmap when complete
|
/// remove if from spawns hashmap when complete
|
||||||
@@ -128,20 +142,23 @@ impl DockerData {
|
|||||||
)
|
)
|
||||||
.take(1);
|
.take(1);
|
||||||
|
|
||||||
|
// some err here
|
||||||
while let Some(Ok(stats)) = stream.next().await {
|
while let Some(Ok(stats)) = stream.next().await {
|
||||||
// Memory stats are only collected if the container is alive - is this the behaviour we want?
|
// 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_stat, cpu_stats) = if state.is_alive() {
|
||||||
let mem_cache = stats.memory_stats.stats.map_or(0, |i| match i {
|
let mem_cache = stats.memory_stats.as_ref().map_or(&0, |i| {
|
||||||
MemoryStatsStats::V1(x) => x.inactive_file,
|
i.stats
|
||||||
MemoryStatsStats::V2(x) => x.inactive_file,
|
.as_ref()
|
||||||
|
.map_or(&0, |i| i.get("inactive_file").unwrap_or(&0))
|
||||||
});
|
});
|
||||||
(
|
(
|
||||||
Some(
|
Some(
|
||||||
stats
|
stats
|
||||||
.memory_stats
|
.memory_stats
|
||||||
.usage
|
.as_ref()
|
||||||
.unwrap_or_default()
|
.map_or(0, |i| i.usage.unwrap_or_default())
|
||||||
.saturating_sub(mem_cache),
|
.saturating_sub(*mem_cache),
|
||||||
),
|
),
|
||||||
Some(Self::calculate_usage(&stats)),
|
Some(Self::calculate_usage(&stats)),
|
||||||
)
|
)
|
||||||
@@ -149,26 +166,22 @@ impl DockerData {
|
|||||||
(None, None)
|
(None, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let op_key = stats
|
let (rx, tx) = stats.networks.as_ref().map_or((0, 0), |i| {
|
||||||
.networks
|
(
|
||||||
.as_ref()
|
i.rx_bytes.unwrap_or_default(),
|
||||||
.and_then(|networks| networks.keys().next().cloned());
|
i.tx_bytes.unwrap_or_default(),
|
||||||
|
)
|
||||||
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)
|
|
||||||
};
|
|
||||||
|
|
||||||
app_data.lock().update_stats_by_id(
|
app_data.lock().update_stats_by_id(
|
||||||
id,
|
id,
|
||||||
cpu_stats,
|
cpu_stats,
|
||||||
mem_stat,
|
mem_stat,
|
||||||
stats.memory_stats.limit.unwrap_or_default(),
|
stats
|
||||||
|
.memory_stats
|
||||||
|
.unwrap_or_default()
|
||||||
|
.limit
|
||||||
|
.unwrap_or_default(),
|
||||||
rx,
|
rx,
|
||||||
tx,
|
tx,
|
||||||
);
|
);
|
||||||
@@ -203,7 +216,7 @@ impl DockerData {
|
|||||||
async fn update_all_containers(&self) {
|
async fn update_all_containers(&self) {
|
||||||
let containers = self
|
let containers = self
|
||||||
.docker
|
.docker
|
||||||
.list_containers(Some(ListContainersOptions::<String> {
|
.list_containers(Some(ListContainersOptions {
|
||||||
all: true,
|
all: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
@@ -242,11 +255,11 @@ impl DockerData {
|
|||||||
spawns: Arc<Mutex<HashMap<SpawnId, JoinHandle<()>>>>,
|
spawns: Arc<Mutex<HashMap<SpawnId, JoinHandle<()>>>>,
|
||||||
stderr: bool,
|
stderr: bool,
|
||||||
) {
|
) {
|
||||||
let options = Some(LogsOptions::<String> {
|
let options = Some(LogsOptions {
|
||||||
stdout: true,
|
stdout: true,
|
||||||
stderr,
|
stderr,
|
||||||
timestamps: true,
|
timestamps: true,
|
||||||
since: i64::try_from(since).unwrap_or_default(),
|
since: i32::try_from(since).unwrap_or_default(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -363,14 +376,31 @@ impl DockerData {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
DockerCommand::Pause => docker.pause_container(id.get()).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::<bollard::query_parameters::RestartContainerOptions>,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
DockerCommand::Resume => docker.unpause_container(id.get()).await,
|
DockerCommand::Resume => docker.unpause_container(id.get()).await,
|
||||||
DockerCommand::Start => {
|
DockerCommand::Start => {
|
||||||
docker
|
docker
|
||||||
.start_container(id.get(), None::<StartContainerOptions<String>>)
|
.start_container(
|
||||||
|
id.get(),
|
||||||
|
None::<bollard::query_parameters::StartContainerOptions>,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
DockerCommand::Stop => {
|
||||||
|
docker
|
||||||
|
.stop_container(
|
||||||
|
id.get(),
|
||||||
|
None::<bollard::query_parameters::StopContainerOptions>,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
DockerCommand::Stop => docker.stop_container(id.get(), None).await,
|
|
||||||
}
|
}
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
@@ -445,119 +475,73 @@ impl DockerData {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::float_cmp)]
|
#[allow(clippy::float_cmp)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use bollard::container::{
|
|
||||||
BlkioStats, CPUStats, CPUUsage, MemoryStats, PidsStats, Stats, StorageStats, ThrottlingData,
|
use bollard::secret::{ContainerCpuStats, ContainerCpuUsage};
|
||||||
};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn gen_stats() -> Stats {
|
fn gen_stats() -> ContainerStatsResponse {
|
||||||
Stats {
|
ContainerStatsResponse {
|
||||||
read: String::new(),
|
read: None,
|
||||||
preread: String::new(),
|
preread: None,
|
||||||
num_procs: 1,
|
num_procs: Some(1),
|
||||||
pids_stats: PidsStats {
|
pids_stats: None,
|
||||||
current: None,
|
|
||||||
limit: None,
|
|
||||||
},
|
|
||||||
network: None,
|
|
||||||
networks: None,
|
networks: None,
|
||||||
memory_stats: MemoryStats {
|
memory_stats: None,
|
||||||
stats: None,
|
blkio_stats: None,
|
||||||
max_usage: None,
|
cpu_stats: Some(ContainerCpuStats {
|
||||||
usage: None,
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
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 {
|
|
||||||
percpu_usage: Some(vec![50]),
|
percpu_usage: Some(vec![50]),
|
||||||
usage_in_usermode: 10,
|
usage_in_usermode: Some(10),
|
||||||
total_usage: 100,
|
total_usage: Some(100),
|
||||||
usage_in_kernelmode: 20,
|
usage_in_kernelmode: Some(20),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(400),
|
system_cpu_usage: Some(400),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
}),
|
||||||
throttled_periods: 0,
|
precpu_stats: Some(ContainerCpuStats {
|
||||||
throttled_time: 0,
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
},
|
|
||||||
},
|
|
||||||
precpu_stats: CPUStats {
|
|
||||||
cpu_usage: CPUUsage {
|
|
||||||
percpu_usage: Some(vec![50]),
|
percpu_usage: Some(vec![50]),
|
||||||
usage_in_usermode: 10,
|
usage_in_usermode: Some(10),
|
||||||
total_usage: 100,
|
total_usage: Some(100),
|
||||||
usage_in_kernelmode: 20,
|
usage_in_kernelmode: Some(20),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(400),
|
system_cpu_usage: Some(400),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
}),
|
||||||
throttled_periods: 0,
|
storage_stats: None,
|
||||||
throttled_time: 0,
|
name: None,
|
||||||
},
|
id: None,
|
||||||
},
|
|
||||||
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(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_usage_50() {
|
fn test_calculate_usage_50() {
|
||||||
let mut stats = gen_stats();
|
let mut stats = gen_stats();
|
||||||
stats.precpu_stats = CPUStats {
|
stats.precpu_stats = Some(ContainerCpuStats {
|
||||||
cpu_usage: CPUUsage {
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
percpu_usage: Some(vec![50]),
|
percpu_usage: Some(vec![50]),
|
||||||
usage_in_usermode: 10,
|
usage_in_usermode: Some(10),
|
||||||
total_usage: 100,
|
total_usage: Some(100),
|
||||||
usage_in_kernelmode: 20,
|
usage_in_kernelmode: Some(20),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(400),
|
system_cpu_usage: Some(400),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
stats.cpu_stats = Some(ContainerCpuStats {
|
||||||
throttled_time: 0,
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
},
|
|
||||||
};
|
|
||||||
stats.cpu_stats = CPUStats {
|
|
||||||
cpu_usage: CPUUsage {
|
|
||||||
percpu_usage: Some(vec![150]),
|
percpu_usage: Some(vec![150]),
|
||||||
usage_in_usermode: 20,
|
usage_in_usermode: Some(20),
|
||||||
total_usage: 150,
|
total_usage: Some(150),
|
||||||
usage_in_kernelmode: 30,
|
usage_in_kernelmode: Some(30),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(500),
|
system_cpu_usage: Some(500),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
|
||||||
throttled_time: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let cpu_percentage = DockerData::calculate_usage(&stats);
|
let cpu_percentage = DockerData::calculate_usage(&stats);
|
||||||
assert_eq!(50.0, cpu_percentage);
|
assert_eq!(50.0, cpu_percentage);
|
||||||
}
|
}
|
||||||
@@ -565,37 +549,28 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_usage_25() {
|
fn test_calculate_usage_25() {
|
||||||
let mut stats = gen_stats();
|
let mut stats = gen_stats();
|
||||||
stats.precpu_stats = CPUStats {
|
stats.precpu_stats = Some(ContainerCpuStats {
|
||||||
cpu_usage: CPUUsage {
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
percpu_usage: Some(vec![50]),
|
percpu_usage: Some(vec![50]),
|
||||||
usage_in_usermode: 10,
|
usage_in_usermode: Some(10),
|
||||||
total_usage: 100,
|
total_usage: Some(100),
|
||||||
usage_in_kernelmode: 20,
|
usage_in_kernelmode: Some(20),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(400),
|
system_cpu_usage: Some(400),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
stats.cpu_stats = Some(ContainerCpuStats {
|
||||||
throttled_time: 0,
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
},
|
|
||||||
};
|
|
||||||
stats.cpu_stats = CPUStats {
|
|
||||||
cpu_usage: CPUUsage {
|
|
||||||
percpu_usage: Some(vec![75]),
|
percpu_usage: Some(vec![75]),
|
||||||
usage_in_usermode: 20,
|
usage_in_usermode: Some(20),
|
||||||
total_usage: 125,
|
total_usage: Some(125),
|
||||||
usage_in_kernelmode: 30,
|
usage_in_kernelmode: Some(30),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(500),
|
system_cpu_usage: Some(500),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
|
||||||
throttled_time: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let cpu_percentage = DockerData::calculate_usage(&stats);
|
let cpu_percentage = DockerData::calculate_usage(&stats);
|
||||||
assert_eq!(25.0, cpu_percentage);
|
assert_eq!(25.0, cpu_percentage);
|
||||||
}
|
}
|
||||||
@@ -603,38 +578,28 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_usage_75() {
|
fn test_calculate_usage_75() {
|
||||||
let mut stats = gen_stats();
|
let mut stats = gen_stats();
|
||||||
stats.precpu_stats = CPUStats {
|
stats.precpu_stats = Some(ContainerCpuStats {
|
||||||
cpu_usage: CPUUsage {
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
percpu_usage: Some(vec![50]),
|
percpu_usage: Some(vec![50]),
|
||||||
usage_in_usermode: 10,
|
usage_in_usermode: Some(10),
|
||||||
total_usage: 100,
|
total_usage: Some(100),
|
||||||
usage_in_kernelmode: 20,
|
usage_in_kernelmode: Some(20),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(400),
|
system_cpu_usage: Some(400),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
stats.cpu_stats = Some(ContainerCpuStats {
|
||||||
throttled_time: 0,
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
stats.cpu_stats = CPUStats {
|
|
||||||
cpu_usage: CPUUsage {
|
|
||||||
percpu_usage: Some(vec![175]),
|
percpu_usage: Some(vec![175]),
|
||||||
usage_in_usermode: 20,
|
usage_in_usermode: Some(20),
|
||||||
total_usage: 175,
|
total_usage: Some(175),
|
||||||
usage_in_kernelmode: 30,
|
usage_in_kernelmode: Some(30),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(500),
|
system_cpu_usage: Some(500),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
|
||||||
throttled_time: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let cpu_percentage = DockerData::calculate_usage(&stats);
|
let cpu_percentage = DockerData::calculate_usage(&stats);
|
||||||
assert_eq!(75.0, cpu_percentage);
|
assert_eq!(75.0, cpu_percentage);
|
||||||
}
|
}
|
||||||
@@ -642,36 +607,28 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_usage_100() {
|
fn test_calculate_usage_100() {
|
||||||
let mut stats = gen_stats();
|
let mut stats = gen_stats();
|
||||||
stats.precpu_stats = CPUStats {
|
stats.precpu_stats = Some(ContainerCpuStats {
|
||||||
cpu_usage: CPUUsage {
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
percpu_usage: Some(vec![50]),
|
percpu_usage: Some(vec![50]),
|
||||||
usage_in_usermode: 10,
|
usage_in_usermode: Some(10),
|
||||||
total_usage: 100,
|
total_usage: Some(100),
|
||||||
usage_in_kernelmode: 20,
|
usage_in_kernelmode: Some(20),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(400),
|
system_cpu_usage: Some(400),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
stats.cpu_stats = Some(ContainerCpuStats {
|
||||||
throttled_time: 0,
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
},
|
|
||||||
};
|
|
||||||
stats.cpu_stats = CPUStats {
|
|
||||||
cpu_usage: CPUUsage {
|
|
||||||
percpu_usage: Some(vec![200]),
|
percpu_usage: Some(vec![200]),
|
||||||
usage_in_usermode: 20,
|
usage_in_usermode: Some(20),
|
||||||
total_usage: 200,
|
total_usage: Some(200),
|
||||||
usage_in_kernelmode: 30,
|
usage_in_kernelmode: Some(30),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(500),
|
system_cpu_usage: Some(500),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
|
||||||
throttled_time: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let cpu_percentage = DockerData::calculate_usage(&stats);
|
let cpu_percentage = DockerData::calculate_usage(&stats);
|
||||||
assert_eq!(100.0, cpu_percentage);
|
assert_eq!(100.0, cpu_percentage);
|
||||||
}
|
}
|
||||||
@@ -679,38 +636,28 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_usage_175() {
|
fn test_calculate_usage_175() {
|
||||||
let mut stats = gen_stats();
|
let mut stats = gen_stats();
|
||||||
stats.precpu_stats = CPUStats {
|
stats.precpu_stats = Some(ContainerCpuStats {
|
||||||
cpu_usage: CPUUsage {
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
percpu_usage: Some(vec![50]),
|
percpu_usage: Some(vec![50]),
|
||||||
usage_in_usermode: 10,
|
usage_in_usermode: Some(10),
|
||||||
total_usage: 100,
|
total_usage: Some(100),
|
||||||
usage_in_kernelmode: 20,
|
usage_in_kernelmode: Some(20),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(400),
|
system_cpu_usage: Some(400),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
stats.cpu_stats = Some(ContainerCpuStats {
|
||||||
throttled_time: 0,
|
cpu_usage: Some(ContainerCpuUsage {
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
stats.cpu_stats = CPUStats {
|
|
||||||
cpu_usage: CPUUsage {
|
|
||||||
percpu_usage: Some(vec![275]),
|
percpu_usage: Some(vec![275]),
|
||||||
usage_in_usermode: 20,
|
usage_in_usermode: Some(20),
|
||||||
total_usage: 275,
|
total_usage: Some(275),
|
||||||
usage_in_kernelmode: 30,
|
usage_in_kernelmode: Some(30),
|
||||||
},
|
}),
|
||||||
system_cpu_usage: Some(500),
|
system_cpu_usage: Some(500),
|
||||||
online_cpus: Some(1),
|
online_cpus: Some(1),
|
||||||
throttling_data: ThrottlingData {
|
throttling_data: None,
|
||||||
periods: 0,
|
});
|
||||||
throttled_periods: 0,
|
|
||||||
throttled_time: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let cpu_percentage = DockerData::calculate_usage(&stats);
|
let cpu_percentage = DockerData::calculate_usage(&stats);
|
||||||
assert_eq!(175.0, cpu_percentage);
|
assert_eq!(175.0, cpu_percentage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ use std::{
|
|||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bollard::container::LogsOptions;
|
use bollard::query_parameters::LogsOptions;
|
||||||
|
// use bollard::container::LogsOptions;
|
||||||
use cansi::v3::categorise_text;
|
use cansi::v3::categorise_text;
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::{DisableMouseCapture, KeyCode, KeyModifiers, MouseButton, MouseEvent, MouseEventKind},
|
event::{DisableMouseCapture, KeyCode, KeyModifiers, MouseButton, MouseEvent, MouseEventKind},
|
||||||
@@ -187,7 +188,7 @@ impl InputHandler {
|
|||||||
|
|
||||||
let path = log_path.join(format!("{name}_{now}.log"));
|
let path = log_path.join(format!("{name}_{now}.log"));
|
||||||
|
|
||||||
let options = Some(LogsOptions::<String> {
|
let options = Some(LogsOptions {
|
||||||
stderr: true,
|
stderr: true,
|
||||||
stdout: true,
|
stdout: true,
|
||||||
timestamps: args.show_timestamp,
|
timestamps: args.show_timestamp,
|
||||||
|
|||||||
+3
-2
@@ -149,7 +149,7 @@ async fn main() {
|
|||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::{str::FromStr, sync::Arc};
|
||||||
|
|
||||||
use bollard::service::{ContainerSummary, Port};
|
use bollard::service::{ContainerSummary, Port};
|
||||||
|
|
||||||
@@ -228,6 +228,7 @@ mod tests {
|
|||||||
|
|
||||||
pub fn gen_container_summary(index: usize, state: &str) -> ContainerSummary {
|
pub fn gen_container_summary(index: usize, state: &str) -> ContainerSummary {
|
||||||
ContainerSummary {
|
ContainerSummary {
|
||||||
|
image_manifest_descriptor: None,
|
||||||
id: Some(format!("{index}")),
|
id: Some(format!("{index}")),
|
||||||
names: Some(vec![format!("container_{}", index)]),
|
names: Some(vec![format!("container_{}", index)]),
|
||||||
image: Some(format!("image_{index}")),
|
image: Some(format!("image_{index}")),
|
||||||
@@ -243,7 +244,7 @@ mod tests {
|
|||||||
size_rw: None,
|
size_rw: None,
|
||||||
size_root_fs: None,
|
size_root_fs: None,
|
||||||
labels: None,
|
labels: None,
|
||||||
state: Some(state.to_owned()),
|
state: Some(bollard::secret::ContainerSummaryStateEnum::from_str(state).unwrap()),
|
||||||
status: Some(format!("Up {index} hour")),
|
status: Some(format!("Up {index} hour")),
|
||||||
host_config: None,
|
host_config: None,
|
||||||
network_settings: None,
|
network_settings: None,
|
||||||
|
|||||||
Reference in New Issue
Block a user