Add configuration hash display to system panel
- Collect config hash from cloned nixos-config git repository - Display "Config: xxxxx" after "Build: xxxxx" in NixOS section - Uses /var/lib/cm-dashboard/nixos-config directory - Shows actual configuration hash vs nixpkgs build hash
This commit is contained in:
parent
996a199050
commit
2d3844b5dd
@ -63,6 +63,29 @@ impl NixOSCollector {
|
|||||||
Ok("unknown".to_string())
|
Ok("unknown".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get configuration hash from cloned nixos-config git repository
|
||||||
|
fn get_config_hash(&self) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
// Get git hash from the cloned nixos-config directory
|
||||||
|
let config_path = "/var/lib/cm-dashboard/nixos-config";
|
||||||
|
|
||||||
|
let output = Command::new("git")
|
||||||
|
.args(&["log", "-1", "--format=%h"])
|
||||||
|
.current_dir(config_path)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
return Err("git log command failed".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let hash = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||||
|
|
||||||
|
if hash.is_empty() {
|
||||||
|
return Err("Empty git hash output".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(hash)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get currently active users
|
/// Get currently active users
|
||||||
fn get_active_users(&self) -> Result<Vec<String>, Box<dyn std::error::Error>> {
|
fn get_active_users(&self) -> Result<Vec<String>, Box<dyn std::error::Error>> {
|
||||||
let output = Command::new("who").output()?;
|
let output = Command::new("who").output()?;
|
||||||
@ -148,6 +171,31 @@ impl Collector for NixOSCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collect config hash
|
||||||
|
match self.get_config_hash() {
|
||||||
|
Ok(hash) => {
|
||||||
|
metrics.push(Metric {
|
||||||
|
name: "system_config_hash".to_string(),
|
||||||
|
value: MetricValue::String(hash),
|
||||||
|
unit: None,
|
||||||
|
description: Some("NixOS configuration git hash".to_string()),
|
||||||
|
status: Status::Ok,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
debug!("Failed to get config hash: {}", e);
|
||||||
|
metrics.push(Metric {
|
||||||
|
name: "system_config_hash".to_string(),
|
||||||
|
value: MetricValue::String("unknown".to_string()),
|
||||||
|
unit: None,
|
||||||
|
description: Some("Config hash (failed to detect)".to_string()),
|
||||||
|
status: Status::Unknown,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Collect agent hash
|
// Collect agent hash
|
||||||
match self.get_agent_hash() {
|
match self.get_agent_hash() {
|
||||||
Ok(hash) => {
|
Ok(hash) => {
|
||||||
|
|||||||
@ -14,6 +14,7 @@ use crate::ui::theme::{StatusIcons, Typography};
|
|||||||
pub struct SystemWidget {
|
pub struct SystemWidget {
|
||||||
// NixOS information
|
// NixOS information
|
||||||
nixos_build: Option<String>,
|
nixos_build: Option<String>,
|
||||||
|
config_hash: Option<String>,
|
||||||
active_users: Option<String>,
|
active_users: Option<String>,
|
||||||
agent_hash: Option<String>,
|
agent_hash: Option<String>,
|
||||||
|
|
||||||
@ -64,6 +65,7 @@ impl SystemWidget {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
nixos_build: None,
|
nixos_build: None,
|
||||||
|
config_hash: None,
|
||||||
active_users: None,
|
active_users: None,
|
||||||
agent_hash: None,
|
agent_hash: None,
|
||||||
cpu_load_1min: None,
|
cpu_load_1min: None,
|
||||||
@ -322,6 +324,11 @@ impl Widget for SystemWidget {
|
|||||||
self.nixos_build = Some(build.clone());
|
self.nixos_build = Some(build.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"system_config_hash" => {
|
||||||
|
if let MetricValue::String(hash) = &metric.value {
|
||||||
|
self.config_hash = Some(hash.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
"system_active_users" => {
|
"system_active_users" => {
|
||||||
if let MetricValue::String(users) = &metric.value {
|
if let MetricValue::String(users) = &metric.value {
|
||||||
self.active_users = Some(users.clone());
|
self.active_users = Some(users.clone());
|
||||||
@ -418,6 +425,11 @@ impl SystemWidget {
|
|||||||
Span::styled(format!("Build: {}", build_text), Typography::secondary())
|
Span::styled(format!("Build: {}", build_text), Typography::secondary())
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
let config_text = self.config_hash.as_deref().unwrap_or("unknown");
|
||||||
|
lines.push(Line::from(vec![
|
||||||
|
Span::styled(format!("Config: {}", config_text), Typography::secondary())
|
||||||
|
]));
|
||||||
|
|
||||||
let agent_hash_text = self.agent_hash.as_deref().unwrap_or("unknown");
|
let agent_hash_text = self.agent_hash.as_deref().unwrap_or("unknown");
|
||||||
let short_hash = if agent_hash_text.len() > 8 && agent_hash_text != "unknown" {
|
let short_hash = if agent_hash_text.len() > 8 && agent_hash_text != "unknown" {
|
||||||
&agent_hash_text[..8]
|
&agent_hash_text[..8]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user