fix(backup): 4 bug fixes from v0.14.1 code review (v0.14.2)
Bug 1 (HIGH): add --exclude _* to rsync --delete so _db/ and _config/ directories are never deleted between backup runs (crossdrive.go) Bug 2 (MEDIUM): refactor RunDBDumps/RunBackup/RunFullBackup to use acquireRunning/releaseRunning helpers; extract runDBDumpsInternal and runBackupInternal so all three public entry points set m.running and RunFullBackup no longer deadlocks calling the public methods (backup.go) Bug 3 (MEDIUM): log [WARN] when GetDiskUsage returns nil in ValidateDestination instead of silently skipping space checks (crossdrive.go) Bug 4 (MEDIUM): add [WARN] on empty SystemDataPath in NewManager; add [ERROR] in GetAppDrivePath; guard DumpStackDB against empty/relative paths (backup.go) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -212,20 +212,23 @@ func (r *CrossDriveRunner) ValidateDestination(path string) error {
|
||||
if !system.IsWritable(path) {
|
||||
return fmt.Errorf("destination %s is not writable", path)
|
||||
}
|
||||
if di := system.GetDiskUsage(path); di != nil {
|
||||
if onSystemDrive {
|
||||
// System drive: protect OS stability — require ≥10 GB free and <90% used
|
||||
if di.AvailGB < 10 {
|
||||
return fmt.Errorf("destination %s is on the system drive with only %.1f GB free — at least 10 GB required to protect OS stability", path, di.AvailGB)
|
||||
}
|
||||
if di.UsedPercent >= 90 {
|
||||
return fmt.Errorf("destination %s is on the system drive at %.0f%% capacity — maximum 90%% allowed", path, di.UsedPercent)
|
||||
}
|
||||
} else {
|
||||
// External drive: just ensure it's not completely full
|
||||
if di.AvailGB < 0.1 {
|
||||
return fmt.Errorf("destination %s has insufficient free space (%.1f GB free)", path, di.AvailGB)
|
||||
}
|
||||
di := system.GetDiskUsage(path)
|
||||
if di == nil {
|
||||
r.logger.Printf("[WARN] Cannot determine disk usage for %s — proceeding without space verification", path)
|
||||
return nil
|
||||
}
|
||||
if onSystemDrive {
|
||||
// System drive: protect OS stability — require ≥10 GB free and <90% used
|
||||
if di.AvailGB < 10 {
|
||||
return fmt.Errorf("destination %s is on the system drive with only %.1f GB free — at least 10 GB required to protect OS stability", path, di.AvailGB)
|
||||
}
|
||||
if di.UsedPercent >= 90 {
|
||||
return fmt.Errorf("destination %s is on the system drive at %.0f%% capacity — maximum 90%% allowed", path, di.UsedPercent)
|
||||
}
|
||||
} else {
|
||||
// External drive: just ensure it's not completely full
|
||||
if di.AvailGB < 0.1 {
|
||||
return fmt.Errorf("destination %s has insufficient free space (%.1f GB free)", path, di.AvailGB)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -263,8 +266,11 @@ func (r *CrossDriveRunner) runRsyncBackup(ctx context.Context, stackName, destBa
|
||||
src := strings.TrimRight(srcMount, "/") + "/"
|
||||
dst := strings.TrimRight(dstPath, "/") + "/"
|
||||
|
||||
// Exclude controller-managed directories (underscore prefix) to prevent --delete from removing
|
||||
// _db/ and _config/ that were created by previous backup runs.
|
||||
// Exclude app-internal DB dump files — the controller handles DB backups via pg_dump separately.
|
||||
cmd := exec.CommandContext(ctx, "rsync", "-a", "--delete",
|
||||
"--exclude", "_*",
|
||||
"--exclude", "backups/*.sql.gz",
|
||||
"--exclude", "backups/*.sql",
|
||||
"--exclude", "backups/*.dump",
|
||||
|
||||
Reference in New Issue
Block a user