(bugfix) Guard dry-run logs and recursive rsync defaults

Clear the reused dry-run rsync log before each dry-run so run details
only show output from the current execution.

Populate new Django global configs with the existing safe rsync and
exclude defaults, including archive mode and standard pseudo-filesystem
exclusions.

Add a host check that fails when effective rsync args do not include
archive or recursive transfer, preventing real backups that only report
"skipping directory .".
This commit is contained in:
2026-05-19 20:09:35 +02:00
parent 8bd2a8ff1a
commit 7e5d31d53b
5 changed files with 61 additions and 0 deletions

View File

@@ -67,6 +67,28 @@ class RunScheduledConfigSourceTests(SimpleTestCase):
self.assertEqual(result["rsync"]["exit_code"], 12)
self.assertEqual(result["rsync"]["log_tail"], ["Permission denied (publickey).", "rsync error"])
def test_dry_run_clears_previous_log_before_running(self) -> None:
def fake_run_rsync(command, log_path, timeout_seconds):
self.assertFalse(log_path.exists())
log_path.parent.mkdir(parents=True, exist_ok=True)
log_path.write_text("current run only\n", encoding="utf-8")
return RsyncResult(exit_code=0, command=command)
old_log = Path("/tmp/pobsync-dryrun/web-01/rsync.log")
old_log.parent.mkdir(parents=True, exist_ok=True)
old_log.write_text("old failure\n", encoding="utf-8")
with patch("pobsync.commands.run_scheduled.run_rsync", side_effect=fake_run_rsync):
result = run_scheduled(
prefix=Path("/missing-prefix"),
host="web-01",
dry_run=True,
config_source=FakeConfigSource(),
)
self.assertTrue(result["ok"])
self.assertEqual(result["rsync"]["log_tail"], ["current run only"])
def test_successful_real_run_applies_prune_when_requested(self) -> None:
with TemporaryDirectory() as tmp:
prefix = Path(tmp) / "home"