From 500f7d6ad67c81c13b98b8c3e13280348b6a9afe Mon Sep 17 00:00:00 2001 From: cproudlock Date: Tue, 25 Aug 2026 14:53:04 -0400 Subject: [PATCH] Give the backups plugin a settings page, and show where a snapshot is The plugin shipped five settings and no page for any of them. The core settings catalog is a hardcoded list a plugin cannot extend, so backups_shareroot and the collection interval were reachable only through the API or a flask shell on the server - which is not a configurable setting in any useful sense, and it is how today went: the setting simply was not there to set. The page is contributed the ADR-010 way rather than by editing core - a card from get_settings_cards plus a route in the plugin's own routes.js, both of which disappear when the plugin is disabled. Filed under Machines, next to Machine Types, because that is where the assets these back up live. It also states the two things the settings do not say for themselves: that health is judged on when a backup was last CONFIRMED rather than when it last changed, and that retention prunes database revisions only - files on the share stay, so enabling it on a share-backed kind leaves orphaned snapshot directories. Snapshot paths are now shown as full UNC text in both places: a Snapshot row on the Marker Contents card, and the existing path on the history page, which gains a copy button. Deliberately NOT a link - browsers refuse to navigate from an https page to file://, so a clickable path looks actionable and silently does nothing, which is worse than no link. Copy, then paste into Explorer. The path comes off the revision, never composed from the configured share root: a snapshot written before the layout changed still lives where it was put. --- plugins/backups/api/routes.py | 6 +- plugins/backups/frontend/routes.js | 11 ++ .../backups/frontend/views/BackupHistory.vue | 43 +++++ .../frontend/views/BackupsSettings.vue | 157 ++++++++++++++++++ plugins/backups/plugin.py | 25 +++ plugins/backups/services/partmarkerinfo.py | 10 +- plugins/backups/services/registry.py | 3 +- tests/test_plugins/test_backups.py | 35 ++++ 8 files changed, 287 insertions(+), 3 deletions(-) create mode 100644 plugins/backups/frontend/views/BackupsSettings.vue diff --git a/plugins/backups/api/routes.py b/plugins/backups/api/routes.py index 9bed80c6..86ac20ba 100644 --- a/plugins/backups/api/routes.py +++ b/plugins/backups/api/routes.py @@ -179,7 +179,11 @@ def asset_info(assetid): # The card names the PC a snapshot came from, and chains its diff on the # same value. Passed from the column rather than read out of the stored # manifest, which carries its own copy that can disagree. - sourcehostname=revision.sourcehostname) + sourcehostname=revision.sourcehostname, + # Where the snapshot actually is. Read off the revision rather than + # composed from the configured share root, so a snapshot written before + # the layout changed still points at where it was really put. + sharepath=revision.sharepath) data['backuprevisionid'] = revision.backuprevisionid data['collectedat'] = _utciso(revision.collectedat) return success_response(data) diff --git a/plugins/backups/frontend/routes.js b/plugins/backups/frontend/routes.js index db2870be..ee75326d 100644 --- a/plugins/backups/frontend/routes.js +++ b/plugins/backups/frontend/routes.js @@ -12,6 +12,17 @@ * JWT + a backups.* permission; an anonymous visit would only render errors. */ export default [ + { + // The plugin's five settings had no page at all until this one: the core + // settings catalog is a hardcoded list that a plugin cannot extend, so + // backups_shareroot and friends were reachable only through the API or a + // shell on the server. Paired with get_settings_cards in plugin.py, which + // puts the card in the rail - both vanish when the plugin is disabled. + path: 'settings/backups', + name: 'backups-settings', + component: () => import('./views/BackupsSettings.vue'), + meta: { requiresAuth: true, requiresAdmin: true, plugin: 'backups' } + }, { path: 'backups/asset/:assetid', name: 'backups-asset-history', diff --git a/plugins/backups/frontend/views/BackupHistory.vue b/plugins/backups/frontend/views/BackupHistory.vue index 6ab4fec3..803c8571 100644 --- a/plugins/backups/frontend/views/BackupHistory.vue +++ b/plugins/backups/frontend/views/BackupHistory.vue @@ -66,6 +66,16 @@ UNC path so the tech can open it directly. -->