feat(shares): R-7b Parts 4-6 — shares restore, samba liveness, UI truth-up
Part 4 — restore: RestoreSharesScratch + PlaceSharesRestore as SIBLINGS of the
per-app scratch/place pair. Files merged missing-only (never overwriting), each
destination PREFIX-ASSERTED against registered LIVE storage roots; definitions
merged with existing-wins; ReconcileSamba via a seam (backup must not import
stacks); credential restored best-effort into the samba named volume.
New routes POST /backup/shares/{restore,place} + a restore-page entry that renders
'Megosztasok', never the raw reserved key.
Also adds scratchJoin: reconstructing an absolute captured path under a scratch
must strip the volume name rather than rely on filepath.Join.
Part 5 — liveness: EffectiveProtected gains a settings-backed dynamic extra so the
samba CONTAINER (not the stack name — they differ) is watched exactly while sharing
is on. FINDING: the issue -> health 'fail' -> existing health_critical event ->
alert -> Hungarian degradation e-mail path needs NO further change, and introduces
no new event type, so the allowlist gotcha does not apply.
Part 6 — UI: per-tier backup status lines on the Megosztas page (amber only on
deviation). Verified the two warning-prose sites (offbox_capture/tier2_capture)
only ever receive per-app stack names, so no mapping is needed there.
RED-PROOFS RUN AND REVERTED (both fired):
4. prefix-assert removed -> place-guard traversal test FAILS
5. dynamic samba extra removed -> Scenario E enabled-case FAILS
This commit is contained in:
@@ -154,6 +154,26 @@ func (s *Server) sharingPageData() map[string]interface{} {
|
||||
roots = append(roots, map[string]string{"Path": sp.Path, "Label": label})
|
||||
}
|
||||
data["StorageRoots"] = roots
|
||||
|
||||
// R-7b: per-tier backup truth. Until R-7b the „Felhőmentés" toggle promised a protection the
|
||||
// engines did not deliver; these two lines are what makes the promise checkable by the customer
|
||||
// rather than taken on faith. Amber ONLY on deviation — a green tier says nothing at all beyond
|
||||
// its timestamp, so the page stays quiet when everything is fine.
|
||||
if s.backupMgr != nil {
|
||||
if cd := s.backupMgr.SharesTier2Status(); cd != nil {
|
||||
data["SharesTier2Status"] = cd.LastStatus
|
||||
data["SharesTier2LastRun"] = cd.LastRun
|
||||
data["SharesTier2Warning"] = cd.LastWarning
|
||||
data["SharesTier2Error"] = cd.LastError
|
||||
data["SharesTier2Dest"] = cd.DestinationPath
|
||||
}
|
||||
if lastRun, status, count, ok := s.backupMgr.SharesOffsiteStatus(); ok {
|
||||
data["SharesOffsiteStatus"] = status
|
||||
data["SharesOffsiteLastRun"] = lastRun
|
||||
data["SharesOffsiteCount"] = count
|
||||
}
|
||||
data["SharesRestoreReady"] = s.backupMgr.SharesScratchReady()
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user