Files
pobsync/src/pobsync_backend/migrations/0003_structured_config_fields.py
Peter van Arkel a0eb5dcc8f refactor: promote backup configuration to structured SQL fields
Add explicit Django model fields for global and host backup settings,
including SSH, rsync, source, excludes, and retention configuration.
Populate them from legacy JSON during migration, make the config
repository prefer structured fields, and update import/admin/tests around
the SQL-first configuration model.
2026-05-19 05:04:49 +02:00

192 lines
7.5 KiB
Python

from __future__ import annotations
from django.db import migrations, models
def copy_json_config_to_fields(apps, schema_editor) -> None:
GlobalConfig = apps.get_model("pobsync_backend", "GlobalConfig")
HostConfig = apps.get_model("pobsync_backend", "HostConfig")
for global_config in GlobalConfig.objects.all():
data = global_config.data or {}
ssh = data.get("ssh") or {}
rsync = data.get("rsync") or {}
defaults = data.get("defaults") or {}
retention = data.get("retention_defaults") or {}
global_config.ssh_user = ssh.get("user") or global_config.ssh_user
global_config.ssh_port = ssh.get("port") or global_config.ssh_port
global_config.ssh_options = ssh.get("options") or []
global_config.rsync_binary = rsync.get("binary") or global_config.rsync_binary
global_config.rsync_args = rsync.get("args") or []
global_config.rsync_extra_args = rsync.get("extra_args") or []
global_config.rsync_timeout_seconds = rsync.get("timeout_seconds") or 0
global_config.rsync_bwlimit_kbps = rsync.get("bwlimit_kbps") or 0
global_config.default_source_root = defaults.get("source_root") or "/"
global_config.default_destination_subdir = defaults.get("destination_subdir") or ""
global_config.excludes_default = data.get("excludes_default") or []
global_config.retention_daily = retention.get("daily", global_config.retention_daily)
global_config.retention_weekly = retention.get("weekly", global_config.retention_weekly)
global_config.retention_monthly = retention.get("monthly", global_config.retention_monthly)
global_config.retention_yearly = retention.get("yearly", global_config.retention_yearly)
global_config.save()
for host_config in HostConfig.objects.all():
config = host_config.config or {}
ssh = config.get("ssh") or {}
rsync = config.get("rsync") or {}
retention = config.get("retention") or {}
host_config.ssh_user = ssh.get("user") or ""
host_config.ssh_port = ssh.get("port")
host_config.source_root = config.get("source_root") or ""
host_config.includes = config.get("includes") or []
host_config.excludes_add = config.get("excludes_add") or []
host_config.excludes_replace = config.get("excludes_replace")
host_config.rsync_extra_args = rsync.get("extra_args") or []
host_config.retention_daily = retention.get("daily", host_config.retention_daily)
host_config.retention_weekly = retention.get("weekly", host_config.retention_weekly)
host_config.retention_monthly = retention.get("monthly", host_config.retention_monthly)
host_config.retention_yearly = retention.get("yearly", host_config.retention_yearly)
host_config.save()
class Migration(migrations.Migration):
dependencies = [
("pobsync_backend", "0002_schedule_run_state"),
]
operations = [
migrations.AddField(
model_name="globalconfig",
name="default_destination_subdir",
field=models.CharField(blank=True, default="", max_length=512),
),
migrations.AddField(
model_name="globalconfig",
name="default_source_root",
field=models.CharField(default="/", max_length=512),
),
migrations.AddField(
model_name="globalconfig",
name="excludes_default",
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name="globalconfig",
name="retention_daily",
field=models.PositiveIntegerField(default=14),
),
migrations.AddField(
model_name="globalconfig",
name="retention_monthly",
field=models.PositiveIntegerField(default=12),
),
migrations.AddField(
model_name="globalconfig",
name="retention_weekly",
field=models.PositiveIntegerField(default=8),
),
migrations.AddField(
model_name="globalconfig",
name="retention_yearly",
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name="globalconfig",
name="rsync_args",
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name="globalconfig",
name="rsync_binary",
field=models.CharField(default="rsync", max_length=128),
),
migrations.AddField(
model_name="globalconfig",
name="rsync_bwlimit_kbps",
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name="globalconfig",
name="rsync_extra_args",
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name="globalconfig",
name="rsync_timeout_seconds",
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name="globalconfig",
name="ssh_options",
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name="globalconfig",
name="ssh_port",
field=models.PositiveIntegerField(default=22),
),
migrations.AddField(
model_name="globalconfig",
name="ssh_user",
field=models.CharField(default="root", max_length=64),
),
migrations.AddField(
model_name="hostconfig",
name="excludes_add",
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name="hostconfig",
name="excludes_replace",
field=models.JSONField(blank=True, null=True),
),
migrations.AddField(
model_name="hostconfig",
name="includes",
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name="hostconfig",
name="retention_daily",
field=models.PositiveIntegerField(default=14),
),
migrations.AddField(
model_name="hostconfig",
name="retention_monthly",
field=models.PositiveIntegerField(default=12),
),
migrations.AddField(
model_name="hostconfig",
name="retention_weekly",
field=models.PositiveIntegerField(default=8),
),
migrations.AddField(
model_name="hostconfig",
name="retention_yearly",
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name="hostconfig",
name="rsync_extra_args",
field=models.JSONField(blank=True, default=list),
),
migrations.AddField(
model_name="hostconfig",
name="source_root",
field=models.CharField(blank=True, max_length=512),
),
migrations.AddField(
model_name="hostconfig",
name="ssh_port",
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name="hostconfig",
name="ssh_user",
field=models.CharField(blank=True, max_length=64),
),
migrations.RunPython(copy_json_config_to_fields, migrations.RunPython.noop),
]