bisync: add overlapping paths check

Before this change, Bisync did not check to make sure that Path1 and Path2 do
not overlap, nor did it check for overlaps with `--backup-dir`. While `sync`
does check for these things, it can sometimes be fooled because of the way
Bisync calls it with `--files-from` filters. Relying on sync could also leave a
run in a half-finished state if it were to error in one direction but not the
other (`--backup-dir` only checks for overlaps with the dest.)

After this change, Bisync does its own check up front, so we can quickly return
an error and exit before any changes are made.
This commit is contained in:
nielash
2023-12-18 13:03:14 -05:00
parent e9cd3e5986
commit e71b252b65
35 changed files with 350 additions and 1 deletions

View File

@@ -248,6 +248,14 @@ func (b *bisyncRun) runLocked(octx context.Context) (err error) {
b.octx = octx
b.fctx = fctx
// overlapping paths check
err = b.overlappingPathsCheck(fctx, b.fs1, b.fs2)
if err != nil {
b.critical = true
b.retryable = true
return err
}
// Generate Path1 and Path2 listings and copy any unique Path2 files to Path1
if opt.Resync {
return b.resync(octx, fctx)
@@ -676,12 +684,45 @@ func (b *bisyncRun) setBackupDir(ctx context.Context, destPath int) context.Cont
ci.BackupDir = b.opt.BackupDir1
}
if destPath == 2 && b.opt.BackupDir2 != "" {
ci.BackupDir = b.opt.BackupDir1
ci.BackupDir = b.opt.BackupDir2
}
fs.Debugf(ci.BackupDir, "updated backup-dir for Path%d", destPath)
return ctx
}
func (b *bisyncRun) overlappingPathsCheck(fctx context.Context, fs1, fs2 fs.Fs) error {
if operations.OverlappingFilterCheck(fctx, fs2, fs1) {
err = fmt.Errorf(Color(terminal.RedFg, "Overlapping paths detected. Cannot bisync between paths that overlap, unless excluded by filters."))
return err
}
// need to test our BackupDirs too, as sync will be fooled by our --files-from filters
testBackupDir := func(ctx context.Context, destPath int) error {
src := fs1
dst := fs2
if destPath == 1 {
src = fs2
dst = fs1
}
ctxBackupDir := b.setBackupDir(ctx, destPath)
ci := fs.GetConfig(ctxBackupDir)
if ci.BackupDir != "" {
// operations.BackupDir should return an error if not properly excluded
_, err = operations.BackupDir(fctx, dst, src, "")
return err
}
return nil
}
err = testBackupDir(fctx, 1)
if err != nil {
return err
}
err = testBackupDir(fctx, 2)
if err != nil {
return err
}
return nil
}
func (b *bisyncRun) debug(nametocheck, msgiftrue string) {
if b.DebugName != "" && b.DebugName == nametocheck {
fs.Infof(Color(terminal.MagentaBg, "DEBUGNAME "+b.DebugName), Color(terminal.MagentaBg, msgiftrue))