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)
|
- ✅ **Smart Panel Switching**: Only cycles through panels with data (backup panel conditional)
|
||||||
- ✅ **Scroll Support**: All panels support content scrolling with proper overflow indicators
|
- ✅ **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 ✅
|
- All keyboard navigation features working correctly ✅
|
||||||
- Service selection cursor implemented with focus-aware highlighting ✅
|
- Service selection cursor implemented with focus-aware highlighting ✅
|
||||||
- Panel scrolling fixed for System, Services, and Backup panels ✅
|
- Panel scrolling fixed for System, Services, and Backup panels ✅
|
||||||
- Build display working: "Build: 25.05.20251004.3bcc93c" ✅
|
- 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:
|
NixOS:
|
||||||
Build: 25.05.20251004.3bcc93c
|
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
|
Active users: cm, simon
|
||||||
CPU:
|
CPU:
|
||||||
● Load: 0.02 0.31 0.86 • 3000MHz
|
● Load: 0.02 0.31 0.86 • 3000MHz
|
||||||
@ -120,15 +120,44 @@ Latest backup: → Latest backup:
|
|||||||
└─ Duration: 1.3m └─ [██████ ] 60%
|
└─ 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:**
|
**Next Session Priority Tasks:**
|
||||||
|
|
||||||
**Remaining Features:**
|
**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
|
- Agent sends command completion/failure back to dashboard via ZMQ
|
||||||
- Dashboard updates UI status from ⏳ to ● when commands complete
|
- Dashboard updates UI status from ⏳ to ● when commands complete
|
||||||
- Clear success/failure status after timeout
|
- Clear success/failure status after timeout
|
||||||
|
|
||||||
2. **Backup Panel Features**:
|
3. **Backup Panel Features**:
|
||||||
- Implement backup trigger functionality (B key)
|
- Implement backup trigger functionality (B key)
|
||||||
- Complete visual feedback for backup operations
|
- Complete visual feedback for backup operations
|
||||||
- Add backup progress indicators
|
- 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"
|
- ✅ "Restructure storage widget with improved layout"
|
||||||
- ✅ "Update CPU thresholds to production values"
|
- ✅ "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
|
## 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
|
### Update Process
|
||||||
|
|
||||||
@ -257,7 +308,7 @@ When code changes are made to cm-dashboard, the NixOS configuration at `~/nixosb
|
|||||||
```
|
```
|
||||||
|
|
||||||
2. **Update NixOS Configuration**
|
2. **Update NixOS Configuration**
|
||||||
Edit `~/nixosbox/hosts/common/cm-dashboard.nix`:
|
Edit `~/projects/nixosbox/hosts/common/cm-dashboard.nix`:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
src = pkgs.fetchgit {
|
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:
|
Build with placeholder hash to get the actual hash:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/nixosbox
|
cd ~/projects/nixosbox
|
||||||
nix-build --no-out-link -E 'with import <nixpkgs> {}; fetchgit {
|
nix-build --no-out-link -E 'with import <nixpkgs> {}; fetchgit {
|
||||||
url = "https://gitea.cmtec.se/cm/cm-dashboard.git";
|
url = "https://gitea.cmtec.se/cm/cm-dashboard.git";
|
||||||
rev = "NEW_COMMIT_HASH";
|
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**
|
5. **Commit NixOS Configuration**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/nixosbox
|
cd ~/projects/nixosbox
|
||||||
git add hosts/common/cm-dashboard.nix
|
git add hosts/common/cm-dashboard.nix
|
||||||
git commit -m "Update cm-dashboard to latest version (SHORT_HASH)"
|
git commit -m "Update cm-dashboard to latest version (SHORT_HASH)"
|
||||||
git push
|
git push
|
||||||
|
|||||||
@ -347,7 +347,7 @@ impl Agent {
|
|||||||
Ok(())
|
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<()> {
|
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;
|
use std::path::Path;
|
||||||
|
|
||||||
@ -379,49 +379,37 @@ impl Agent {
|
|||||||
git_url.to_string()
|
git_url.to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let git_dir = Path::new(working_dir).join(".git");
|
// Always remove existing directory and do fresh clone for consistent state
|
||||||
|
let working_path = Path::new(working_dir);
|
||||||
if git_dir.exists() {
|
if working_path.exists() {
|
||||||
info!("Git repository exists, updating to latest {}", git_branch);
|
info!("Removing existing repository directory: {}", working_dir);
|
||||||
|
if let Err(e) = tokio::fs::remove_dir_all(working_path).await {
|
||||||
// Pull latest changes
|
error!("Failed to remove existing directory: {}", e);
|
||||||
let output = tokio::process::Command::new("git")
|
return Err(anyhow::anyhow!("Failed to remove existing directory: {}", e));
|
||||||
.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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(())
|
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::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tracing::{info, warn, error};
|
use tracing::{info, warn, debug};
|
||||||
|
|
||||||
/// Simple persistent cache for metrics
|
/// Simple persistent cache for metrics
|
||||||
pub struct SimpleCache {
|
pub struct SimpleCache {
|
||||||
@ -38,49 +38,14 @@ impl SimpleCache {
|
|||||||
|
|
||||||
/// Save cache to disk
|
/// Save cache to disk
|
||||||
pub async fn save_to_disk(&self) {
|
pub async fn save_to_disk(&self) {
|
||||||
let metrics = self.metrics.read().await;
|
// Cache persistence disabled to prevent stale data issues during debugging
|
||||||
|
debug!("Cache persistence disabled - not saving to disk");
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load cache from disk
|
/// Load cache from disk (DISABLED)
|
||||||
fn load_from_disk(&self) {
|
fn load_from_disk(&self) {
|
||||||
match fs::read_to_string(&self.persist_path) {
|
// Cache loading disabled to prevent stale data issues during debugging
|
||||||
Ok(content) => {
|
info!("Cache loading disabled - starting with fresh cache");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear cache file on startup to ensure fresh data
|
/// Clear cache file on startup to ensure fresh data
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user