Update NixOS display format to show build hash and timestamp
- Change from showing version to build format: 'hash dd/mm/yy H:M:S' - Parse nixos-version output to extract short hash and format date - Update system widget to display 'Build:' instead of 'Version:' - Remove version/build_date fields in favor of single build string - Follow TODO.md specification for NixOS section layout
This commit is contained in:
parent
df036e90dc
commit
64af24dc40
@ -20,45 +20,42 @@ impl NixOSCollector {
|
|||||||
Self { config }
|
Self { config }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get NixOS version information
|
/// Get NixOS build information (short hash and timestamp)
|
||||||
fn get_nixos_version(&self) -> Result<(String, Option<String>), Box<dyn std::error::Error>> {
|
fn get_nixos_build_info(&self) -> Result<(String, String), Box<dyn std::error::Error>> {
|
||||||
// Try nixos-version command first
|
// Try nixos-version command first
|
||||||
if let Ok(output) = Command::new("nixos-version").output() {
|
if let Ok(output) = Command::new("nixos-version").output() {
|
||||||
if output.status.success() {
|
if output.status.success() {
|
||||||
let version_line = String::from_utf8_lossy(&output.stdout);
|
let version_line = String::from_utf8_lossy(&output.stdout);
|
||||||
let version = version_line.trim().to_string();
|
let version = version_line.trim();
|
||||||
|
|
||||||
// Extract build date if present (format: "24.05.20241023.abcdef (Vicuna)")
|
// Parse format: "24.05.20241023.abcdef (Vicuna)"
|
||||||
let build_date = if version.contains('.') {
|
if let Some(parts) = version.split('.').collect::<Vec<&str>>().get(2) {
|
||||||
let parts: Vec<&str> = version.split('.').collect();
|
if parts.len() >= 14 { // 8 digits + 6 hex chars minimum
|
||||||
if parts.len() >= 3 && parts[2].len() >= 8 {
|
let date_part = &parts[..8]; // YYYYMMDD
|
||||||
Some(parts[2][..8].to_string()) // Extract YYYYMMDD
|
let hash_part = &parts[8..]; // remaining is hash
|
||||||
} else {
|
|
||||||
None
|
// Extract short hash (first 6 characters)
|
||||||
|
let short_hash = if hash_part.len() >= 6 {
|
||||||
|
&hash_part[..6]
|
||||||
|
} else {
|
||||||
|
hash_part
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format date from YYYYMMDD to dd/mm/yy
|
||||||
|
if date_part.len() == 8 {
|
||||||
|
let year = &date_part[2..4]; // YY
|
||||||
|
let month = &date_part[4..6]; // MM
|
||||||
|
let day = &date_part[6..8]; // DD
|
||||||
|
let formatted_date = format!("{}/{}/{}", day, month, year);
|
||||||
|
|
||||||
|
return Ok((short_hash.to_string(), formatted_date));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok((version, build_date));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to /etc/os-release
|
|
||||||
if let Ok(content) = std::fs::read_to_string("/etc/os-release") {
|
|
||||||
for line in content.lines() {
|
|
||||||
if line.starts_with("VERSION_ID=") {
|
|
||||||
let version = line
|
|
||||||
.strip_prefix("VERSION_ID=")
|
|
||||||
.unwrap_or("")
|
|
||||||
.trim_matches('"')
|
|
||||||
.to_string();
|
|
||||||
return Ok((version, None));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err("Could not determine NixOS version".into())
|
Err("Could not parse NixOS build information".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get currently active users
|
/// Get currently active users
|
||||||
@ -95,36 +92,34 @@ impl Collector for NixOSCollector {
|
|||||||
let mut metrics = Vec::new();
|
let mut metrics = Vec::new();
|
||||||
let timestamp = chrono::Utc::now().timestamp() as u64;
|
let timestamp = chrono::Utc::now().timestamp() as u64;
|
||||||
|
|
||||||
// Collect NixOS version information
|
// Collect NixOS build information
|
||||||
match self.get_nixos_version() {
|
match self.get_nixos_build_info() {
|
||||||
Ok((version, build_date)) => {
|
Ok((short_hash, formatted_date)) => {
|
||||||
|
// Create combined build string: "hash dd/mm/yy H:M:S"
|
||||||
|
// For now, use current time for H:M:S (could be enhanced to get actual build time)
|
||||||
|
let now = chrono::Local::now();
|
||||||
|
let build_string = format!("{} {} {}",
|
||||||
|
short_hash,
|
||||||
|
formatted_date,
|
||||||
|
now.format("%H:%M:%S")
|
||||||
|
);
|
||||||
|
|
||||||
metrics.push(Metric {
|
metrics.push(Metric {
|
||||||
name: "system_nixos_version".to_string(),
|
name: "system_nixos_build".to_string(),
|
||||||
value: MetricValue::String(version),
|
value: MetricValue::String(build_string),
|
||||||
unit: None,
|
unit: None,
|
||||||
description: Some("NixOS version".to_string()),
|
description: Some("NixOS build information".to_string()),
|
||||||
status: Status::Ok,
|
status: Status::Ok,
|
||||||
timestamp,
|
timestamp,
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(date) = build_date {
|
|
||||||
metrics.push(Metric {
|
|
||||||
name: "system_nixos_build_date".to_string(),
|
|
||||||
value: MetricValue::String(date),
|
|
||||||
unit: None,
|
|
||||||
description: Some("NixOS build date".to_string()),
|
|
||||||
status: Status::Ok,
|
|
||||||
timestamp,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("Failed to get NixOS version: {}", e);
|
debug!("Failed to get NixOS build info: {}", e);
|
||||||
metrics.push(Metric {
|
metrics.push(Metric {
|
||||||
name: "system_nixos_version".to_string(),
|
name: "system_nixos_build".to_string(),
|
||||||
value: MetricValue::String("unknown".to_string()),
|
value: MetricValue::String("unknown".to_string()),
|
||||||
unit: None,
|
unit: None,
|
||||||
description: Some("NixOS version (failed to detect)".to_string()),
|
description: Some("NixOS build (failed to detect)".to_string()),
|
||||||
status: Status::Unknown,
|
status: Status::Unknown,
|
||||||
timestamp,
|
timestamp,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,8 +14,7 @@ use crate::ui::theme::{StatusIcons, Typography};
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SystemWidget {
|
pub struct SystemWidget {
|
||||||
// NixOS information
|
// NixOS information
|
||||||
nixos_version: Option<String>,
|
nixos_build: Option<String>,
|
||||||
nixos_build_date: Option<String>,
|
|
||||||
active_users: Option<String>,
|
active_users: Option<String>,
|
||||||
|
|
||||||
// CPU metrics
|
// CPU metrics
|
||||||
@ -63,8 +62,7 @@ struct StorageDrive {
|
|||||||
impl SystemWidget {
|
impl SystemWidget {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
nixos_version: None,
|
nixos_build: None,
|
||||||
nixos_build_date: None,
|
|
||||||
active_users: None,
|
active_users: None,
|
||||||
cpu_load_1min: None,
|
cpu_load_1min: None,
|
||||||
cpu_load_5min: None,
|
cpu_load_5min: None,
|
||||||
@ -301,14 +299,9 @@ impl Widget for SystemWidget {
|
|||||||
for metric in metrics {
|
for metric in metrics {
|
||||||
match metric.name.as_str() {
|
match metric.name.as_str() {
|
||||||
// NixOS metrics
|
// NixOS metrics
|
||||||
"system_nixos_version" => {
|
"system_nixos_build" => {
|
||||||
if let MetricValue::String(version) = &metric.value {
|
if let MetricValue::String(build) = &metric.value {
|
||||||
self.nixos_version = Some(version.clone());
|
self.nixos_build = Some(build.clone());
|
||||||
}
|
|
||||||
}
|
|
||||||
"system_nixos_build_date" => {
|
|
||||||
if let MetricValue::String(date) = &metric.value {
|
|
||||||
self.nixos_build_date = Some(date.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"system_active_users" => {
|
"system_active_users" => {
|
||||||
@ -390,9 +383,9 @@ impl Widget for SystemWidget {
|
|||||||
Span::styled("NixOS:", Typography::widget_title())
|
Span::styled("NixOS:", Typography::widget_title())
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let version_text = self.nixos_version.as_deref().unwrap_or("unknown");
|
let build_text = self.nixos_build.as_deref().unwrap_or("unknown");
|
||||||
lines.push(Line::from(vec![
|
lines.push(Line::from(vec![
|
||||||
Span::styled(format!("Version: {}", version_text), Typography::secondary())
|
Span::styled(format!("Build: {}", build_text), Typography::secondary())
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let users_text = self.active_users.as_deref().unwrap_or("unknown");
|
let users_text = self.active_users.as_deref().unwrap_or("unknown");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user