feat: drive migration & Tier 2 restic deprecation (v0.18.0)

Phase 1: Deprecate restic as Tier 2 method (rsync only), auto-migrate on startup
Phase 2: Enhanced per-app migration with backup awareness, DB dump copy, auto-cleanup
Phase 3: Full drive migration with decommissioned state, rollback support, wizard UI
Phase 4: Hub report includes decommissioned drive state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 21:49:14 +01:00
parent bdbe170a54
commit 99bf3ca7a8
22 changed files with 1725 additions and 402 deletions
+9
View File
@@ -69,6 +69,15 @@ func BuildReport(
{Mount: "/", Label: "SSD", TotalGB: sysInfo.DiskTotalGB, UsedGB: sysInfo.DiskUsedGB, Percent: sysInfo.DiskPercent},
}
for _, sp := range storagePaths {
if sp.Decommissioned {
r.Storage = append(r.Storage, StorageReport{
Mount: sp.Path,
Label: sp.Label,
Decommissioned: true,
MigratedTo: sp.MigratedTo,
})
continue
}
if sp.Disconnected {
r.Storage = append(r.Storage, StorageReport{
Mount: sp.Path,
@@ -75,12 +75,6 @@ func BuildInfraBackup(
logger.Printf("[WARN] Infra backup: could not read restic password file: %v", err)
}
// Cross-drive password is stored as plain text (not base64) because it's
// already a string in settings, unlike ResticPassword which comes from a file.
if pw := sett.GetCrossDriveResticPassword(); pw != "" {
ib.CrossDrivePassword = pw
}
// Collect disk layout from fstab + blkid
ib.DiskLayout = collectDiskLayout(systemDataPath)
+8 -6
View File
@@ -39,12 +39,14 @@ type SystemReport struct {
// StorageReport holds disk usage for a mount point.
type StorageReport struct {
Mount string `json:"mount"`
Label string `json:"label,omitempty"`
TotalGB float64 `json:"total_gb"`
UsedGB float64 `json:"used_gb"`
Percent float64 `json:"percent"`
Disconnected bool `json:"disconnected,omitempty"`
Mount string `json:"mount"`
Label string `json:"label,omitempty"`
TotalGB float64 `json:"total_gb"`
UsedGB float64 `json:"used_gb"`
Percent float64 `json:"percent"`
Disconnected bool `json:"disconnected,omitempty"`
Decommissioned bool `json:"decommissioned,omitempty"`
MigratedTo string `json:"migrated_to,omitempty"`
}
// ContainerReport holds aggregate and per-container status.