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]