Drop the pre-Django YAML import/export management commands and remove the
file-based config loader fallback from the backup and retention engines.
Keep the runtime config bridge backed by Django models, and add tests that
ensure engine operations require an explicit Django config source.
Record the final rsync log path for successful real backup runs, matching
the existing dry-run and failure result payloads.
Add a staff-only run log endpoint and surface the link on run detail pages,
including fallback log discovery for older runs based on snapshot_path.
Cover direct log links and inferred scheduled backup logs with view tests.
Parse rsync --stats output into structured run metrics for file counts,
transferred bytes, literal data, matched data, speedup, and estimated
link-dest savings.
Store collected stats on backup run results and successful snapshot metadata,
including snapshot data usage and backup-root capacity details for future
dashboard graphs and disk-full projections.
Render the collected metrics on run and snapshot detail pages, with tests
covering parsing, metadata persistence, and UI output.
Expose a verbose rsync output option in the Django manual backup form and
store the selected value with the queued run request.
Propagate the option through the worker, direct management command, and
rsync command builder so real backups can emit itemized changes, file-list
progress, and stats when requested. Dry-runs continue to use verbose output
by default and report that consistently in requested options.
Cover the queue, worker, view, and rsync command behavior with focused
tests.
Classify rsync failures in run results so transport issues such as exit
255 and broken pipes show clearer diagnostic hints.
Teach the worker to reconcile running dry-runs when their log already
contains a terminal rsync error, and to fail stale dry-runs after their
timeout window. This prevents failed rsync processes from leaving runs
stuck in the running state indefinitely.
Add default dry-run rsync output flags so long-running dry-runs expose
file-list, progress, stats, and itemized change information in their
run-specific log files.
Avoid duplicating user-supplied itemize or --info arguments so operators
can still tune rsync output from global or host configuration.
Add a cancel action for queued and running backup runs. Queued runs are
cancelled immediately, while running runs are marked for cancellation and
the worker terminates the active rsync process group.
Make dry-run log paths run-specific and add a defensive default dry-run
timeout so stuck dry-runs do not remain running indefinitely.
Remove rsync exit codes from run overview tables while keeping detailed
diagnostics available on the run detail payload.
Clear the reused dry-run rsync log before each dry-run so run details
only show output from the current execution.
Populate new Django global configs with the existing safe rsync and
exclude defaults, including archive mode and standard pseudo-filesystem
exclusions.
Add a host check that fails when effective rsync args do not include
archive or recursive transfer, preventing real backups that only report
"skipping directory .".
Include the selected SSH credential metadata and rsync log tail in
dry-run and failed backup results so Django shows the actual SSH or
rsync failure instead of only the exit code.
Warn in host checks when a host still uses database-stored private key
material, making it easier to spot old credentials after switching to
generated filesystem keys.
Introduce a ConfigSource interface so scheduled backups no longer need
to load host configuration directly from runtime YAML. Add a Django-backed
config source for SQL-driven backup runs, keep file-based config as the
CLI default, and make scheduled prune execution actually apply retention
after successful runs.