From 7362464b4651680cf2e12b10eea47c2e68deee6f Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Thu, 11 Dec 2025 10:06:59 +0100 Subject: [PATCH] Deduplicate NFS exports and remove client info 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. --- Cargo.lock | 6 +++--- agent/Cargo.toml | 2 +- agent/src/collectors/systemd.rs | 25 ++++++++++++++++--------- dashboard/Cargo.toml | 2 +- shared/Cargo.toml | 2 +- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76f7d97..7140979 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index 2136920..05bb66b 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-agent" -version = "0.1.271" +version = "0.1.272" edition = "2021" [dependencies] diff --git a/agent/src/collectors/systemd.rs b/agent/src/collectors/systemd.rs index eba2d1e..aa9f72e 100644 --- a/agent/src/collectors/systemd.rs +++ b/agent/src/collectors/systemd.rs @@ -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 = 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(), diff --git a/dashboard/Cargo.toml b/dashboard/Cargo.toml index 30fdd2e..0795af1 100644 --- a/dashboard/Cargo.toml +++ b/dashboard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard" -version = "0.1.271" +version = "0.1.272" edition = "2021" [dependencies] diff --git a/shared/Cargo.toml b/shared/Cargo.toml index f69d2c4..275adc3 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-shared" -version = "0.1.271" +version = "0.1.272" edition = "2021" [dependencies]