Commit Graph

52 Commits

Author SHA1 Message Date
4e8e4f75fd (ui) Add dashboard-linked run and snapshot lists
Add staff-only list pages for backup runs and snapshots with practical
filters, then wire the dashboard summary cards and latest-runs panel to
those overviews.

This gives the dashboard real drill-down paths for run and snapshot counts
instead of leaving the data only partially visible on the first screen.

Refs #23
2026-05-21 11:52:35 +02:00
ea9e3e41e3 (release) Add purged snapshot audit overview
Record snapshot purge history whenever retention or incomplete cleanup removes
snapshot directories and SQL records. Store the purge reason, original kind,
path, action source, and triggering operator so manual, scheduled, CLI, and
incomplete cleanup actions remain auditable after the original snapshot record
is deleted.

Add a staff-only Purged Snapshots page with host/action filters and register
the audit model in Django admin.

Refs #16
Refs #8
2026-05-21 03:46:38 +02:00
5b5a5bc637 (release) Harden SSH key edit and delete flow
Make SSH credential management more explicit by adding an edit action in the
key overview and requiring name confirmation before deletion. Keep deletion
blocked while a key is still selected by hosts or global config, and cover
rename, delete confirmation, and in-use protection in view tests.

Refs #20
Refs #8
2026-05-21 03:38:55 +02:00
c2e5a534aa (release) Add review resolution for operational tasks
Add reviewed state for failed/warning runs and incomplete snapshot records,
then use it to clear dashboard and host “need review” tasks after an operator
has acknowledged them.

Expose Mark reviewed actions on run detail and host retention warnings, keep
reviewed records available for audit/debug, and exclude reviewed problem runs
from operational counts and latest issue summaries.

Refs #19
Refs #8
2026-05-21 03:34:41 +02:00
d0c23deb72 (release) Add explicit incomplete snapshot cleanup
Add a dedicated cleanup path for incomplete snapshots instead of letting
retention prune them implicitly. The retention plan now exposes a guarded
form that requires host and delete-count confirmation before removing
.incomplete snapshot directories and their SQL records.

Keep scheduled/manual retention behavior unchanged, add path safety checks,
and cover cleanup success, confirmation failures, max-delete limits, and
unexpected paths in tests.

Refs #10
2026-05-21 03:26:21 +02:00
4c8ed24561 (release) Track worker heartbeat for running jobs
Record worker pid, host, claim time, and heartbeat metadata on running
backup jobs so operators can see which worker owns a run.

Refresh the heartbeat while rsync is active and reconcile stale running
runs when the worker heartbeat stops. Add a worker option to tune or
disable stale-run reconciliation.

Refs #11
2026-05-21 03:16:38 +02:00
404b7f7500 (release) Add Django changelog page
Expose the repository CHANGELOG.md through a staff-only Django view and
link it from the main navigation.

Render a small safe subset of Markdown without adding a runtime dependency,
copy the changelog into the Docker image, and cover the page with view tests.
2026-05-21 03:10:31 +02:00
20a9f93378 (docs) Add targeted restore examples
Extend the restore guidance with directory and single-file dry-run
examples so operators can restore a focused path without copying an
entire snapshot.

Render the examples on snapshot detail pages using the selected
snapshot's data path and the host-specific staging destination.
2026-05-21 02:05:19 +02:00
b78f102e9d (docs) Add manual restore guidance for snapshots
Document the manual restore workflow in the README and surface snapshot-
specific restore commands on the snapshot detail page.

The guidance keeps restores intentionally manual for now: inspect the
snapshot data directory, run rsync with --dry-run, restore to staging
first, and treat hardlinked snapshot files as read-only.
2026-05-21 02:01:40 +02:00
a0fd33fcb8 (ui) Improve dashboard host card scanability
Add per-host status chips for queued, running, warning, and failed runs so
the dashboard shows operational pressure without needing to open each host.

Restructure host cards into clearer backup activity and snapshot health
sections, with less visual clutter and better mobile wrapping.
2026-05-21 01:41:45 +02:00
ef1761385e (ui) Separate healthy and problematic dashboard runs
Split dashboard host cards into last successful backup and latest warning
or failed run so operators can quickly see whether a host is protected even
when recent activity produced an issue.

Also add queued and warning run counts to the dashboard summary metrics.
2026-05-21 01:34:38 +02:00
f76b6cad14 (feature) Require delete count confirmation for retention apply
Make manual retention application more explicit by requiring operators to
confirm both the host name and the current number of planned deletions.

This reduces the risk of applying a stale or misunderstood retention plan
when the delete set changes between review and confirmation.
2026-05-21 01:19:08 +02:00
90e293facd (ui) Surface retention warnings on run detail
Show host-level retention warnings on run detail pages so successful or
warning runs still expose scheduled prune limit issues and incomplete
snapshots that need operator attention.
2026-05-21 01:13:44 +02:00
50eb7cf2f3 (ui) Make retention planning warnings explicit
Show keep/delete reasons in the retention plan, surface scheduled prune
limit warnings, and explain base snapshot protection before retention is
applied.

Also surface incomplete snapshots from the retention views without deleting
them automatically, so interrupted backups are visible on the dashboard,
host detail, and retention plan.
2026-05-21 01:10:45 +02:00
5faef1492d (ui) Add readable dry-run summaries
Surface dry-run status, transfer estimates, file counts, warnings, and the full
rsync log link directly on the run detail page.

Keep raw rsync output and JSON available, but make the common review path easier
to scan before starting a real backup.
2026-05-21 00:55:19 +02:00
3045093dcf (feature) Add remote host connection preflight
Add an on-demand host preflight action that verifies SSH reachability,
remote rsync availability, and remote source root access.

Persist the latest preflight result on the host config, render it in Django,
and block real backups when the last remote preflight failed.
2026-05-21 00:50:05 +02:00
64a0ff8322 (feature) Add host backup preflight gates
Introduce a host preflight layer that separates dry-run blockers from real backup blockers.
Show the effective per-host backup configuration in Django before queueing a run.

Block real backup queueing when failed host checks remain, while still allowing dry-runs
when only local storage preparation is missing.
2026-05-21 00:41:45 +02:00
a9e40df44b (feature) Add focused filtering to the service logs view
Extend the Django logs view with filters for service unit, severity, time
window, host, run id, and message text. Pass severity and time window directly
to journalctl, then apply host/run/message filtering to the returned pobsync
journal lines.

This makes failed or slow backups easier to investigate from the control panel
without needing shell access.
2026-05-21 00:24:07 +02:00
98695f9888 (ui) Surface run debugging details in Django
Restructure the run detail page into clearer sections for summary, failure
classification, requested options, rsync command, rsync log output, stats,
retention, and raw result data.

Show recent rsync log output inline with a link to the full log, and promote
failure and retention warning details out of the JSON payload so failed or slow
runs are easier to debug from the control panel.
2026-05-21 00:17:39 +02:00
0babc57f57 (feature) Link rsync logs from backup run detail
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.
2026-05-20 00:09:59 +02:00
c2d7342a47 (refactor) Remove unused schedule user field
Drop the legacy schedule user setting from the Django model, form, defaults,
and configure command.

Schedules are executed by the pobsync scheduler service under the configured
systemd service user, while remote SSH login users are configured separately
on global or host backup config.

Add a migration to remove the unused database column and update schedule
view tests around the simplified form.
2026-05-19 23:41:55 +02:00
1e04da9de8 (bugfix) Preserve existing schedule values in the edit form
Only apply default schedule initial values when creating a new schedule.

Avoid passing default initial data while editing an existing ScheduleConfig,
so the form renders the active cron-style expression, user, and retention
settings from the database.

Add a regression test that reopens an existing schedule and verifies the
stored values are shown instead of defaults.
2026-05-19 23:13:53 +02:00
124421b85c (bugfix) Show latest successful runs without requiring stats
Separate operational latest-run display from trend-stat collection so
successful backups without parsed stats still appear in dashboard host rows.

Keep trend summaries limited to runs with stats, but use all successful
real runs for the host latest-run indicator.

Render next scheduled run times with an explicit timezone label to avoid
ambiguity between UTC and local scheduler time.
2026-05-19 23:05:22 +02:00
86eee0f916 (feature) Show next scheduled run and backup run type in the UI
Add a scheduler helper that calculates the next due time for a cron-style
schedule expression and surface that value on the dashboard and host detail
pages.

Show the latest run type in host summaries and backup trend tables so
manual and scheduled backups are distinguishable in the Django UI.

Keep the calculation derived from existing ScheduleConfig data without
adding a migration.
2026-05-19 22:57:58 +02:00
fc22842fc4 (feature) Summarize backup trends in the Django UI
Add a stats summary layer that aggregates recent successful real backup runs
into dashboard and host-level trend metrics.

Show backup-root usage, available space, average new data, average duration,
estimated runs until full, and link-dest savings on the dashboard. Add a host
trend table with recent run duration, file count, new data, matched data, and
snapshot links.

Keep the implementation based on existing run and snapshot stats JSON so the
UI gains useful trend visibility without introducing a schema migration yet.
2026-05-19 22:31:24 +02:00
6940dc55b7 (feature) Capture structured backup statistics
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.
2026-05-19 22:25:04 +02:00
728e5c740a (feature) Add optional verbose rsync output for manual backups
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.
2026-05-19 22:13:33 +02:00
bbb0f652f3 (feature) Add cancellable backup runs and clearer dry-run logs
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.
2026-05-19 20:46:10 +02:00
088f43279e (feature) Add global and effective host config checks
Introduce reusable configuration checks for global settings and effective
host runtime configuration. The checks now surface risky backup settings
such as missing recursive rsync args, missing critical root excludes,
invalid SSH settings, missing credentials, and retention gaps.

Show these checks on the global config form, host edit form, and host
detail page so operators can validate the compounded host/global config
before starting real backup runs.
2026-05-19 20:24:29 +02:00
7e5d31d53b (bugfix) Guard dry-run logs and recursive rsync defaults
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 .".
2026-05-19 20:09:35 +02:00
d3ffca1843 (feature) Add host key scanning for SSH credentials
Add a host detail action that scans the target SSH host key with
ssh-keyscan and stores it on the selected SSH credential.

Merge scanned known_hosts entries without duplicates and let the
existing runtime config pass them through as UserKnownHostsFile for
unattended rsync over SSH.

Extend host checks to warn when the selected credential has no known_hosts
entries, making host key verification failures actionable from Django.
2026-05-19 19:55:40 +02:00
df3dcc47c9 (feature) Generate filesystem-backed SSH credentials
Add filesystem-backed SSH credentials for the native systemd deployment
path. Generated keys are stored below POBSYNC_HOME with 0600
permissions, while Django keeps the public key, fingerprint, path, and
selection metadata.

Add a Django SSH key generation view, delete action for unused generated
keys, and a management command used by the installer to ensure a default
backup key exists.

Update runtime config to use generated key paths directly as IdentityFile,
extend host checks to verify key readability, and keep legacy uploaded
keys available for compatibility.
2026-05-19 19:41:40 +02:00
ccacad3d37 (bugfix) Grant service user backup and journal access
Update the native installer so the pobsync service user gets journal
read access when the host exposes systemd-journal or adm groups.

Apply ownership and private directory modes to the configured backup
root, and reuse the existing environment backup root on reinstall so
production updates do not fall back to /backups.

Add a self-check for journal access and a host detail action that can
prepare missing backup directories for existing host configurations.
2026-05-19 19:25:05 +02:00
90f28410ce (feature) Add host doctor checks and Django log viewer
Add host-level checks for address, enabled state, SSH credential
selection, and backup directory readiness, and show them on the host
detail page.

Create host backup directories during host creation and prefill new
hosts from the default global config.

Add a staff-only logs view backed by journalctl with filtering by
pobsync unit, priority, and message text.

Improve runtime checks for gunicorn in virtualenv installs and ensure
the native installer grants the service user access to the backup root.
2026-05-19 19:11:57 +02:00
98d152da06 (bugfix) Add SSH private key file upload
Allow SSH credentials to be created from an uploaded private key file
as an alternative to pasting the key into a textarea.

Use multipart form handling in the credential views so server-side
keys can be imported without copy/paste wrapping or formatting damage.

Cover the upload path with a view test while keeping existing pasted
key validation behavior intact.
2026-05-19 18:48:17 +02:00
372a857f15 (feature) Add full native installer and self-check page
Expand the systemd installer so it can perform a complete native
installation with sensible defaults: copy the checkout into the target
app directory, create runtime directories, write the environment file,
install dependencies, configure systemd units, and optionally configure
nginx.

Add a staff-only Django self-check page that verifies runtime settings,
required binaries, writable paths, database connectivity, global config
state, and systemd service status when available.

Document installer overrides and expose the self-check from the main
navigation.
2026-05-19 16:05:03 +02:00
c018011e83 (bugfix) Validate Django-managed SSH private keys
Validate uploaded SSH private keys with ssh-keygen before saving them so
invalid, malformed, or unsupported key material is rejected in the
control panel instead of failing later during rsync.

Auto-populate the public key when it is omitted, add an edit flow for
existing SSH credentials, and cover create, update, and invalid-key
paths with view tests.
2026-05-19 15:22:40 +02:00
e65537c6de (feature) Add Django-managed SSH credentials
Add SSH credentials as first-class Django data so backup keys can be
uploaded through the control panel instead of mounted into containers.

Credentials can be selected globally or overridden per host. At runtime
the selected key is materialized inside the container with restrictive
file permissions and injected into the rsync SSH command via IdentityFile.
Known hosts entries are handled the same way when configured.

Add control panel views for creating and listing SSH keys, expose the
fields in config forms and admin, document the workflow, and cover global
and host credential selection with tests.
2026-05-19 14:37:38 +02:00
91ce7ad4c5 (feature) Add host backup control actions
Turn the host detail page into a more useful operator surface for
starting greenfield backups from Django.

Add quick actions for dry-run and real backup runs, keep the advanced
manual options available, and show whether a host is ready, disabled, or
blocked by missing global config. Surface queued and running counts plus
a direct link to the active run.

Expose requested backup options on the run detail page and cover the new
control flow with view tests.
2026-05-19 14:25:28 +02:00
4fb33eca6c (feature) Add Django retention apply flow
Expose retention apply from the host retention plan page so planned
snapshot deletions can be executed from the Django UI.

The form requires explicit host confirmation, carries through the
selected retention kind and base-protection setting, and uses max_delete
as a deletion guard. The view delegates to the SQL retention apply
service and reports predictable pobsync errors back through Django
messages instead of surfacing a server error.

Add view coverage for confirmed deletion, invalid confirmation, and
POST-only enforcement.
2026-05-19 13:54:15 +02:00
83334803b9 (feature) show latest snapshot on the Django dashboard
Add latest snapshot context to each dashboard host row so imported legacy
snapshots are visible without opening every host page.

Link the latest snapshot directly to its detail page and show its kind
and status beside the host snapshot count.

Cover the dashboard latest-snapshot selection with a view test.
2026-05-19 13:44:28 +02:00
1d90454109 (feature) improve snapshot discovery visibility in Django
Add a discovery preflight that reports the configured backup root, host
root, and snapshot directory counts before importing anything.

Show discovery status on host detail pages so missing mounts or mismatched
host directories are visible from the UI.

Warn clearly when discovery scans zero snapshots, including whether the
host backup directory is missing or simply empty.
2026-05-19 13:21:31 +02:00
573177e118 (refactor) make Docker backup root static in Django setup
Remove backup_root from the normal Django global config form and display
the fixed container path /backups instead.

Always persist /backups from the setup form so Docker deployments do not
mix host paths with container paths.

Update tests and docs to clarify that the host backup directory is chosen
through the Docker mount, while Django always uses /backups internally.
2026-05-19 13:14:22 +02:00
3da877eb8a (feature) queue manual backups from the Django host page
Add a staff-only manual backup form to host detail pages with safe
dry-run defaults and optional retention settings.

Queue manual BackupRun records through the existing worker-backed runner
path instead of executing backups inside the web request.

Validate disabled hosts, missing global config, and invalid methods with
view tests covering the new UI flow.
2026-05-19 13:04:50 +02:00
aea22597ba (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.
2026-05-19 12:48:32 +02:00
66e1f549b9 (feature) add Django detail views for backup runs and snapshots
Add staff-only run and snapshot detail pages so scheduler and command
output can be inspected from the Django UI.

Link dashboard and host detail tables to the new detail views, including
snapshot/base relationships and linked backup runs.

Render stored result and metadata JSON in readable form and cover the new
inspection views with tests.
2026-05-19 12:31:47 +02:00
6bcc15c174 (feature) add Django setup flow for initial pobsync configuration
Add staff-only UI routes for creating/editing the default GlobalConfig
and creating the first HostConfig from the dashboard.

Improve the empty dashboard state so a fresh database guides the user
towards the next useful setup action instead of only showing empty tables.

Cover the setup flow with view tests for empty state prompts, global
config creation, and host creation.
2026-05-19 12:25:45 +02:00
4dbde43465 (feature) Add host config editing view
Add a staff-only Django form for editing operational host settings while keeping
host identity stable. Support address, enablement, SSH/source overrides,
include/exclude lists, rsync extra args, and retention settings using the same
SQL-backed HostConfig model consumed by backup and scheduler flows.

Parse newline-separated list fields into JSON lists, preserve nullable
excludes_replace semantics, and cover rendering plus update behavior with view
tests.
2026-05-19 12:17:17 +02:00
6d7bf531ac (feature) Add schedule editing view for hosts
Add a staff-only Django form for creating and updating host schedules using the
SQL-backed ScheduleConfig model. Link the form from host detail pages, validate
cron expressions with the existing scheduler parser, and preserve scheduler/CLI
behavior by writing to the same source of truth.

Cover default rendering, schedule creation, updates, and invalid cron handling
with view tests.
2026-05-19 12:13:12 +02:00
123583a502 (feature) Add read-only retention plan view
Add a staff-only retention plan page for each host using the SQL-backed
retention service. Link it from the host detail page and show policy settings,
keep reasons, and snapshots that would be deleted for scheduled, manual, or all
snapshot kinds.

Keep the flow non-destructive for now, validate query parameters, and cover the
view with tests for rendering, base protection, and invalid kind handling.
2026-05-19 12:00:19 +02:00