Skip to content

Commit

Permalink
Fix execute function for suse specific usecase
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteOtter committed Oct 28, 2024
1 parent bf3972d commit 8e572fd
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 30 deletions.
11 changes: 5 additions & 6 deletions scripts/suse.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,12 @@ cpu_config="{\"CPU_Sockets\": \"$cpu_sockets\", \"CPU_Cores\": \"$cpu_cores\", \
system_info["CPU_Configuration"]="$cpu_config"

# Print the final JSON output
# FIXME: cpu_type omitted until filter works
cat << EOF
{
"CPU_Architecture": "${system_info["CPU_Architecture"]}",
"Max_Capacity_TB": "${system_info["Max_Capacity_TB"]}",
"CPU_Type": "${system_info["CPU_Type"]}",
"Max_Power_Watt": "${system_info["Max_Power_Watt"]}",
"RAM_GB": "${system_info["RAM_GB"]}",
"CPU_Configuration": ${system_info["CPU_Configuration"]}
"arch": "${system_info["CPU_Architecture"]}",
"capacity": "${system_info["Max_Capacity_TB"]}",
"max_power": "${system_info["Max_Power_Watt"]}",
"memory": "${system_info["RAM_GB"]}"
}
EOF
128 changes: 104 additions & 24 deletions src/collectors/pluginhandler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
//!
//! Currently, Nazara is set to handle `bash`, `python` and `Lua` scripts.
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::hash::RandomState;
use std::path::PathBuf;
use std::process::Command;
use std::{error::Error, path::Path};

Expand All @@ -23,38 +24,117 @@ use serde_json::{self, Value};
///
/// * `Ok(HashMap<String, Value, RandomState>)` - Returns a HashMap if the plugin script returns valid JSON.
/// * `Error` - If the execution of the plugin fails or it does not return a valid JSON.
pub fn execute(
path: Option<String>,
) -> Result<HashMap<String, Value, RandomState>, Box<dyn Error>> {
let script_path = match path.as_deref() {
Some(p) => Path::new(p),
None => return Err("No path provided.".into()),
};

println!(
"Attempting to execute plugin at path '{}'...",
script_path.display()
);

if !script_path.is_file() {
return Err("Provided path does not lead to a file.".into());
pub fn execute(path: Option<String>) -> Result<HashMap<String, Value, RandomState>, Box<dyn Error>> {
println!("Attempting to execute plugin at path '{:?}'...", path);

// Verify that the path is valid
if let Some(path) = path.clone() {
if !PathBuf::from(path).is_file() {
return Err("Provided path does not lead to a valid file.".into());
}
}

let output = Command::new("bash").arg(script_path).output()?;
// Execute the script
let output = Command::new("bash").arg(path.unwrap()).output()?;

// Check for execution errors
if !output.status.success() {
let err = CollectorError::PluginExecutionError(
"Either you have a syntax error in your code or the file does not exist.".to_string(),
);
return Err(err.into());
return Err("Script execution failed.".into());
}

// Convert stdout to a string
let stdout_str = String::from_utf8(output.stdout)?;

validate(&stdout_str)?; // Validate JSON format
// Parse the output JSON
let json_output: Value = serde_json::from_str(&stdout_str)?;

// Define allowed choices for cpu_type and arch
let valid_cpu_types: HashSet<&str> = [
"XEON X5/X7",
"XEON E7",
"XEON E7 v4",
"XEON E3 v4",
"XEON E5 v2",
"XEON Phi",
"XEON E5 v2",
"XEON-D",
"XEON E5 v3",
"XEON Gold/Platinum 81xx/82xx",
"XEON Platinum 92xx",
"XEON Gold 53xx",
"XEON Gold/platinum 63xx/83xx",
"XEON Gold/Platinum 64xx/84XX",
"XEON D 17xx/27xx",
"ATOM P 53xx/57xx/59xx",
"XEON E 23xx",
]
.iter()
.cloned()
.collect();

let valid_arch: HashSet<&str> = [
"aarch64", "i386", "ia64", "x86_64", "ppc64", "s390x", "ppc64le",
]
.iter()
.cloned()
.collect();

// Convert JSON to a HashMap, filtering invalid cpu_type and arch values
let mut output_map: HashMap<String, Value> = json_output
.as_object()
.ok_or("Expected JSON object format")?
.clone()
.into_iter()
.collect();

if let Some(cpu_type) = output_map.get("CPU_Type") {
if let Some(cpu_type_str) = cpu_type.as_str() {
if !valid_cpu_types.contains(cpu_type_str) {
output_map.remove("cpu_type");
}
}
}

if let Some(arch) = output_map.get("CPU_Architecture") {
if let Some(arch_str) = arch.as_str() {
if !valid_arch.contains(arch_str) {
output_map.remove("arch");
}
}
}
// Parse and adjust Max_Power_Watt, RAM_GB, and Max_Capacity_TB as integers
if let Some(max_power) = output_map.get("max_power") {
if let Some(max_power_str) = max_power.as_str() {
if let Ok(max_power_int) = max_power_str.parse::<i64>() {
output_map.insert("max_power".to_string(), Value::Number(max_power_int.into()));
} else {
output_map.remove("max_power"); // Remove if not a valid integer
}
}
}

if let Some(ram_gb) = output_map.get("memory") {
if let Some(ram_gb_str) = ram_gb.as_str() {
if let Ok(ram_gb_int) = ram_gb_str.parse::<i64>() {
output_map.insert("memory".to_string(), Value::Number(ram_gb_int.into()));
} else {
output_map.remove("memory"); // Remove if not a valid integer
}
}
}

if let Some(max_capacity) = output_map.get("capacity") {
if let Some(max_capacity_str) = max_capacity.as_str() {
if let Ok(max_capacity_int) = max_capacity_str.parse::<i64>() {
output_map.insert("capacity".to_string(), Value::Number(max_capacity_int.into()));
} else {
output_map.remove("capacity"); // Remove if not a valid integer
}
}
}

let json_output: HashMap<String, Value> = serde_json::from_str(&stdout_str)?;
Ok(json_output)
println!("{:?}", &output_map);
Ok(output_map)
}

/// Validate the output of the given plugin to ensure it is valid JSON.
Expand Down

0 comments on commit 8e572fd

Please sign in to comment.