(bugfix) preserve saved global backup root in Django setup form

Fix the global config edit view so default initial values are only used
when creating a new config, preventing saved backup_root values from
being hidden by form defaults.

Keep pobsync_home as an internal runtime setting instead of exposing it
in the normal Django setup form.

Mount a host backup directory into Docker at /backups and document
POBSYNC_BACKUP_ROOT so backup_root behaves predictably in containers.
This commit is contained in:
2026-05-19 12:48:32 +02:00
parent 66e1f549b9
commit aea22597ba
6 changed files with 42 additions and 7 deletions

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from django import forms
from django.conf import settings
from .models import GlobalConfig, HostConfig, ScheduleConfig
from .scheduler import parse_cron_expr
@@ -84,7 +85,6 @@ class GlobalConfigForm(forms.ModelForm):
fields = (
"name",
"backup_root",
"pobsync_home",
"ssh_user",
"ssh_port",
"ssh_options",
@@ -104,11 +104,18 @@ class GlobalConfigForm(forms.ModelForm):
help_texts = {
"name": "Usually 'default'. The backup engine currently reads the default config.",
"backup_root": "Directory that contains host backup folders.",
"pobsync_home": "Base directory for runtime state inside the container or host.",
"default_source_root": "Used by hosts without a custom source root.",
"default_destination_subdir": "Optional subdirectory below each snapshot.",
}
def save(self, commit: bool = True):
instance = super().save(commit=False)
instance.pobsync_home = settings.POBSYNC_HOME
if commit:
instance.save()
self.save_m2m()
return instance
class ScheduleConfigForm(forms.ModelForm):
cron_expr = forms.CharField(

View File

@@ -76,7 +76,6 @@ class ViewTests(TestCase):
{
"name": "default",
"backup_root": "/backups",
"pobsync_home": "/opt/pobsync",
"ssh_user": "backup",
"ssh_port": "2222",
"ssh_options": "StrictHostKeyChecking=no\nBatchMode=yes",
@@ -100,6 +99,7 @@ class ViewTests(TestCase):
self.assertContains(response, "Global config saved for default.")
config = GlobalConfig.objects.get(name="default")
self.assertEqual(config.backup_root, "/backups")
self.assertEqual(config.pobsync_home, "/opt/pobsync")
self.assertEqual(config.ssh_user, "backup")
self.assertEqual(config.ssh_port, 2222)
self.assertEqual(config.ssh_options, ["StrictHostKeyChecking=no", "BatchMode=yes"])
@@ -109,6 +109,21 @@ class ViewTests(TestCase):
self.assertEqual(config.retention_daily, 7)
self.assertEqual(config.retention_yearly, 1)
def test_global_config_form_renders_saved_backup_root_on_edit(self) -> None:
self.client.force_login(self.staff_user)
GlobalConfig.objects.create(
name="default",
backup_root="/mnt/pobsync/backups",
pobsync_home="/custom/legacy/home",
)
response = self.client.get(reverse("edit_global_config"))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "/mnt/pobsync/backups")
self.assertNotContains(response, "/opt/pobsync/backups")
self.assertNotContains(response, "Pobsync home")
def test_create_host_config_form_creates_host(self) -> None:
self.client.force_login(self.staff_user)
@@ -196,7 +211,7 @@ class ViewTests(TestCase):
self.assertContains(response, "web-01")
self.assertContains(response, "success")
self.assertContains(response, "ABCDEFGH")
self.assertContains(response, '"ok": true')
self.assertContains(response, ""ok": true")
self.assertContains(response, reverse("snapshot_detail", args=[snapshot.id]))
def test_snapshot_detail_renders_metadata_runs_and_children(self) -> None:

View File

@@ -51,7 +51,7 @@ def edit_global_config(request):
messages.success(request, f"Global config saved for {saved_config.name}.")
return redirect("dashboard")
else:
form = GlobalConfigForm(instance=global_config, initial=_default_global_initial())
form = GlobalConfigForm(instance=global_config) if global_config else GlobalConfigForm(initial=_default_global_initial())
return render(
request,
@@ -235,8 +235,7 @@ def _default_schedule_initial() -> dict[str, object]:
def _default_global_initial() -> dict[str, object]:
return {
"name": "default",
"backup_root": "/opt/pobsync/backups",
"pobsync_home": "/opt/pobsync",
"backup_root": "/backups",
"ssh_user": "root",
"ssh_port": 22,
"rsync_binary": "rsync",