v0.26.0: Storage namespace felhom-data/ + test node wipe script
All felhom-managed data on external drives now lives under felhom-data/ subdirectory, cleanly separating controller data from user files. - backup/paths.go: add FelhomDataDir constant, update 8 path helpers - stacks/delete.go: add local felhomDataDir constant (circular import boundary), update ProtectedHDDPaths + GetStackBackupData - storage/migrate_drive.go: import backup pkg, fix conflict check, verify, rsync excludes (felhom-data/backups/*/restic/), size estimation - storage/migrate.go: import backup pkg, fix DB dump paths - web/handlers.go: fix legacy 'storage' path -> backup.AppDataDir() - storage/format_linux.go: create felhom-data/ instead of storage/ - storage/attach_linux.go: create felhom-data/ instead of storage/ - scripts/felhom-wipe.sh: new multi-level test node wipe script (soft/controller/full/nuclear) - CHANGELOG.md, controller/README.md, scripts/README.md: updated docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -310,7 +310,7 @@ func FinalizeAttach(req AttachRequest, progress chan<- FormatProgress) (string,
|
||||
|
||||
_ = exec.Command("chown", "1000:1000", mountPath).Run()
|
||||
|
||||
for _, subdir := range []string{"storage", "Dokumentumok"} {
|
||||
for _, subdir := range []string{"felhom-data", "Dokumentumok"} {
|
||||
dir := filepath.Join(mountPath, subdir)
|
||||
if err := os.MkdirAll(dir, 0755); err == nil {
|
||||
_ = exec.Command("chown", "1000:1000", dir).Run()
|
||||
|
||||
@@ -208,7 +208,7 @@ func FormatAndMount(req FormatRequest, progress chan<- FormatProgress) (string,
|
||||
|
||||
_ = exec.Command("chown", "1000:1000", mountPath).Run()
|
||||
|
||||
for _, subdir := range []string{"storage", "Dokumentumok"} {
|
||||
for _, subdir := range []string{"felhom-data", "Dokumentumok"} {
|
||||
dir := filepath.Join(mountPath, subdir)
|
||||
if err := os.MkdirAll(dir, 0755); err == nil {
|
||||
_ = exec.Command("chown", "1000:1000", dir).Run()
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
||||
)
|
||||
|
||||
@@ -394,8 +395,8 @@ func (o *MigrateOrchestrator) RunEnhancedMigration(
|
||||
// --- Post-migration steps (all non-fatal) ---
|
||||
|
||||
// 1. Copy DB dumps from source to destination
|
||||
srcDBDumps := filepath.Join(req.CurrentHDDPath, "backups", "primary", req.StackName, "db-dumps")
|
||||
dstDBDumps := filepath.Join(req.TargetPath, "backups", "primary", req.StackName, "db-dumps")
|
||||
srcDBDumps := backup.AppDBDumpPath(req.CurrentHDDPath, req.StackName)
|
||||
dstDBDumps := backup.AppDBDumpPath(req.TargetPath, req.StackName)
|
||||
if _, err := os.Stat(srcDBDumps); err == nil {
|
||||
if err := os.MkdirAll(filepath.Dir(dstDBDumps), 0755); err != nil {
|
||||
o.Logger.Printf("[WARN] Migration %s: failed to create DB dump dir: %v", req.StackName, err)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
||||
)
|
||||
|
||||
@@ -180,7 +181,7 @@ func (dm *DriveMigrator) MigrateDrive(ctx context.Context, req DriveMigrateReque
|
||||
|
||||
// Check for conflicts on destination
|
||||
for _, app := range appsToMigrate {
|
||||
destAppData := filepath.Join(req.DestPath, "appdata", app.Name)
|
||||
destAppData := backup.AppDataDir(req.DestPath, app.Name)
|
||||
if info, err := os.Stat(destAppData); err == nil && info.IsDir() {
|
||||
entries, _ := os.ReadDir(destAppData)
|
||||
if len(entries) > 0 {
|
||||
@@ -192,18 +193,30 @@ func (dm *DriveMigrator) MigrateDrive(ctx context.Context, req DriveMigrateReque
|
||||
}
|
||||
}
|
||||
|
||||
// Estimate total size (exclude restic repos)
|
||||
// Estimate total size (exclude restic repos inside felhom-data/backups/)
|
||||
var totalBytes int64
|
||||
entries, _ := os.ReadDir(req.SourcePath)
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
entryPath := filepath.Join(req.SourcePath, entry.Name())
|
||||
if entry.IsDir() {
|
||||
// Skip restic repos in size estimate
|
||||
if entry.Name() == "backups" {
|
||||
totalBytes += dirSizeExcluding(entryPath, "restic")
|
||||
} else {
|
||||
totalBytes += dirSize(entryPath)
|
||||
if entry.Name() == backup.FelhomDataDir {
|
||||
// Scan inside namespace dir, excluding restic repos from estimate
|
||||
subEntries, _ := os.ReadDir(entryPath)
|
||||
for _, sub := range subEntries {
|
||||
if !sub.IsDir() {
|
||||
continue
|
||||
}
|
||||
subPath := filepath.Join(entryPath, sub.Name())
|
||||
if sub.Name() == "backups" {
|
||||
totalBytes += dirSizeExcluding(subPath, "restic")
|
||||
} else {
|
||||
totalBytes += dirSize(subPath)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
totalBytes += dirSize(entryPath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,8 +265,8 @@ func (dm *DriveMigrator) MigrateDrive(ctx context.Context, req DriveMigrateReque
|
||||
send("copying", "Adatok másolása...", 10)
|
||||
|
||||
rsyncCmd := exec.CommandContext(ctx, "rsync", "-a", "--info=progress2",
|
||||
"--exclude=backups/primary/restic/",
|
||||
"--exclude=backups/secondary/restic/",
|
||||
"--exclude=felhom-data/backups/primary/restic/",
|
||||
"--exclude=felhom-data/backups/secondary/restic/",
|
||||
req.SourcePath+"/", req.DestPath+"/",
|
||||
)
|
||||
|
||||
@@ -322,11 +335,11 @@ func (dm *DriveMigrator) MigrateDrive(ctx context.Context, req DriveMigrateReque
|
||||
send("verifying", "Másolat ellenőrzése...", 62)
|
||||
|
||||
for _, app := range appsToMigrate {
|
||||
destAppData := filepath.Join(req.DestPath, "appdata", app.Name)
|
||||
destAppData := backup.AppDataDir(req.DestPath, app.Name)
|
||||
if _, err := os.Stat(destAppData); os.IsNotExist(err) {
|
||||
// appdata might not exist for all apps (SSD-only apps that share the drive)
|
||||
// Only warn, don't fail
|
||||
dm.Logger.Printf("[WARN] Drive migration: %s/appdata/%s not found on destination (may be SSD-only)", req.DestPath, app.Name)
|
||||
dm.Logger.Printf("[WARN] Drive migration: %s not found on destination (may be SSD-only)", destAppData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user