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
This commit is contained in:
Lucy C
2021-11-05 16:03:43 -06:00
committed by Aiden McClelland
parent 44324b7127
commit eac7db091f
4 changed files with 121 additions and 67 deletions

View File

@@ -40,7 +40,7 @@ pub struct DiskInfo {
pub vendor: Option<String>,
pub model: Option<String>,
pub partitions: Vec<PartitionInfo>,
pub capacity: usize,
pub capacity: u64,
pub guid: Option<String>,
}
@@ -49,8 +49,8 @@ pub struct DiskInfo {
pub struct PartitionInfo {
pub logicalname: PathBuf,
pub label: Option<String>,
pub capacity: usize,
pub used: Option<usize>,
pub capacity: u64,
pub used: Option<u64>,
pub embassy_os: Option<EmbassyOsRecoveryInfo>,
}
@@ -109,7 +109,7 @@ pub async fn get_model<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error>
}
#[instrument(skip(path))]
pub async fn get_capacity<P: AsRef<Path>>(path: P) -> Result<usize, Error> {
pub async fn get_capacity<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
Ok(String::from_utf8(
Command::new("blockdev")
.arg("--getsize64")
@@ -118,7 +118,7 @@ pub async fn get_capacity<P: AsRef<Path>>(path: P) -> Result<usize, Error> {
.await?,
)?
.trim()
.parse()?)
.parse::<u64>()?)
}
#[instrument(skip(path))]
@@ -137,10 +137,11 @@ pub async fn get_label<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error>
}
#[instrument(skip(path))]
pub async fn get_used<P: AsRef<Path>>(path: P) -> Result<usize, Error> {
pub async fn get_used<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
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<P: AsRef<Path>>(path: P) -> Result<usize, Error> {
.next()
.unwrap_or_default()
.trim()
.parse()?)
.parse::<u64>()?)
}
#[instrument(skip(path))]
pub async fn get_available<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
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::<u64>()?)
}
#[instrument(skip(path))]
pub async fn get_percentage<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
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::<u64>()?)
}
pub async fn pvscan() -> Result<BTreeMap<PathBuf, Option<String>>, Error> {

View File

@@ -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<MetricsMemory, Error> {
#[instrument]
async fn get_disk_info() -> Result<MetricsDisk, Error> {
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::<f64>()
.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::<f64>()
.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::<f64>()
.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),
})
}

View File

@@ -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"

View File

@@ -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()))