From eac7db091f65ffeff05cd08a11fd5c83a8ceea41 Mon Sep 17 00:00:00 2001 From: Lucy C <12953208+elvece@users.noreply.github.com> Date: Fri, 5 Nov 2021 16:03:43 -0600 Subject: [PATCH] Bugfix/disk info (#770) * use df for getting disk info * fix import * fix type errors * add duplicity flag for different source hosts * fix borrow * reorder args * update cargo lock * use 1byte block sizes and using floating point numbers --- appmgr/src/disk/util.rs | 52 +++++++++++++++--- appmgr/src/system.rs | 85 ++++++++++-------------------- system-images/compat/Cargo.lock | 45 ++++++++++++++++ system-images/compat/src/backup.rs | 6 ++- 4 files changed, 121 insertions(+), 67 deletions(-) diff --git a/appmgr/src/disk/util.rs b/appmgr/src/disk/util.rs index 429dee2c9..ab923ae35 100644 --- a/appmgr/src/disk/util.rs +++ b/appmgr/src/disk/util.rs @@ -40,7 +40,7 @@ pub struct DiskInfo { pub vendor: Option, pub model: Option, pub partitions: Vec, - pub capacity: usize, + pub capacity: u64, pub guid: Option, } @@ -49,8 +49,8 @@ pub struct DiskInfo { pub struct PartitionInfo { pub logicalname: PathBuf, pub label: Option, - pub capacity: usize, - pub used: Option, + pub capacity: u64, + pub used: Option, pub embassy_os: Option, } @@ -109,7 +109,7 @@ pub async fn get_model>(path: P) -> Result, Error> } #[instrument(skip(path))] -pub async fn get_capacity>(path: P) -> Result { +pub async fn get_capacity>(path: P) -> Result { Ok(String::from_utf8( Command::new("blockdev") .arg("--getsize64") @@ -118,7 +118,7 @@ pub async fn get_capacity>(path: P) -> Result { .await?, )? .trim() - .parse()?) + .parse::()?) } #[instrument(skip(path))] @@ -137,10 +137,11 @@ pub async fn get_label>(path: P) -> Result, Error> } #[instrument(skip(path))] -pub async fn get_used>(path: P) -> Result { +pub async fn get_used>(path: P) -> Result { Ok(String::from_utf8( Command::new("df") .arg("--output=used") + .arg("--block-size=1") .arg(path.as_ref()) .invoke(crate::ErrorKind::Filesystem) .await?, @@ -150,7 +151,44 @@ pub async fn get_used>(path: P) -> Result { .next() .unwrap_or_default() .trim() - .parse()?) + .parse::()?) +} + +#[instrument(skip(path))] +pub async fn get_available>(path: P) -> Result { + Ok(String::from_utf8( + Command::new("df") + .arg("--output=avail") + .arg("--block-size=1") + .arg(path.as_ref()) + .invoke(crate::ErrorKind::Filesystem) + .await?, + )? + .lines() + .skip(1) + .next() + .unwrap_or_default() + .trim() + .parse::()?) +} + +#[instrument(skip(path))] +pub async fn get_percentage>(path: P) -> Result { + Ok(String::from_utf8( + Command::new("df") + .arg("--output=pcent") + .arg(path.as_ref()) + .invoke(crate::ErrorKind::Filesystem) + .await?, + )? + .lines() + .skip(1) + .next() + .unwrap_or_default() + .trim() + .strip_suffix("%") + .unwrap() + .parse::()?) } pub async fn pvscan() -> Result>, Error> { diff --git a/appmgr/src/system.rs b/appmgr/src/system.rs index 5cb2a1c3a..c443b316a 100644 --- a/appmgr/src/system.rs +++ b/appmgr/src/system.rs @@ -9,6 +9,7 @@ use tracing::instrument; use crate::context::RpcContext; use crate::db::util::WithRevision; +use crate::disk::util::{get_available, get_percentage, get_used}; use crate::logs::{display_logs, fetch_logs, LogResponse, LogSource}; use crate::shutdown::Shutdown; use crate::util::{display_none, display_serializable, IoFormat}; @@ -601,65 +602,33 @@ async fn get_mem_info() -> Result { #[instrument] async fn get_disk_info() -> Result { - use crate::util::Invoke; - let mut size_cmd = tokio::process::Command::new("zpool"); - let size_task = size_cmd - .arg("list") - .arg("-Hp") - .arg("-o") - .arg("size") - .arg("embassy-data") - .invoke(ErrorKind::ParseSysInfo); - let mut alloc_cmd = tokio::process::Command::new("zpool"); - let alloc_task = alloc_cmd - .arg("list") - .arg("-Hp") - .arg("-o") - .arg("allocated") - .arg("embassy-data") - .invoke(ErrorKind::ParseSysInfo); - let mut free_cmd = tokio::process::Command::new("zpool"); - let free_task = free_cmd - .arg("list") - .arg("-Hp") - .arg("-o") - .arg("free") - .arg("embassy-data") - .invoke(ErrorKind::ParseSysInfo); - let (size_bytes, alloc_bytes, free_bytes) = - futures::try_join!(size_task, alloc_task, free_task)?; - let size = String::from_utf8(size_bytes)? - .trim() - .parse::() - .map_err(|e| { - Error::new( - color_eyre::eyre::eyre!("Could not parse disk size: {}", e), - ErrorKind::ParseSysInfo, - ) - })?; - let alloc = String::from_utf8(alloc_bytes)? - .trim() - .parse::() - .map_err(|e| { - Error::new( - color_eyre::eyre::eyre!("Could not parse disk alloc: {}", e), - ErrorKind::ParseSysInfo, - ) - })?; - let free = String::from_utf8(free_bytes)? - .trim() - .parse::() - .map_err(|e| { - Error::new( - color_eyre::eyre::eyre!("Could not parse disk alloc: {}", e), - ErrorKind::ParseSysInfo, - ) - })?; + let package_used_task = get_used("/embassy-data/package-data"); + let package_available_task = get_available("/embassy-data/package-data"); + let package_percentage_task = get_percentage("/embassy-data/package-data"); + let os_used_task = get_used("/embassy-data/main"); + let os_available_task = get_available("/embassy-data/main"); + let os_percentage_task = get_percentage("/embassy-data/main"); + + let (package_used, package_available, package_percentage, os_used, os_available, os_percentage) = + futures::try_join!( + package_used_task, + package_available_task, + package_percentage_task, + os_used_task, + os_available_task, + os_percentage_task, + )?; + + let total_used = package_used + os_used; + let total_available = package_available + os_available; + let total_percentage = package_percentage + os_percentage; + let total_size = total_used + total_available; + Ok(MetricsDisk { - size: GigaBytes(size / 1_000_000_000.0), - used: GigaBytes(alloc / 1_000_000_000.0), - available: GigaBytes(free / 1_000_000_000.0), - used_percentage: Percentage(alloc / size * 100.0), + size: GigaBytes(total_size as f64 / 1_000_000_000.0), + used: GigaBytes(total_used as f64 / 1_000_000_000.0), + available: GigaBytes(total_available as f64 / 1_000_000_000.0), + used_percentage: Percentage(total_percentage as f64), }) } diff --git a/system-images/compat/Cargo.lock b/system-images/compat/Cargo.lock index ad620478a..303ee8933 100644 --- a/system-images/compat/Cargo.lock +++ b/system-images/compat/Cargo.lock @@ -709,6 +709,17 @@ dependencies = [ "syn 1.0.76", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.29", + "quote 1.0.9", + "syn 1.0.76", +] + [[package]] name = "derive_more" version = "0.99.16" @@ -870,7 +881,9 @@ dependencies = [ "libc", "log", "nix 0.23.0", + "nom 7.0.0", "num", + "num_enum", "openssh-keys", "openssl", "patch-db", @@ -1937,6 +1950,28 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" +dependencies = [ + "derivative", + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.29", + "quote 1.0.9", + "syn 1.0.76", +] + [[package]] name = "object" version = "0.26.2" @@ -2258,6 +2293,16 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" diff --git a/system-images/compat/src/backup.rs b/system-images/compat/src/backup.rs index 146455c83..2899b52fb 100644 --- a/system-images/compat/src/backup.rs +++ b/system-images/compat/src/backup.rs @@ -24,18 +24,19 @@ pub fn create_backup( data_path .join(exclude.to_string().trim_start_matches('!')) .display() - )); + )).arg("--allow-source-mismatch"); } else { data_cmd.arg(format!( "--exclude={}", data_path.join(exclude.to_string()).display() - )); + )).arg("--allow-source-mismatch"); } } let data_output = data_cmd .env("PASSPHRASE", DEFAULT_PASSWORD) .arg(data_path) .arg(format!("file://{}", mountpoint.display().to_string())) + .arg("--allow-source-mismatch") .stderr(Stdio::piped()) .output()?; if !data_output.status.success() { @@ -56,6 +57,7 @@ pub fn restore_backup( let data_path = std::fs::canonicalize(data_path)?; let data_output = std::process::Command::new("duplicity") + .arg("--allow-source-mismatch") .env("PASSPHRASE", DEFAULT_PASSWORD) .arg("--force") .arg(format!("file://{}", mountpoint.display().to_string()))