Deduplicate NFS exports and remove client info
All checks were successful
Build and Release / build-and-release (push) Successful in 1m48s

Fix NFS export display to show each export path only once instead of
once per client. Use HashMap to deduplicate by path and sort results
alphabetically. Remove IP addresses and client specifications from
display, showing only export paths with their options.

Prevents duplicate entries when a single export is shared with multiple
clients or networks.
This commit is contained in:
Christoffer Martinsson 2025-12-11 10:06:59 +01:00
parent c8b79576fa
commit 7362464b46
5 changed files with 22 additions and 15 deletions

6
Cargo.lock generated
View File

@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]]
name = "cm-dashboard"
version = "0.1.270"
version = "0.1.271"
dependencies = [
"anyhow",
"chrono",
@ -301,7 +301,7 @@ dependencies = [
[[package]]
name = "cm-dashboard-agent"
version = "0.1.270"
version = "0.1.271"
dependencies = [
"anyhow",
"async-trait",
@ -325,7 +325,7 @@ dependencies = [
[[package]]
name = "cm-dashboard-shared"
version = "0.1.270"
version = "0.1.271"
dependencies = [
"chrono",
"serde",

View File

@ -1,6 +1,6 @@
[package]
name = "cm-dashboard-agent"
version = "0.1.271"
version = "0.1.272"
edition = "2021"
[dependencies]

View File

@ -1053,7 +1053,7 @@ impl SystemdCollector {
{
Ok(output) if output.status.success() => {
let exports_output = String::from_utf8_lossy(&output.stdout);
let mut exports = Vec::new();
let mut exports_map: std::collections::HashMap<String, String> = std::collections::HashMap::new();
for line in exports_output.lines() {
let line = line.trim();
@ -1061,8 +1061,9 @@ impl SystemdCollector {
continue;
}
// Format: "/path/to/export hostname(options)"
// We want just the path and a summary of options
// Format: "/path/to/export hostname(options)" or "/path/to/export 192.168.1.0/24(options)"
// exportfs -v shows each export once per client/network
// We want to deduplicate by path and just show one entry
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.is_empty() {
continue;
@ -1070,12 +1071,12 @@ impl SystemdCollector {
let export_path = parts[0].to_string();
// Extract options from parentheses (simplified)
// Extract options from parentheses (from the client specification)
let options = if parts.len() > 1 {
let opts_str = parts[1..].join(" ");
if let Some(start) = opts_str.find('(') {
if let Some(end) = opts_str.find(')') {
opts_str[start+1..end].to_string()
let client_spec = parts[1];
if let Some(start) = client_spec.find('(') {
if let Some(end) = client_spec.find(')') {
client_spec[start+1..end].to_string()
} else {
String::new()
}
@ -1086,9 +1087,15 @@ impl SystemdCollector {
String::new()
};
exports.push((export_path, options));
// Only store the first occurrence of each path (deduplicates multiple clients)
exports_map.entry(export_path).or_insert(options);
}
// Convert HashMap to Vec
let mut exports: Vec<(String, String)> = exports_map.into_iter().collect();
// Sort by path for consistent display
exports.sort_by(|a, b| a.0.cmp(&b.0));
exports
}
_ => Vec::new(),

View File

@ -1,6 +1,6 @@
[package]
name = "cm-dashboard"
version = "0.1.271"
version = "0.1.272"
edition = "2021"
[dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "cm-dashboard-shared"
version = "0.1.271"
version = "0.1.272"
edition = "2021"
[dependencies]