Application backups were driven by one crontab entry per app, each offset by id * CFG_BACKUP_CRONTAB_APP_INTERVAL minutes. That minute offset is written straight into cron's 0-59 minute field, so past ~20 apps it overflowed into an invalid entry that silently never fired, and the fixed spacing could not serialize backups that ran longer than the gap. Replace it with a single daily entry (`libreportal backup scheduled`) that enqueues a backup task per enabled app. The existing systemd task processor drains them serially — no minute overflow, real serialization, and backups are now visible/cancellable in the Tasks UI. Per-app enable is read from CFG_<APP>_BACKUP at schedule time instead of being mirrored into crontab. Removes the stagger machinery (timing/setup/check/remove scripts), the now-unused cron_jobs table + insert, and the CFG_BACKUP_CRONTAB_APP_INTERVAL config knob and its WebUI field. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
100 lines
3.7 KiB
Bash
Executable File
100 lines
3.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
cliHandleBackupCommands()
|
|
{
|
|
local backup_type="$initial_command2"
|
|
local action="$initial_command3"
|
|
local name="$initial_command4"
|
|
local extra="$initial_command5"
|
|
local extra2="$initial_command6"
|
|
|
|
if [[ -z "$backup_type" ]]; then
|
|
cliShowBackupHelp
|
|
return
|
|
fi
|
|
|
|
case "$backup_type" in
|
|
app)
|
|
case "$action" in
|
|
""|help) cliShowBackupHelp ;;
|
|
create)
|
|
[[ -z "$name" ]] && { isNotice "No app name provided."; cliShowBackupHelp; return; }
|
|
backupAppStart "$name"
|
|
;;
|
|
schedule)
|
|
[[ -z "$name" ]] && { isNotice "No app name provided."; cliShowBackupHelp; return; }
|
|
backupAppSchedule "$name"
|
|
;;
|
|
delete)
|
|
[[ -z "$name" ]] && { isNotice "No app name provided."; cliShowBackupHelp; return; }
|
|
[[ -z "$extra" ]] && { isNotice "No <location_idx>:<snapshot_id> provided (e.g. 1:abc123)."; cliShowBackupHelp; return; }
|
|
local idx="${extra%%:*}"
|
|
local snap="${extra##*:}"
|
|
backupAppDeleteSnapshot "$idx" "$snap"
|
|
;;
|
|
delete_all)
|
|
[[ -z "$name" ]] && { isNotice "No app name provided."; cliShowBackupHelp; return; }
|
|
backupAppDeleteAll "$name"
|
|
;;
|
|
list)
|
|
[[ -z "$name" ]] && { isNotice "No app name provided."; cliShowBackupHelp; return; }
|
|
local idx
|
|
while IFS= read -r idx; do
|
|
[[ -z "$idx" ]] && continue
|
|
echo "--- $(resticLocationName "$idx") (loc $idx) ---"
|
|
engineSnapshotsJson "$idx" "$name"
|
|
done < <(resticEnabledLocations)
|
|
;;
|
|
*)
|
|
isNotice "Invalid app backup action: $action"
|
|
cliShowBackupHelp
|
|
;;
|
|
esac
|
|
;;
|
|
all)
|
|
backupAllApps
|
|
;;
|
|
scheduled)
|
|
backupScheduleEnabledApps
|
|
;;
|
|
location)
|
|
case "$action" in
|
|
add)
|
|
[[ -z "$name" ]] && { isNotice "Usage: backup location add <name> [type]"; cliShowBackupHelp; return; }
|
|
locationAdd "$name" "$extra"
|
|
;;
|
|
remove)
|
|
[[ -z "$name" ]] && { isNotice "Usage: backup location remove <idx>"; cliShowBackupHelp; return; }
|
|
locationRemove "$name" "$extra"
|
|
;;
|
|
list)
|
|
local idx
|
|
while IFS= read -r idx; do
|
|
[[ -z "$idx" ]] && continue
|
|
local enabled="no"; resticLocationEnabled "$idx" && enabled="yes"
|
|
echo "[$idx] $(resticLocationName "$idx") — type=$(resticLocationType "$idx"), enabled=$enabled"
|
|
done < <(resticAllLocationIndices)
|
|
;;
|
|
init)
|
|
engineInitAllLocations
|
|
;;
|
|
check)
|
|
engineCheckAllLocations "${name:-5}"
|
|
;;
|
|
stats)
|
|
[[ -z "$name" ]] && name="1"
|
|
engineLocationStats "$name"
|
|
;;
|
|
*) isNotice "Invalid location action: $action"; cliShowBackupHelp ;;
|
|
esac
|
|
;;
|
|
verify)
|
|
engineCheckAllLocations "${action:-5}"
|
|
;;
|
|
*)
|
|
isNotice "Invalid backup type: $backup_type"
|
|
cliShowBackupHelp
|
|
;;
|
|
esac
|
|
}
|