5.8 KiB
5.8 KiB
P0-009: Storage Scanner Reports Disk Info to Updates Table Instead of System Info
Priority: P0 (Critical - Data Architecture Issue) Date Identified: 2025-12-17 Date Created: 2025-12-17 Status: Open (Investigation Complete, Fix Needed) Created By: Casey & Claude
Problem Description
The storage scanner (Disk Usage Reporter) is reporting disk/partition information to the updates table instead of populating system_info. This causes:
- Disk information not appearing in Agent Storage UI tab
- Disk data stored in wrong table (treated as updatable packages)
- Hourly delay for disk info to appear (waiting for system info report)
- Inappropriate severity tracking for static system information
Current Behavior
Agent Side:
- Storage scanner runs and collects detailed disk info (mountpoints, devices, types, filesystems)
- Converts to
UpdateReportItemformat with severity levels - Reports via
/api/v1/agents/:id/updatesendpoint - Stored in
update_packagestable with package_type='storage'
Server Side:
- Storage metrics endpoint reads from
system_infostructure (not updates table) - UI expects
agent.system_info.disk_infoarray - Disk data is in wrong place, so UI shows empty
Root Cause
In aggregator-agent/internal/orchestrator/storage_scanner.go:
func (s *StorageScanner) Scan() ([]client.UpdateReportItem, error) {
// Converts StorageMetric to UpdateReportItem
// Stores disk info in updates table, not system_info
}
The storage scanner implements legacy interface:
- Uses
Scan()→UpdateReportItem - Should use
ScanTyped()→TypedScannerResultwithStorageData - System info reporters (system, filesystem) already use proper interface
What I've Investigated
Agent Code:
- ✅ Storage scanner collects comprehensive disk data
- ✅ Data includes: mountpoints, devices, disk_type, filesystem, severity
- ❌ Reports via legacy conversion to updates
Server Code:
- ✅ Has
/api/v1/agents/:id/metrics/storageendpoint (reads from system_info) - ✅ Has proper
TypedScannerResultinfrastructure - ❌ Never receives disk data because it's in wrong table
Database Schema:
update_packagestable stores disk info (package_type='storage')agent_specstable hasmetadataJSONB field- No dedicated
system_infotable - it's embedded in agent response
UI Code:
AgentStorage.tsxreads fromagent.system_info.disk_info- Has both overview bars AND detailed table implemented
- Works correctly when data is in right place
What Needs to be Fixed
Option 1: Store in AgentSpecs.metadata (Proper)
- Modify storage scanner to return
TypedScannerResult - Call
client.ReportSystemInfo()with disk_info populated - Update
agent_specs.metadataor addsystem_infocolumn - Remove legacy
Scan()method from storage scanner
Pros:
- Data in correct semantic location
- No hourly delay for disk info
- Aligns with system/filesystem scanners
- Works immediately with existing UI
Cons:
- Requires database schema change (add system_info column or use metadata)
- Breaking change for existing disk usage report structure
- Need migration for existing storage data
Option 2: Make Metrics READ from Updates (Workaround)
- Keep storage scanner reporting to updates table
- Modify
GetAgentStorageMetrics()to read from updates - Transform update_packages rows into storage metrics format
Pros:
- No agent code changes
- Works with current data flow
- Quick fix
Cons:
- Semantic wrongness (system info in updates)
- Performance issues (querying updates table for system info)
- Still has severity tracking (inappropriate for static info)
Option 3: Dual Write (Temporary Bridge)
- Storage scanner reports BOTH to system_info AND updates (for backward compatibility)
- After migration, remove updates reporting
Pros:
- Backward compatible
- Smooth transition
Cons:
- Data duplication
- Temporary hack
- Still need Option 1 eventually
Recommended Fix: Option 1
Implement proper typed scanning for storage:
-
In
storage_scanner.go:- Remove
Scan()legacy method - Implement
ScanTyped()returningTypedScannerResult - Populate
TypedScannerResult.StorageDatawith disks
- Remove
-
In metrics handler or agent check-in:
- When storage scanner runs, collect
TypedScannerResult - Call
client.ReportSystemInfo()withreport.SystemInfo.DiskInfopopulated - This updates agent's system_info in real-time
- When storage scanner runs, collect
-
In database:
- Add
system_info JSONBcolumn to agent_specs table - Or reuse existing metadata field
- Add
-
In UI:
- No changes needed (already reads from system_info)
Files to Modify
Agent:
/home/casey/Projects/RedFlag/aggregator-agent/internal/orchestrator/storage_scanner.go
Server:
/home/casey/Projects/RedFlag/aggregator-server/internal/api/handlers/metrics.go- Database schema (add system_info column)
Migration:
- Create migration to add system_info column
- Optional: migrate existing storage update_reports to system_info
Testing After Fix
- Install agent with fixed storage scanner
- Navigate to Agent → Storage tab
- Should immediately see:
- Overview disk usage bars
- Detailed partition table with all disks
- Device names, types, filesystems, mountpoints
- Severity indicators
- No waiting for hourly system info report
- Data should persist correctly
Related Issues
- P0-007: Install script path variables (fixed)
- P0-008: Migration false positives (fixed)
- P0-009: This issue (storage scanner wrong table)
Notes for Implementer
- Look at how
systemscanner implementsScanTyped()for reference - The agent already has
reportSystemInfo()method - just need to populate disk_info - Storage scanner is the ONLY scanner still using legacy Scan() interface
- Remove legacy Scan() method entirely once ScanTyped() is implemented