From 86873bd0352af9dfa71b455eb474b8547c5e144c Mon Sep 17 00:00:00 2001 From: Peter van Arkel Date: Thu, 21 May 2026 02:46:09 +0200 Subject: [PATCH] (refactor) Remove obsolete global config JSON storage Drop the unused GlobalConfig.data field and remove the remaining YAML config path helpers from PobsyncPaths. Keep HostConfig.config as runtime state for preflight data, and relabel it in the admin so it no longer reads as legacy compatibility storage. --- src/pobsync/commands/run_scheduled.py | 1 - src/pobsync/config/schemas.py | 1 - src/pobsync/paths.py | 13 ------------- src/pobsync_backend/admin.py | 3 +-- .../migrations/0011_remove_globalconfig_data.py | 14 ++++++++++++++ src/pobsync_backend/models.py | 1 - src/pobsync_backend/tests/test_admin.py | 6 ++++-- .../tests/test_config_repository.py | 6 ------ .../tests/test_django_config_source.py | 14 -------------- 9 files changed, 19 insertions(+), 40 deletions(-) create mode 100644 src/pobsync_backend/migrations/0011_remove_globalconfig_data.py diff --git a/src/pobsync/commands/run_scheduled.py b/src/pobsync/commands/run_scheduled.py index 4a321b0..1cd76c9 100644 --- a/src/pobsync/commands/run_scheduled.py +++ b/src/pobsync/commands/run_scheduled.py @@ -317,7 +317,6 @@ def run_scheduled( "duration_seconds": None, "base": _base_meta_from_path(base_dir, link_dest), "rsync": {"exit_code": None, "command": cmd, "stats": {}}, - # Keep existing fields for future expansion / compatibility with current structure. "overrides": {"includes": [], "excludes": [], "base": None}, } diff --git a/src/pobsync/config/schemas.py b/src/pobsync/config/schemas.py index c8baa1c..e840965 100644 --- a/src/pobsync/config/schemas.py +++ b/src/pobsync/config/schemas.py @@ -94,7 +94,6 @@ GLOBAL_SCHEMA = Schema( ), "logging": FieldSpec(dict, required=False, schema=LOGGING_SCHEMA), "output": FieldSpec(dict, required=False, schema=OUTPUT_SCHEMA), - # Used by `init-host` as a convenience default "retention_defaults": FieldSpec( dict, required=False, diff --git a/src/pobsync/paths.py b/src/pobsync/paths.py index 28151db..e57a554 100644 --- a/src/pobsync/paths.py +++ b/src/pobsync/paths.py @@ -8,14 +8,6 @@ from pathlib import Path class PobsyncPaths: home: Path # usually /opt/pobsync - @property - def config_dir(self) -> Path: - return self.home / "config" - - @property - def hosts_dir(self) -> Path: - return self.config_dir / "hosts" - @property def state_dir(self) -> Path: return self.home / "state" @@ -28,11 +20,6 @@ class PobsyncPaths: def logs_dir(self) -> Path: return self.home / "logs" - @property - def global_config_path(self) -> Path: - return self.config_dir / "global.yaml" - @property def central_log_path(self) -> Path: return self.logs_dir / "pobsync.log" - diff --git a/src/pobsync_backend/admin.py b/src/pobsync_backend/admin.py index 708ae5a..327ecb0 100644 --- a/src/pobsync_backend/admin.py +++ b/src/pobsync_backend/admin.py @@ -50,7 +50,6 @@ class GlobalConfigAdmin(admin.ModelAdmin): ), ("Defaults", {"fields": ("default_source_root", "default_destination_subdir", "excludes_default")}), ("Retention defaults", {"fields": ("retention_daily", "retention_weekly", "retention_monthly", "retention_yearly")}), - ("Compatibility data", {"fields": ("data",), "classes": ("collapse",)}), ("Timestamps", {"fields": ("created_at", "updated_at"), "classes": ("collapse",)}), ) @@ -76,7 +75,7 @@ class HostConfigAdmin(admin.ModelAdmin): ("Source", {"fields": ("source_root", "includes", "excludes_add", "excludes_replace")}), ("Rsync override", {"fields": ("rsync_extra_args",)}), ("Retention", {"fields": ("retention_daily", "retention_weekly", "retention_monthly", "retention_yearly")}), - ("Compatibility data", {"fields": ("config",), "classes": ("collapse",)}), + ("Runtime state", {"fields": ("config",), "classes": ("collapse",)}), ("Timestamps", {"fields": ("created_at", "updated_at"), "classes": ("collapse",)}), ) diff --git a/src/pobsync_backend/migrations/0011_remove_globalconfig_data.py b/src/pobsync_backend/migrations/0011_remove_globalconfig_data.py new file mode 100644 index 0000000..4f41a1f --- /dev/null +++ b/src/pobsync_backend/migrations/0011_remove_globalconfig_data.py @@ -0,0 +1,14 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("pobsync_backend", "0010_remove_globalconfig_pobsync_home"), + ] + + operations = [ + migrations.RemoveField( + model_name="globalconfig", + name="data", + ), + ] diff --git a/src/pobsync_backend/models.py b/src/pobsync_backend/models.py index c97ffe3..93faa50 100644 --- a/src/pobsync_backend/models.py +++ b/src/pobsync_backend/models.py @@ -36,7 +36,6 @@ class GlobalConfig(TimestampedModel): retention_weekly = models.PositiveIntegerField(default=8) retention_monthly = models.PositiveIntegerField(default=12) retention_yearly = models.PositiveIntegerField(default=0) - data = models.JSONField(default=dict, blank=True) class Meta: verbose_name = "global config" diff --git a/src/pobsync_backend/tests/test_admin.py b/src/pobsync_backend/tests/test_admin.py index c87d707..29a05bc 100644 --- a/src/pobsync_backend/tests/test_admin.py +++ b/src/pobsync_backend/tests/test_admin.py @@ -10,7 +10,7 @@ from pobsync_backend.models import BackupRun, GlobalConfig, HostConfig, Schedule class AdminDisplayTests(TestCase): - def test_admin_hides_old_global_state_field_and_uses_compatibility_label(self) -> None: + def test_admin_hides_old_global_state_fields_and_labels_host_runtime_state(self) -> None: site = AdminSite() global_admin = GlobalConfigAdmin(GlobalConfig, site) host_admin = HostConfigAdmin(HostConfig, site) @@ -21,7 +21,9 @@ class AdminDisplayTests(TestCase): fieldset_names = [name for name, _options in [*global_fieldsets, *host_fieldsets]] self.assertNotIn("pobsync_home", global_fields) - self.assertIn("Compatibility data", fieldset_names) + self.assertNotIn("data", global_fields) + self.assertIn("Runtime state", fieldset_names) + self.assertNotIn("Compatibility data", fieldset_names) self.assertNotIn("Legacy JSON", fieldset_names) def test_host_admin_links_to_related_snapshots_and_runs(self) -> None: diff --git a/src/pobsync_backend/tests/test_config_repository.py b/src/pobsync_backend/tests/test_config_repository.py index 64d32d1..e25f366 100644 --- a/src/pobsync_backend/tests/test_config_repository.py +++ b/src/pobsync_backend/tests/test_config_repository.py @@ -19,12 +19,6 @@ class ConfigRepositoryTests(TestCase): retention_weekly=4, retention_monthly=3, retention_yearly=1, - data={ - "backup_root": "/ignored", - "ssh": {"user": "ignored", "port": 22, "options": []}, - "unknown": "must-not-leak", - "retention_defaults": {"daily": 99, "weekly": 99, "monthly": 99, "yearly": 99}, - }, ) HostConfig.objects.create( host="web-01", diff --git a/src/pobsync_backend/tests/test_django_config_source.py b/src/pobsync_backend/tests/test_django_config_source.py index 0dbc549..6070061 100644 --- a/src/pobsync_backend/tests/test_django_config_source.py +++ b/src/pobsync_backend/tests/test_django_config_source.py @@ -22,20 +22,6 @@ class DjangoConfigSourceTests(TestCase): retention_weekly=4, retention_monthly=3, retention_yearly=1, - data={ - "backup_root": "/ignored", - "ssh": {"user": "root", "port": 22, "options": []}, - "rsync": { - "binary": "rsync", - "args": ["--archive"], - "timeout_seconds": 0, - "bwlimit_kbps": 0, - "extra_args": ["--numeric-ids"], - }, - "defaults": {"source_root": "/", "destination_subdir": ""}, - "excludes_default": ["/proc/***"], - "retention_defaults": {"daily": 7, "weekly": 4, "monthly": 3, "yearly": 1}, - }, ) HostConfig.objects.create( host="web-01",