F-S2 + F-S3: compose-derived appdata dir resolution (v0.131.0)
The controller assumed an app's HDD appdata dir is always appdata/<stackName>.
paperless-ngx writes appdata/paperless (stack paperless-ngx), so every consumer
keying by stack name silently missed it via a stat-and-skip. One canonical
resolver appbackup.AppDataDirNames derives the real dir name(s) from the app's
compose ${HDD_PATH} binds; all consumers use it.
- F-S2 (tier-2): RunTier2 mirrors the resolved appdata/<name> (paperless docs
got NO tier-2 copy before). Tier2Info size + RestoreTier2Files live dir use it.
WARN when a declared appdata dir is absent. New tier2Mirror seam.
- F-S3 (migrate, NEW): all six per-app appdata legs (collision/size/copy/verify/
cleanup/skip-set) now loop resolved names. scope="app" migration of paperless
previously copied nothing and left an empty media dir (scope="all" was saved by
the merge walk). WARN on missing declared dir in the copy leg.
- Multi-dir (N>1) refusal: tier-2 backup/info/restore refuse loudly (Hungarian);
migrate supports N. No catalog app hits it today; lifted by Task 3.
- Display: storage page sums resolved dirs.
- Truth repair: the v0.130.0 "tier-2 copies the namespace wholesale" claim is
false; corrected in CHANGELOG + main.go export-adapter comment.
+9 tests; red-proofs RP-1..RP-5 all confirmed. Controller-only, no agent/hub
coupling. Task 1 of the backup-classification-redesign arc.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A45Qop8YY8tS94bz63LFne
This commit is contained in:
@@ -29,6 +29,9 @@ var (
|
||||
errTier2DriveGone = errors.New("a másodlagos meghajtó nincs csatlakoztatva")
|
||||
errLiveDriveGone = errors.New("az alkalmazás meghajtója nincs csatlakoztatva")
|
||||
errLiveDriveDecommed = errors.New("az alkalmazás meghajtója le van szerelve")
|
||||
// errTier2MultiDirRestore (F-S2): the app resolves to more than one appdata dir, which the flat
|
||||
// tier-2 copy layout does not represent — refused BEFORE the app is stopped.
|
||||
errTier2MultiDirRestore = errors.New("az alkalmazáshoz több adatkönyvtár tartozik — a fájl-visszaállítás jelenleg nem támogatott")
|
||||
)
|
||||
|
||||
// RestoreTier2Files restores the app's MISSING user files in place from its recorded Tier-2 copy
|
||||
@@ -60,7 +63,14 @@ func (m *Manager) RestoreTier2Files(stackName string) (filesRestored int, err er
|
||||
return 0, fmt.Errorf("%w (%s)", errLiveDriveDecommed, drive)
|
||||
}
|
||||
}
|
||||
liveDir := AppDataDir(m.namespaceRoot(drive), stackName)
|
||||
// F-S2: the live appdata dir is the app's REAL compose-derived dir (paperless-ngx → paperless),
|
||||
// not the stack name. N>1 distinct dirs → refuse here, BEFORE the app is stopped.
|
||||
liveNsRoot := m.namespaceRoot(drive)
|
||||
appDataName, resErr := m.tier2AppDataName(stackName, liveNsRoot)
|
||||
if resErr != nil {
|
||||
return 0, errTier2MultiDirRestore
|
||||
}
|
||||
liveDir := AppDataDir(liveNsRoot, appDataName)
|
||||
|
||||
// Source side: the RECORDED Tier-2 copy must exist and its drive must be connected.
|
||||
var srcDir string
|
||||
|
||||
Reference in New Issue
Block a user