## Summary

- Add per-host rsync bandwidth limit overrides with inherit/unlimited semantics.
- Store the effective bwlimit in run metadata/results and show it in host/run detail views.
- Document recommended starting values for VPN and remote backups.

## Tests
- `.venv/bin/python manage.py makemigrations --check --dry-run`
- `.venv/bin/python manage.py test src.pobsync_backend.tests.test_django_config_source.DjangoConfigSourceTests.test_returns_effective_config_from_database src.pobsync_backend.tests.test_django_config_source.DjangoConfigSourceTests.test_host_can_disable_global_rsync_bandwidth_limit src.pobsync_backend.tests.test_configure_commands.ConfigureCommandsTests.test_configure_host_uses_global_retention_defaults src.pobsync_backend.tests.test_run_scheduled_config_source.RunScheduledConfigSourceTests.test_dry_run_applies_configured_bandwidth_limit src.pobsync_backend.tests.test_run_scheduled_config_source.RunScheduledConfigSourceTests.test_real_run_can_request_verbose_output_args --verbosity 2`
- `.venv/bin/python manage.py test src.pobsync_backend.tests.test_views.ViewTests.test_create_host_config_form_creates_host src.pobsync_backend.tests.test_views.ViewTests.test_host_detail_renders_effective_config_preview src.pobsync_backend.tests.test_views.ViewTests.test_run_detail_renders_result_payload src.pobsync_backend.tests.test_views.ViewTests.test_host_config_form_updates_host_config --verbosity 2`
- `.venv/bin/python manage.py check`

Closes #51
This commit is contained in:
2026-05-23 00:59:55 +02:00
parent fdf401a0be
commit 515330c436
16 changed files with 136 additions and 13 deletions

View File

@@ -921,6 +921,7 @@ class ViewTests(TestCase):
"excludes_add": "*.tmp",
"excludes_replace": "",
"rsync_extra_args": "--numeric-ids",
"rsync_bwlimit_kbps": "4096",
"retention_daily": "7",
"retention_weekly": "4",
"retention_monthly": "2",
@@ -938,6 +939,7 @@ class ViewTests(TestCase):
self.assertEqual(host.includes, ["/srv/www", "/srv/db"])
self.assertEqual(host.excludes_add, ["*.tmp"])
self.assertEqual(host.rsync_extra_args, ["--numeric-ids"])
self.assertEqual(host.rsync_bwlimit_kbps, 4096)
self.assertEqual(host.retention_weekly, 4)
def test_create_host_config_uses_global_defaults_and_prepares_directories(self) -> None:
@@ -1077,6 +1079,7 @@ class ViewTests(TestCase):
self.assertContains(response, "default-key")
self.assertContains(response, "-oBatchMode=yes")
self.assertContains(response, "--archive --numeric-ids --delete --one-file-system")
self.assertContains(response, "2048 KB/s")
self.assertContains(response, "/srv/www/***")
self.assertContains(response, "/srv/www/cache/***")
self.assertContains(response, "d14")
@@ -1473,9 +1476,10 @@ class ViewTests(TestCase):
"ok": True,
"snapshot": snapshot.path,
"rsync": {
"command": ["rsync", "--archive", "root@web-01:/", snapshot.path],
"command": ["rsync", "--archive", "--bwlimit=2048", "root@web-01:/", snapshot.path],
"exit_code": 0,
"log_tail": ["sending incremental file list", "sent 500 bytes"],
"bwlimit_kbps": 2048,
},
"requested": {
"dry_run": True,
@@ -1510,6 +1514,8 @@ class ViewTests(TestCase):
self.assertContains(response, "Dry run:</strong> yes")
self.assertContains(response, "Verbose rsync output:</strong> yes")
self.assertContains(response, "Rsync Command")
self.assertContains(response, "Bandwidth limit:</strong>")
self.assertContains(response, "2048 KB/s")
self.assertContains(response, "--archive")
self.assertContains(response, "Rsync Log")
self.assertContains(response, "sending incremental file list")
@@ -2464,6 +2470,7 @@ class ViewTests(TestCase):
"excludes_add": "*.tmp\ncache/",
"excludes_replace": "",
"rsync_extra_args": "--numeric-ids\n--delete",
"rsync_bwlimit_kbps": "8192",
"retention_daily": "7",
"retention_weekly": "4",
"retention_monthly": "2",
@@ -2483,6 +2490,7 @@ class ViewTests(TestCase):
self.assertEqual(host.excludes_add, ["*.tmp", "cache/"])
self.assertIsNone(host.excludes_replace)
self.assertEqual(host.rsync_extra_args, ["--numeric-ids", "--delete"])
self.assertEqual(host.rsync_bwlimit_kbps, 8192)
self.assertEqual(host.retention_daily, 7)
self.assertEqual(host.retention_yearly, 1)