controller: F7 atomic volume dumps + F6 no-single-copy + F5 stale-primary sweep (WIP, pre-build)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017CDMFpFx84pfviCTVuGGhf
This commit is contained in:
@@ -206,19 +206,25 @@ func (m *Manager) RunAllTier2() {
|
||||
}
|
||||
var n int
|
||||
for _, stack := range m.stackProvider.ListDeployedStacks() {
|
||||
if m.stackProvider.GetStackHDDPath(stack.Name) == "" {
|
||||
continue // not an HDD app — its data is on the rootfs, covered by PBS
|
||||
}
|
||||
// F6 (CAMPAIGN-3): volume-only apps (no HDD_PATH, backups on sys_drive) previously got NO
|
||||
// tier-2 copy — a single controller-level copy on one device. They now flow through too: their
|
||||
// recovery unit (which holds the db/volume dumps) gets a cross-drive second copy like any HDD
|
||||
// app. Apps with no recovery unit yet (infra/never-backed-up) are a cheap no-op inside RunTier2
|
||||
// (the `os.Stat(unitDir)` guard), so this doesn't spuriously copy protected stacks.
|
||||
if m.settings != nil && (m.settings.IsDisconnected(m.GetAppDrivePath(stack.Name)) ||
|
||||
m.settings.IsDecommissioned(m.GetAppDrivePath(stack.Name))) {
|
||||
continue
|
||||
}
|
||||
if err := m.RunTier2(stack.Name); err != nil {
|
||||
runOne := m.perAppTier2
|
||||
if runOne == nil {
|
||||
runOne = m.RunTier2
|
||||
}
|
||||
if err := runOne(stack.Name); err != nil {
|
||||
m.logger.Printf("[WARN] [backup] Tier 2 failed for %s: %v", stack.Name, err)
|
||||
}
|
||||
n++
|
||||
}
|
||||
m.logger.Printf("[INFO] [backup] Tier 2 run complete: %d HDD app(s) processed", n)
|
||||
m.logger.Printf("[INFO] [backup] Tier 2 run complete: %d app(s) processed (incl. volume-only — F6)", n)
|
||||
}
|
||||
|
||||
// --- per-app config-panel view (drives the Tier-2 "Beállítás" page) ---
|
||||
|
||||
Reference in New Issue
Block a user