Display disk serial numbers instead of device names
All checks were successful
Build and Release / build-and-release (push) Successful in 1m18s
All checks were successful
Build and Release / build-and-release (push) Successful in 1m18s
- Add serial_number field to DriveData structure - Collect serial numbers from SMART data for all drives - Display truncated serial numbers (last 8 chars) in dashboard - Fix parity drive label to show status icon before "Parity:" - Fix mount point label styling to match other labels
This commit is contained in:
parent
c9d12793ef
commit
dc1105eefe
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cm-dashboard"
|
name = "cm-dashboard"
|
||||||
version = "0.1.154"
|
version = "0.1.155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -301,7 +301,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cm-dashboard-agent"
|
name = "cm-dashboard-agent"
|
||||||
version = "0.1.154"
|
version = "0.1.155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -324,7 +324,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cm-dashboard-shared"
|
name = "cm-dashboard-shared"
|
||||||
version = "0.1.154"
|
version = "0.1.155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cm-dashboard-agent"
|
name = "cm-dashboard-agent"
|
||||||
version = "0.1.154"
|
version = "0.1.155"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -534,6 +534,7 @@ impl DiskCollector {
|
|||||||
|
|
||||||
agent_data.system.storage.drives.push(DriveData {
|
agent_data.system.storage.drives.push(DriveData {
|
||||||
name: drive.name.clone(),
|
name: drive.name.clone(),
|
||||||
|
serial_number: smart.and_then(|s| s.serial_number.clone()),
|
||||||
health: smart.map(|s| s.health.clone()).unwrap_or_else(|| drive.health.clone()),
|
health: smart.map(|s| s.health.clone()).unwrap_or_else(|| drive.health.clone()),
|
||||||
temperature_celsius: smart.and_then(|s| s.temperature_celsius),
|
temperature_celsius: smart.and_then(|s| s.temperature_celsius),
|
||||||
wear_percent: smart.and_then(|s| s.wear_percent),
|
wear_percent: smart.and_then(|s| s.wear_percent),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cm-dashboard"
|
name = "cm-dashboard"
|
||||||
version = "0.1.154"
|
version = "0.1.155"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -239,8 +239,11 @@ impl SystemWidget {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Add drive info
|
// Add drive info
|
||||||
|
let display_name = drive.serial_number.as_ref()
|
||||||
|
.map(|s| truncate_serial(s))
|
||||||
|
.unwrap_or(drive.name.clone());
|
||||||
let storage_drive = StorageDrive {
|
let storage_drive = StorageDrive {
|
||||||
name: drive.name.clone(),
|
name: display_name,
|
||||||
temperature: drive.temperature_celsius,
|
temperature: drive.temperature_celsius,
|
||||||
wear_percent: drive.wear_percent,
|
wear_percent: drive.wear_percent,
|
||||||
status: Status::Ok,
|
status: Status::Ok,
|
||||||
@ -311,7 +314,9 @@ impl SystemWidget {
|
|||||||
Status::Unknown
|
Status::Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
let display_name = drive.serial_number.clone().unwrap_or(drive.name.clone());
|
let display_name = drive.serial_number.as_ref()
|
||||||
|
.map(|s| truncate_serial(s))
|
||||||
|
.unwrap_or(drive.name.clone());
|
||||||
let storage_drive = StorageDrive {
|
let storage_drive = StorageDrive {
|
||||||
name: display_name,
|
name: display_name,
|
||||||
temperature: drive.temperature_celsius,
|
temperature: drive.temperature_celsius,
|
||||||
@ -334,7 +339,9 @@ impl SystemWidget {
|
|||||||
Status::Unknown
|
Status::Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
let display_name = drive.serial_number.clone().unwrap_or(drive.name.clone());
|
let display_name = drive.serial_number.as_ref()
|
||||||
|
.map(|s| truncate_serial(s))
|
||||||
|
.unwrap_or(drive.name.clone());
|
||||||
let storage_drive = StorageDrive {
|
let storage_drive = StorageDrive {
|
||||||
name: display_name,
|
name: display_name,
|
||||||
temperature: drive.temperature_celsius,
|
temperature: drive.temperature_celsius,
|
||||||
@ -460,14 +467,13 @@ impl SystemWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let drive_text = if !drive_details.is_empty() {
|
let drive_text = if !drive_details.is_empty() {
|
||||||
format!("{} {}", drive.name, drive_details.join(" "))
|
format!("Parity: {} {}", drive.name, drive_details.join(" "))
|
||||||
} else {
|
} else {
|
||||||
drive.name.clone()
|
format!("Parity: {}", drive.name)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parity_spans = vec![
|
let mut parity_spans = vec![
|
||||||
Span::styled(" ├─ ", Typography::tree()),
|
Span::styled(" ├─ ", Typography::tree()),
|
||||||
Span::styled("Parity: ", Typography::secondary()),
|
|
||||||
];
|
];
|
||||||
parity_spans.extend(StatusIcons::create_status_spans(drive.status.clone(), &drive_text));
|
parity_spans.extend(StatusIcons::create_status_spans(drive.status.clone(), &drive_text));
|
||||||
lines.push(Line::from(parity_spans));
|
lines.push(Line::from(parity_spans));
|
||||||
@ -476,7 +482,8 @@ impl SystemWidget {
|
|||||||
|
|
||||||
// Mount point
|
// Mount point
|
||||||
lines.push(Line::from(vec![
|
lines.push(Line::from(vec![
|
||||||
Span::styled(" └─ Mount: ", Typography::tree()),
|
Span::styled(" └─ ", Typography::tree()),
|
||||||
|
Span::styled("Mount: ", Typography::secondary()),
|
||||||
Span::styled(&pool.mount_point, Typography::secondary())
|
Span::styled(&pool.mount_point, Typography::secondary())
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
@ -486,6 +493,16 @@ impl SystemWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Truncate serial number to last 8 characters
|
||||||
|
fn truncate_serial(serial: &str) -> String {
|
||||||
|
let len = serial.len();
|
||||||
|
if len > 8 {
|
||||||
|
serial[len - 8..].to_string()
|
||||||
|
} else {
|
||||||
|
serial.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper function to render a drive in a MergerFS pool
|
/// Helper function to render a drive in a MergerFS pool
|
||||||
fn render_mergerfs_drive<'a>(drive: &StorageDrive, tree_symbol: &'a str, lines: &mut Vec<Line<'a>>) {
|
fn render_mergerfs_drive<'a>(drive: &StorageDrive, tree_symbol: &'a str, lines: &mut Vec<Line<'a>>) {
|
||||||
let mut drive_details = Vec::new();
|
let mut drive_details = Vec::new();
|
||||||
@ -542,6 +559,7 @@ impl SystemWidget {
|
|||||||
|
|
||||||
// First line: serial number with temperature and wear
|
// First line: serial number with temperature and wear
|
||||||
if let Some(serial) = &self.backup_disk_serial {
|
if let Some(serial) = &self.backup_disk_serial {
|
||||||
|
let truncated_serial = truncate_serial(serial);
|
||||||
let mut details = Vec::new();
|
let mut details = Vec::new();
|
||||||
if let Some(temp) = self.backup_disk_temperature {
|
if let Some(temp) = self.backup_disk_temperature {
|
||||||
details.push(format!("T: {}°C", temp as i32));
|
details.push(format!("T: {}°C", temp as i32));
|
||||||
@ -551,9 +569,9 @@ impl SystemWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let disk_text = if !details.is_empty() {
|
let disk_text = if !details.is_empty() {
|
||||||
format!("{} {}", serial, details.join(" "))
|
format!("{} {}", truncated_serial, details.join(" "))
|
||||||
} else {
|
} else {
|
||||||
serial.clone()
|
truncated_serial
|
||||||
};
|
};
|
||||||
|
|
||||||
let backup_status = match self.backup_status.as_str() {
|
let backup_status = match self.backup_status.as_str() {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cm-dashboard-shared"
|
name = "cm-dashboard-shared"
|
||||||
version = "0.1.154"
|
version = "0.1.155"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -66,6 +66,7 @@ pub struct StorageData {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct DriveData {
|
pub struct DriveData {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub serial_number: Option<String>,
|
||||||
pub health: String,
|
pub health: String,
|
||||||
pub temperature_celsius: Option<f32>,
|
pub temperature_celsius: Option<f32>,
|
||||||
pub wear_percent: Option<f32>,
|
pub wear_percent: Option<f32>,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user