fix(inventory_agent): Inventory agent now fallsback on error messages when it cant find values
Some checks failed
Run Check Script / check (pull_request) Failing after 38s

This commit is contained in:
Jean-Gabriel Gill-Couture 2025-08-22 11:52:51 -04:00
parent 361f240762
commit 0f59f29ac4

View File

@ -1,4 +1,4 @@
use log::debug;
use log::{debug, warn};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::fs;
@ -104,48 +104,58 @@ impl PhysicalHost {
fn all_tools_available() -> Result<(), String> {
let required_tools = [
("lsblk", "--version"),
("lspci", "--version"),
("lsmod", "--version"),
("dmidecode", "--version"),
("smartctl", "--version"),
("ip", "route"), // No version flag available
("lsblk", Some("--version")),
("lspci", Some("--version")),
("lsmod", None),
("dmidecode", Some("--version")),
("smartctl", Some("--version")),
("ip", Some("route")), // No version flag available
];
let mut missing_tools = Vec::new();
debug!("Looking for required_tools {required_tools:?}");
for (tool, tool_arg) in required_tools.iter() {
// First check if tool exists in PATH using which(1)
let exists = if let Ok(output) = Command::new("which").arg(tool).output() {
let mut exists = if let Ok(output) = Command::new("which").arg(tool).output() {
output.status.success()
} else {
// Fallback: manual PATH search if which(1) is unavailable
if let Ok(path_var) = std::env::var("PATH") {
path_var.split(':').any(|dir| {
let tool_path = std::path::Path::new(dir).join(tool);
tool_path.exists() && Self::is_executable(&tool_path)
})
} else {
false
}
};
if !exists {
// Fallback: manual PATH search if which(1) is unavailable
debug!("Looking for {tool} in path");
if let Ok(path_var) = std::env::var("PATH") {
debug!("PATH is {path_var}");
exists = path_var.split(':').any(|dir| {
let tool_path = std::path::Path::new(dir).join(tool);
tool_path.exists() && Self::is_executable(&tool_path)
})
}
}
if !exists {
warn!("Unable to find tool {tool} from PATH");
missing_tools.push(*tool);
continue;
}
// Verify tool is functional by checking version/help output
let mut cmd = Command::new(tool);
if let Some(tool_arg) = tool_arg {
cmd.arg(tool_arg);
}
cmd.stdout(std::process::Stdio::null());
cmd.stderr(std::process::Stdio::null());
if let Ok(status) = cmd.status() {
if !status.success() {
warn!("Unable to test {tool} status failed");
missing_tools.push(*tool);
}
} else {
warn!("Unable to test {tool}");
missing_tools.push(*tool);
}
}
@ -167,6 +177,7 @@ impl PhysicalHost {
#[cfg(unix)]
fn is_executable(path: &std::path::Path) -> bool {
debug!("Checking if {} is executable", path.to_string_lossy());
use std::os::unix::fs::PermissionsExt;
match std::fs::metadata(path) {
@ -285,11 +296,11 @@ impl PhysicalHost {
if device_path.exists() {
if drive.model.is_empty() {
drive.model = Self::read_sysfs_string(&device_path.join("device/model"))
.map_err(|e| format!("Failed to read model for {}: {}", name, e))?;
.unwrap_or(format!("Failed to read model for {}", name));
}
if drive.serial.is_empty() {
drive.serial = Self::read_sysfs_string(&device_path.join("device/serial"))
.map_err(|e| format!("Failed to read serial for {}: {}", name, e))?;
.unwrap_or(format!("Failed to read serial for {}", name));
}
}
@ -655,6 +666,10 @@ impl PhysicalHost {
Ok("IDE".to_string())
} else if device_name.starts_with("vd") {
Ok("VirtIO".to_string())
} else if device_name.starts_with("sr") {
Ok("CDROM".to_string())
} else if device_name.starts_with("zram") {
Ok("Ramdisk".to_string())
} else {
// Try to determine from device path
let subsystem = Self::read_sysfs_string(&device_path.join("device/subsystem"))?;