fix(backup): system config in scheduled backups + retention (review findings)
Final-review gaps in the system-config backup: 1. Scheduled (cron) backups skipped it — backupScheduleEnabledApps only queued per-app backups, so the daily schedule never refreshed the system config (and thus the backup-location creds could go stale). Now it queues a `libreportal backup system` task (or runs inline on terminal-only installs), and skips the reproducible libreportal app for consistency with backupAllApps. 2. No retention on system snapshots — they bypass backupAppStart's per-app forget, so they accumulated unbounded. Add resticForgetSystem (tag system=config, respects append-only + the same keep-* policy) + engineForgetSystem dispatcher; backupSystemConfig now applies retention across all locations after snapshotting. Verified with stubs: backupSystemConfig snapshots AND prunes on every location; engineForgetSystem pairs with resticForgetSystem; scheduled createTaskFile call matches the existing 3-arg signature. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
95882ea7e6
commit
038d1c0729
@ -21,6 +21,9 @@ backupScheduleEnabledApps()
|
|||||||
|
|
||||||
local queued=0
|
local queued=0
|
||||||
for name in "${app_names[@]}"; do
|
for name in "${app_names[@]}"; do
|
||||||
|
# libreportal (the WebUI) is reproducible — its state rides in the system
|
||||||
|
# config snapshot, so it's never scheduled as an app backup.
|
||||||
|
[[ "$name" == "libreportal" ]] && continue
|
||||||
local backup_flag="CFG_${name^^}_BACKUP"
|
local backup_flag="CFG_${name^^}_BACKUP"
|
||||||
if [[ "${!backup_flag}" == "true" ]]; then
|
if [[ "${!backup_flag}" == "true" ]]; then
|
||||||
backupAppSchedule "$name"
|
backupAppSchedule "$name"
|
||||||
@ -28,5 +31,17 @@ backupScheduleEnabledApps()
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
isSuccessful "Backup scheduling complete — $queued app(s) queued"
|
# Keep the system config fresh on the schedule too (settings + the
|
||||||
|
# backup-location creds). Queue it via the task processor on WebUI installs,
|
||||||
|
# else run inline — mirroring backupAppSchedule. backupSystemConfig no-ops
|
||||||
|
# when no locations are enabled.
|
||||||
|
if [[ "$CFG_REQUIREMENT_WEBUI" == "true" ]] && declare -f createTaskFile >/dev/null 2>&1; then
|
||||||
|
createTaskFile "libreportal backup system" "backup" "system" \
|
||||||
|
&& isSuccessful "System config backup task queued" \
|
||||||
|
|| backupSystemConfig
|
||||||
|
else
|
||||||
|
backupSystemConfig
|
||||||
|
fi
|
||||||
|
|
||||||
|
isSuccessful "Backup scheduling complete — $queued app(s) queued + system config"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,6 +56,7 @@ engineSnapshotsJson() { local i="$1"; shift; engineDispatch "$(engineForL
|
|||||||
engineSystemSnapshotsJson() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")SystemSnapshotsJson" "$i" "$@"; }
|
engineSystemSnapshotsJson() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")SystemSnapshotsJson" "$i" "$@"; }
|
||||||
engineSnapshotListFiles() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")SnapshotListFiles" "$i" "$@"; }
|
engineSnapshotListFiles() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")SnapshotListFiles" "$i" "$@"; }
|
||||||
engineForgetApp() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")ForgetApp" "$i" "$@"; }
|
engineForgetApp() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")ForgetApp" "$i" "$@"; }
|
||||||
|
engineForgetSystem() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")ForgetSystem" "$i" "$@"; }
|
||||||
engineCheckLocation() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")CheckLocation" "$i" "$@"; }
|
engineCheckLocation() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")CheckLocation" "$i" "$@"; }
|
||||||
engineDumpFile() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")DumpFile" "$i" "$@"; }
|
engineDumpFile() { local i="$1"; shift; engineDispatch "$(engineForLocation "$i")DumpFile" "$i" "$@"; }
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,39 @@ resticForgetApp()
|
|||||||
return $rc
|
return $rc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resticForgetSystem()
|
||||||
|
{
|
||||||
|
local idx="$1"
|
||||||
|
|
||||||
|
if resticLocationAppendOnly "$idx"; then
|
||||||
|
isNotice "$(resticLocationName "$idx") is append-only — skipping forget for system config"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local keep_last keep_daily keep_weekly keep_monthly keep_yearly
|
||||||
|
keep_last=$(resticRetentionFor "$idx" KEEP_LAST)
|
||||||
|
keep_daily=$(resticRetentionFor "$idx" KEEP_DAILY)
|
||||||
|
keep_weekly=$(resticRetentionFor "$idx" KEEP_WEEKLY)
|
||||||
|
keep_monthly=$(resticRetentionFor "$idx" KEEP_MONTHLY)
|
||||||
|
keep_yearly=$(resticRetentionFor "$idx" KEEP_YEARLY)
|
||||||
|
|
||||||
|
resticEnvExport "$idx" || return 1
|
||||||
|
|
||||||
|
local args=(forget --tag "system=config" --group-by tags,host)
|
||||||
|
[[ -n "$keep_last" ]] && args+=(--keep-last "$keep_last")
|
||||||
|
[[ -n "$keep_daily" ]] && args+=(--keep-daily "$keep_daily")
|
||||||
|
[[ -n "$keep_weekly" ]] && args+=(--keep-weekly "$keep_weekly")
|
||||||
|
[[ -n "$keep_monthly" ]] && args+=(--keep-monthly "$keep_monthly")
|
||||||
|
[[ -n "$keep_yearly" ]] && args+=(--keep-yearly "$keep_yearly")
|
||||||
|
[[ "$CFG_BACKUP_PRUNE_AFTER_FORGET" == "true" ]] && args+=(--prune)
|
||||||
|
|
||||||
|
isNotice "Applying retention for system config on $(resticLocationName "$idx")"
|
||||||
|
runBackupOp restic "${args[@]}"
|
||||||
|
local rc=$?
|
||||||
|
resticEnvUnset
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
resticRetentionFor()
|
resticRetentionFor()
|
||||||
{
|
{
|
||||||
local idx="$1"
|
local idx="$1"
|
||||||
|
|||||||
@ -40,6 +40,14 @@ backupSystemConfig()
|
|||||||
isError "System config backup failed on all locations"
|
isError "System config backup failed on all locations"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Apply retention so system snapshots don't accumulate (respects append-only
|
||||||
|
# locations; bypasses backupAppStart's per-app forget, so do it here).
|
||||||
|
while IFS= read -r idx; do
|
||||||
|
[[ -z "$idx" ]] && continue
|
||||||
|
engineForgetSystem "$idx" >/dev/null 2>&1 || true
|
||||||
|
done < <(resticEnabledLocations)
|
||||||
|
|
||||||
if [[ $fail -gt 0 ]]; then
|
if [[ $fail -gt 0 ]]; then
|
||||||
isNotice "System config backed up to $ok location(s), failed on $fail"
|
isNotice "System config backed up to $ok location(s), failed on $fail"
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user