v0.110.0: offbox stale-lock self-heal (campaign C2) + crash-truthful status (C1)
resticStep escalates a restic lock error to `unlock --remove-all` + one retry (safe: single-writer repo — sub-account isolation + single-flight mutex); plain `unlock` is stale-only and can't clear a crash lock across a container-hostname change. Pre-run stale unlock hygiene on run+restore. C1: NewManager flips a persisted LastStatus=running to a truthful error. Both red-proofed (A reproduces the exact campaign backup failure). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -110,12 +110,34 @@ func NewManager(cfg *config.Config, sett *settings.Settings, logger *log.Logger)
|
||||
if cfg.Paths.SystemDataPath == "" {
|
||||
logger.Printf("[WARN] [backup] SystemDataPath is empty in config — SSD-only apps will not have correct backup paths")
|
||||
}
|
||||
return &Manager{
|
||||
m := &Manager{
|
||||
cfg: cfg,
|
||||
logger: logger,
|
||||
settings: sett,
|
||||
systemDataPath: cfg.Paths.SystemDataPath,
|
||||
}
|
||||
m.reconcileCrashedRun()
|
||||
return m
|
||||
}
|
||||
|
||||
// reconcileCrashedRun makes the persisted offbox status truthful after a crash (campaign C1): a controller
|
||||
// that died mid-run left LastStatus="running" on disk (the in-memory single-flight mutex is gone with the
|
||||
// process, but the persisted status keeps lying "running" forever). Flip it to error with a Hungarian
|
||||
// "interrupted run" message; the next successful run overwrites it. No-op unless a run was actually in
|
||||
// flight at the crash.
|
||||
func (m *Manager) reconcileCrashedRun() {
|
||||
if m.settings == nil {
|
||||
return
|
||||
}
|
||||
t := m.settings.GetOffboxTarget()
|
||||
if t == nil || t.LastStatus != "running" {
|
||||
return
|
||||
}
|
||||
_ = m.settings.UpdateOffboxStatus(func(o *settings.OffboxTarget) {
|
||||
o.LastStatus = "error"
|
||||
o.LastError = "megszakadt futás (a vezérlő újraindult futás közben)"
|
||||
})
|
||||
m.logger.Printf("[WARN] [offbox] previous run was interrupted by a controller restart — marking the last status as failed (self-corrects on the next run)")
|
||||
}
|
||||
|
||||
// GetAppDrivePath returns the drive path for an app.
|
||||
|
||||
Reference in New Issue
Block a user