(refactor) Normalize maintainer command labels

Prefer --schedule-expression for scripted schedule updates while keeping
--cron as a compatibility alias.

Clean up management command help, errors, and output so operator-facing
text talks about hosts, global config, and Django backup configuration
instead of model names or old SQL-backed pobsync wording.
This commit is contained in:
2026-05-21 02:52:42 +02:00
parent 86873bd035
commit 1c8cbd96ca
8 changed files with 26 additions and 20 deletions

View File

@@ -11,7 +11,7 @@ from pobsync_backend.models import GlobalConfig
class Command(BaseCommand):
help = "Create or update the SQL-backed global pobsync configuration."
help = "Create or update the default global backup configuration."
def add_arguments(self, parser) -> None:
parser.add_argument("--name", default="default")
@@ -48,8 +48,8 @@ class Command(BaseCommand):
}
if GlobalConfig.objects.filter(name=options["name"]).exists() and not options["force"]:
raise CommandError(f"GlobalConfig {options['name']!r} already exists; use --force to update")
raise CommandError(f"Global config {options['name']!r} already exists; use --force to update")
_obj, created = GlobalConfig.objects.update_or_create(name=options["name"], defaults=defaults)
action = "Created" if created else "Updated"
self.stdout.write(self.style.SUCCESS(f"{action} GlobalConfig {options['name']!r}."))
self.stdout.write(self.style.SUCCESS(f"{action} global config {options['name']!r}."))

View File

@@ -10,7 +10,7 @@ from pobsync_backend.models import GlobalConfig, HostConfig
class Command(BaseCommand):
help = "Create or update a SQL-backed host pobsync configuration."
help = "Create or update a host backup configuration."
def add_arguments(self, parser) -> None:
parser.add_argument("host")
@@ -29,7 +29,7 @@ class Command(BaseCommand):
def handle(self, *args: Any, **options: Any) -> None:
host = sanitize_host(options["host"])
if HostConfig.objects.filter(host=host).exists() and not options["force"]:
raise CommandError(f"HostConfig {host!r} already exists; use --force to update")
raise CommandError(f"Host {host!r} already exists; use --force to update")
retention = self._retention(options["retention"])
defaults = {
@@ -49,7 +49,7 @@ class Command(BaseCommand):
}
_obj, created = HostConfig.objects.update_or_create(host=host, defaults=defaults)
action = "Created" if created else "Updated"
self.stdout.write(self.style.SUCCESS(f"{action} HostConfig {host!r}."))
self.stdout.write(self.style.SUCCESS(f"{action} host {host!r}."))
def _retention(self, value: str | None) -> dict[str, int]:
if value:

View File

@@ -9,11 +9,16 @@ from pobsync_backend.scheduler import parse_cron_expr
class Command(BaseCommand):
help = "Create, update, disable, or remove a SQL-backed pobsync schedule."
help = "Create, update, disable, or remove a scheduler-managed host schedule."
def add_arguments(self, parser) -> None:
parser.add_argument("host")
parser.add_argument("--cron", help='Cron expression, e.g. "15 2 * * *"')
parser.add_argument(
"--schedule-expression",
"--cron",
dest="schedule_expression",
help='Five-field schedule expression, e.g. "15 2 * * *"',
)
parser.add_argument("--prune", action="store_true")
parser.add_argument("--prune-max-delete", type=int, default=10)
parser.add_argument("--prune-protect-bases", action="store_true")
@@ -24,24 +29,25 @@ class Command(BaseCommand):
try:
host = HostConfig.objects.get(host=options["host"])
except HostConfig.DoesNotExist as exc:
raise CommandError(f"Missing HostConfig {options['host']!r}") from exc
raise CommandError(f"Missing host {options['host']!r}") from exc
if options["delete"]:
deleted, _details = ScheduleConfig.objects.filter(host=host).delete()
self.stdout.write(self.style.SUCCESS(f"Deleted {deleted} schedule row(s) for {host.host!r}."))
return
if not options["cron"]:
raise CommandError("--cron is required unless --delete is used")
schedule_expression = options["schedule_expression"]
if not schedule_expression:
raise CommandError("--schedule-expression is required unless --delete is used")
try:
parse_cron_expr(options["cron"])
parse_cron_expr(schedule_expression)
except ValueError as exc:
raise CommandError(str(exc)) from exc
schedule, created = ScheduleConfig.objects.update_or_create(
host=host,
defaults={
"cron_expr": options["cron"],
"cron_expr": schedule_expression,
"enabled": not options["disabled"],
"prune": bool(options["prune"]),
"prune_max_delete": int(options["prune_max_delete"]),

View File

@@ -20,14 +20,14 @@ class Command(BaseCommand):
try:
global_config = GlobalConfig.objects.get(name="default")
except GlobalConfig.DoesNotExist as exc:
raise CommandError("Missing GlobalConfig 'default'") from exc
raise CommandError("Missing default global config") from exc
host = None
if options["host"]:
try:
host = HostConfig.objects.get(host=options["host"], enabled=True)
except HostConfig.DoesNotExist as exc:
raise CommandError(f"Missing enabled HostConfig {options['host']!r}") from exc
raise CommandError(f"Missing enabled host {options['host']!r}") from exc
kind = normalize_kind(options["kind"])
kinds = ["scheduled", "manual", "incomplete"] if kind == "all" else [kind]

View File

@@ -30,7 +30,7 @@ class Command(BaseCommand):
try:
host = HostConfig.objects.get(host=host_name, enabled=True)
except HostConfig.DoesNotExist as exc:
raise CommandError(f"Missing enabled HostConfig {host_name!r}") from exc
raise CommandError(f"Missing enabled host {host_name!r}") from exc
run = BackupRun.objects.create(
host=host,

View File

@@ -12,7 +12,7 @@ from pobsync_backend.retention import run_sql_retention_apply, run_sql_retention
class Command(BaseCommand):
help = "Plan or apply retention using SQL-backed pobsync configuration."
help = "Plan or apply retention using the Django backup configuration."
def add_arguments(self, parser) -> None:
parser.add_argument("host")

View File

@@ -23,7 +23,7 @@ class ConfigureCommandsTests(TestCase):
config = GlobalConfig.objects.get(name="default")
self.assertEqual(config.backup_root, "/backups")
self.assertEqual(config.retention_daily, 3)
self.assertIn("Created GlobalConfig", out.getvalue())
self.assertIn("Created global config", out.getvalue())
def test_configure_host_uses_global_retention_defaults(self) -> None:
GlobalConfig.objects.create(
@@ -61,7 +61,7 @@ class ConfigureCommandsTests(TestCase):
call_command(
"configure_pobsync_schedule",
host.host,
cron="15 2 * * *",
schedule_expression="15 2 * * *",
prune=True,
stdout=out,
)