Fix config hash to use nix store hash and disable cache persistence
This commit is contained in:
parent
fb6ee6d7ae
commit
8dd943e8f1
71
CLAUDE.md
71
CLAUDE.md
@ -28,18 +28,18 @@ All keyboard navigation and service selection features successfully implemented:
|
||||
- ✅ **Smart Panel Switching**: Only cycles through panels with data (backup panel conditional)
|
||||
- ✅ **Scroll Support**: All panels support content scrolling with proper overflow indicators
|
||||
|
||||
**Current Status - October 24, 2025:**
|
||||
**Current Status - October 25, 2025:**
|
||||
- All keyboard navigation features working correctly ✅
|
||||
- Service selection cursor implemented with focus-aware highlighting ✅
|
||||
- Panel scrolling fixed for System, Services, and Backup panels ✅
|
||||
- Build display working: "Build: 25.05.20251004.3bcc93c" ✅
|
||||
- Configuration hash display implemented: "Config: d16f0d0" ✅
|
||||
- Configuration hash display: Currently shows git hash, needs to be fixed ❌
|
||||
|
||||
**Layout Achieved:**
|
||||
**Target Layout:**
|
||||
```
|
||||
NixOS:
|
||||
Build: 25.05.20251004.3bcc93c
|
||||
Config: d16f0d0 # Shows actual nixosbox config hash
|
||||
Config: d8ivwiar # Should show nix store hash (8 chars) from deployed system
|
||||
Active users: cm, simon
|
||||
CPU:
|
||||
● Load: 0.02 0.31 0.86 • 3000MHz
|
||||
@ -120,15 +120,44 @@ Latest backup: → Latest backup:
|
||||
└─ Duration: 1.3m └─ [██████ ] 60%
|
||||
```
|
||||
|
||||
**Critical Configuration Hash Fix - HIGH PRIORITY:**
|
||||
|
||||
**Problem:** Configuration hash currently shows git commit hash instead of actual deployed system hash.
|
||||
|
||||
**Current (incorrect):**
|
||||
- Shows git hash: `db11f82` (source repository commit)
|
||||
- Not accurate - doesn't reflect what's actually deployed
|
||||
|
||||
**Target (correct):**
|
||||
- Show nix store hash: `d8ivwiar` (first 8 chars from deployed system)
|
||||
- Source: `/nix/store/d8ivwiarhwhgqzskj6q2482r58z46qjf-nixos-system-cmbox-25.05.20251004.3bcc93c`
|
||||
- Pattern: Extract hash from `/nix/store/HASH-nixos-system-HOSTNAME-VERSION`
|
||||
|
||||
**Benefits:**
|
||||
1. **Deployment Verification:** Confirms rebuild actually succeeded
|
||||
2. **Accurate Status:** Shows what's truly running, not just source
|
||||
3. **Rebuild Completion Detection:** Hash change = rebuild completed
|
||||
4. **Rollback Tracking:** Each deployment has unique identifier
|
||||
|
||||
**Implementation Required:**
|
||||
1. Agent extracts nix store hash from `ls -la /run/current-system`
|
||||
2. Reports this as `system_config_hash` metric instead of git hash
|
||||
3. Dashboard displays first 8 characters: `Config: d8ivwiar`
|
||||
|
||||
**Next Session Priority Tasks:**
|
||||
|
||||
**Remaining Features:**
|
||||
1. **Command Response Protocol**:
|
||||
1. **Fix Configuration Hash Display (CRITICAL)**:
|
||||
- Use nix store hash instead of git commit hash
|
||||
- Extract from `/run/current-system` -> `/nix/store/HASH-nixos-system-*`
|
||||
- Enables proper rebuild completion detection
|
||||
|
||||
2. **Command Response Protocol**:
|
||||
- Agent sends command completion/failure back to dashboard via ZMQ
|
||||
- Dashboard updates UI status from ⏳ to ● when commands complete
|
||||
- Clear success/failure status after timeout
|
||||
|
||||
2. **Backup Panel Features**:
|
||||
3. **Backup Panel Features**:
|
||||
- Implement backup trigger functionality (B key)
|
||||
- Complete visual feedback for backup operations
|
||||
- Add backup progress indicators
|
||||
@ -244,9 +273,31 @@ NEVER implement code without first getting explicit user agreement on the approa
|
||||
- ✅ "Restructure storage widget with improved layout"
|
||||
- ✅ "Update CPU thresholds to production values"
|
||||
|
||||
## Development and Deployment Architecture
|
||||
|
||||
**CRITICAL:** Development and deployment paths are completely separate:
|
||||
|
||||
### Development Path
|
||||
- **Location:** `~/projects/nixosbox`
|
||||
- **Purpose:** Development workflow only - for committing new cm-dashboard code
|
||||
- **Access:** Only for developers to commit changes
|
||||
- **Code Access:** Running cm-dashboard code shall NEVER access this path
|
||||
|
||||
### Deployment Path
|
||||
- **Location:** `/var/lib/cm-dashboard/nixos-config`
|
||||
- **Purpose:** Production deployment only - agent clones/pulls from git
|
||||
- **Access:** Only cm-dashboard agent for deployment operations
|
||||
- **Workflow:** git pull → `/var/lib/cm-dashboard/nixos-config` → nixos-rebuild
|
||||
|
||||
### Git Flow
|
||||
```
|
||||
Development: ~/projects/nixosbox → git commit → git push
|
||||
Deployment: git pull → /var/lib/cm-dashboard/nixos-config → rebuild
|
||||
```
|
||||
|
||||
## NixOS Configuration Updates
|
||||
|
||||
When code changes are made to cm-dashboard, the NixOS configuration at `~/nixosbox` must be updated to deploy the changes.
|
||||
When code changes are made to cm-dashboard, the NixOS configuration at `~/projects/nixosbox` must be updated to deploy the changes.
|
||||
|
||||
### Update Process
|
||||
|
||||
@ -257,7 +308,7 @@ When code changes are made to cm-dashboard, the NixOS configuration at `~/nixosb
|
||||
```
|
||||
|
||||
2. **Update NixOS Configuration**
|
||||
Edit `~/nixosbox/hosts/common/cm-dashboard.nix`:
|
||||
Edit `~/projects/nixosbox/hosts/common/cm-dashboard.nix`:
|
||||
|
||||
```nix
|
||||
src = pkgs.fetchgit {
|
||||
@ -271,7 +322,7 @@ When code changes are made to cm-dashboard, the NixOS configuration at `~/nixosb
|
||||
Build with placeholder hash to get the actual hash:
|
||||
|
||||
```bash
|
||||
cd ~/nixosbox
|
||||
cd ~/projects/nixosbox
|
||||
nix-build --no-out-link -E 'with import <nixpkgs> {}; fetchgit {
|
||||
url = "https://gitea.cmtec.se/cm/cm-dashboard.git";
|
||||
rev = "NEW_COMMIT_HASH";
|
||||
@ -293,7 +344,7 @@ When code changes are made to cm-dashboard, the NixOS configuration at `~/nixosb
|
||||
5. **Commit NixOS Configuration**
|
||||
|
||||
```bash
|
||||
cd ~/nixosbox
|
||||
cd ~/projects/nixosbox
|
||||
git add hosts/common/cm-dashboard.nix
|
||||
git commit -m "Update cm-dashboard to latest version (SHORT_HASH)"
|
||||
git push
|
||||
|
||||
@ -347,7 +347,7 @@ impl Agent {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ensure git repository is cloned and up to date
|
||||
/// Ensure git repository is cloned and up to date with force clone approach
|
||||
async fn ensure_git_repository(&self, git_url: &str, git_branch: &str, working_dir: &str, api_key_file: Option<&str>) -> Result<()> {
|
||||
use std::path::Path;
|
||||
|
||||
@ -379,49 +379,37 @@ impl Agent {
|
||||
git_url.to_string()
|
||||
};
|
||||
|
||||
let git_dir = Path::new(working_dir).join(".git");
|
||||
|
||||
if git_dir.exists() {
|
||||
info!("Git repository exists, updating to latest {}", git_branch);
|
||||
|
||||
// Pull latest changes
|
||||
let output = tokio::process::Command::new("git")
|
||||
.arg("pull")
|
||||
.arg("origin")
|
||||
.arg(git_branch)
|
||||
.current_dir(working_dir)
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
error!("Git pull failed: {}", stderr);
|
||||
return Err(anyhow::anyhow!("Git pull failed: {}", stderr));
|
||||
// Always remove existing directory and do fresh clone for consistent state
|
||||
let working_path = Path::new(working_dir);
|
||||
if working_path.exists() {
|
||||
info!("Removing existing repository directory: {}", working_dir);
|
||||
if let Err(e) = tokio::fs::remove_dir_all(working_path).await {
|
||||
error!("Failed to remove existing directory: {}", e);
|
||||
return Err(anyhow::anyhow!("Failed to remove existing directory: {}", e));
|
||||
}
|
||||
|
||||
info!("Git repository updated successfully");
|
||||
} else {
|
||||
info!("Cloning git repository from {} (branch: {})", git_url, git_branch);
|
||||
|
||||
// Clone repository with authentication if available
|
||||
let output = tokio::process::Command::new("git")
|
||||
.arg("clone")
|
||||
.arg("--branch")
|
||||
.arg(git_branch)
|
||||
.arg(&auth_url) // Use authenticated URL
|
||||
.arg(working_dir)
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
error!("Git clone failed: {}", stderr);
|
||||
return Err(anyhow::anyhow!("Git clone failed: {}", stderr));
|
||||
}
|
||||
|
||||
info!("Git repository cloned successfully");
|
||||
}
|
||||
|
||||
info!("Force cloning git repository from {} (branch: {})", git_url, git_branch);
|
||||
|
||||
// Force clone with depth 1 for efficiency (no history needed for deployment)
|
||||
let output = tokio::process::Command::new("git")
|
||||
.arg("clone")
|
||||
.arg("--depth")
|
||||
.arg("1")
|
||||
.arg("--branch")
|
||||
.arg(git_branch)
|
||||
.arg(&auth_url)
|
||||
.arg(working_dir)
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
error!("Git clone failed: {}", stderr);
|
||||
return Err(anyhow::anyhow!("Git clone failed: {}", stderr));
|
||||
}
|
||||
|
||||
info!("Git repository cloned successfully with latest state");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
47
agent/src/cache/mod.rs
vendored
47
agent/src/cache/mod.rs
vendored
@ -4,7 +4,7 @@ use std::fs;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{info, warn, error};
|
||||
use tracing::{info, warn, debug};
|
||||
|
||||
/// Simple persistent cache for metrics
|
||||
pub struct SimpleCache {
|
||||
@ -38,49 +38,14 @@ impl SimpleCache {
|
||||
|
||||
/// Save cache to disk
|
||||
pub async fn save_to_disk(&self) {
|
||||
let metrics = self.metrics.read().await;
|
||||
|
||||
// Create directory if needed
|
||||
if let Some(parent) = Path::new(&self.persist_path).parent() {
|
||||
if let Err(e) = fs::create_dir_all(parent) {
|
||||
warn!("Failed to create cache directory {}: {}", parent.display(), e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize and save
|
||||
match serde_json::to_string_pretty(&*metrics) {
|
||||
Ok(json) => {
|
||||
if let Err(e) = fs::write(&self.persist_path, json) {
|
||||
error!("Failed to save cache to {}: {}", self.persist_path, e);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to serialize cache: {}", e);
|
||||
}
|
||||
}
|
||||
// Cache persistence disabled to prevent stale data issues during debugging
|
||||
debug!("Cache persistence disabled - not saving to disk");
|
||||
}
|
||||
|
||||
/// Load cache from disk
|
||||
/// Load cache from disk (DISABLED)
|
||||
fn load_from_disk(&self) {
|
||||
match fs::read_to_string(&self.persist_path) {
|
||||
Ok(content) => {
|
||||
match serde_json::from_str::<HashMap<String, Metric>>(&content) {
|
||||
Ok(loaded_metrics) => {
|
||||
if let Ok(mut metrics) = self.metrics.try_write() {
|
||||
*metrics = loaded_metrics;
|
||||
info!("Loaded {} metrics from cache", metrics.len());
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Failed to parse cache file {}: {}", self.persist_path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
info!("No cache file found at {}, starting fresh", self.persist_path);
|
||||
}
|
||||
}
|
||||
// Cache loading disabled to prevent stale data issues during debugging
|
||||
info!("Cache loading disabled - starting with fresh cache");
|
||||
}
|
||||
|
||||
/// Clear cache file on startup to ensure fresh data
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user