v0.25.0 — Debug page: operator testing & diagnostics dashboard

Debug-mode-only dashboard (/debug) with 8 collapsible sections:
system diagnostics, notification testing, backup triggers, storage
simulation, hub & connectivity, self-update dry-run, DR/setup wizard,
and in-memory log viewer. Migrates debug dump from API router to web
server. Adds ring buffer log capture, storage disconnect simulation,
event history tracking, and cross-drive/self-update test methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 20:18:57 +01:00
parent be7803c0ac
commit 7f48786312
16 changed files with 2283 additions and 233 deletions
+61
View File
@@ -234,6 +234,67 @@ func imageName(image string) string {
return parts[len(parts)-1]
}
// DryRunResult holds the result of a self-update dry run.
type DryRunResult struct {
CurrentVersion string `json:"current_version"`
LatestVersion string `json:"latest_version"`
UpdateAvailable bool `json:"update_available"`
ComposeWritable bool `json:"compose_writable"`
CurrentImageLine string `json:"current_image_line"`
NewImageLine string `json:"new_image_line"`
BackupRunning bool `json:"backup_running"`
Error string `json:"error,omitempty"`
}
// DryRun checks for updates and reports what would happen without performing any changes.
func (u *Updater) DryRun() *DryRunResult {
result := &DryRunResult{
CurrentVersion: u.currentVer,
}
// Check for update
check := u.CheckForUpdate()
result.LatestVersion = check.LatestVersion
result.UpdateAvailable = check.UpdateAvailable
if check.Error != "" {
result.Error = check.Error
return result
}
// Check compose file
data, err := os.ReadFile(u.composePath)
if err != nil {
result.Error = fmt.Sprintf("Compose fájl nem olvasható: %v", err)
return result
}
// Find current image line
re := regexp.MustCompile(`(image:\s*)gitea\.dooplex\.hu/admin/felhom-controller:\S+`)
match := re.Find(data)
if match != nil {
result.CurrentImageLine = string(match)
}
// Build new image line
if check.UpdateAvailable {
result.NewImageLine = fmt.Sprintf("image: %s:%s", u.cfg.Image, check.LatestVersion)
}
// Check writability
f, err := os.OpenFile(u.composePath, os.O_WRONLY, 0)
if err == nil {
f.Close()
result.ComposeWritable = true
}
// Check backup running
if u.backupRunning != nil {
result.BackupRunning = u.backupRunning()
}
return result
}
// TriggerUpdate starts the self-update process. Returns error immediately if
// preconditions fail. The actual update runs in a goroutine.
func (u *Updater) TriggerUpdate(initiatedBy string) error {