0430c0f2a8
- Nouveaux types payload: NetworkInterface, HardwareInfo - Config: slow_daily_time (HH:MM), network_info, hardware_info - Module network_info: interfaces locales, type ETH/WIFI, speed, MAC, WoL, iperf3 - Module hardware: dmidecode (carte mère, CPU, slots RAM, type/vitesse) - Scheduler: collecte au démarrage + 1×/jour à l'heure configurée - install.sh: ajout iperf3, dmidecode dans paquets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
73 lines
2.4 KiB
Rust
73 lines
2.4 KiB
Rust
fn run_dmidecode(type_num: u8) -> String {
|
|
std::process::Command::new("dmidecode")
|
|
.args(["-t", &type_num.to_string()])
|
|
.output()
|
|
.map(|o| String::from_utf8_lossy(&o.stdout).into_owned())
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
fn extract_field(text: &str, key: &str) -> Option<String> {
|
|
for line in text.lines() {
|
|
let t = line.trim();
|
|
if t.starts_with(key) {
|
|
let val = t[key.len()..].trim().trim_start_matches(':').trim();
|
|
if !val.is_empty() && val != "Not Specified" && val != "Unknown"
|
|
&& val != "To Be Filled By O.E.M." {
|
|
return Some(val.to_string());
|
|
}
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
pub fn is_available() -> bool {
|
|
std::process::Command::new("which")
|
|
.arg("dmidecode")
|
|
.output()
|
|
.map(|o| o.status.success())
|
|
.unwrap_or(false)
|
|
}
|
|
|
|
pub fn collect() -> Option<crate::payload::HardwareInfo> {
|
|
if !is_available() { return None; }
|
|
|
|
let board = run_dmidecode(2); // Baseboard
|
|
let cpu = run_dmidecode(4); // Processor
|
|
let mem = run_dmidecode(17); // Memory Device
|
|
|
|
let mut slots_total: i64 = 0;
|
|
let mut slots_used: i64 = 0;
|
|
let mut ram_type: Option<String> = None;
|
|
let mut ram_speed: Option<i64> = None;
|
|
|
|
for block in mem.split("\n\n") {
|
|
if !block.contains("Memory Device") { continue; }
|
|
slots_total += 1;
|
|
if let Some(size) = extract_field(block, "Size") {
|
|
if !size.contains("No Module") && size != "0" {
|
|
slots_used += 1;
|
|
}
|
|
}
|
|
if ram_type.is_none() {
|
|
ram_type = extract_field(block, "Type")
|
|
.filter(|t| t != "Unknown" && t != "Other");
|
|
}
|
|
if ram_speed.is_none() {
|
|
if let Some(spd) = extract_field(block, "Speed") {
|
|
ram_speed = spd.split_whitespace().next()
|
|
.and_then(|s| s.parse().ok());
|
|
}
|
|
}
|
|
}
|
|
|
|
Some(crate::payload::HardwareInfo {
|
|
motherboard_vendor: extract_field(&board, "Manufacturer"),
|
|
motherboard_model: extract_field(&board, "Product Name"),
|
|
cpu_model: extract_field(&cpu, "Version").or_else(|| extract_field(&cpu, "Family")),
|
|
ram_type,
|
|
ram_speed_mhz: ram_speed,
|
|
ram_slots_used: if slots_total > 0 { Some(slots_used) } else { None },
|
|
ram_slots_total: if slots_total > 0 { Some(slots_total) } else { None },
|
|
})
|
|
}
|