Recover disk space safely and complete metadata-only backup updates

This commit is contained in:
admin committed 2026-09-21 16:30:38 +02:00
1 parent 04283a607c
commit a5a7e38853
17 files changed
+827 -209

No files matched your search

+43 -9
View File
@@ -20,11 +20,13 @@ UP_MAIL_HOMES=false
UP_STATE=''
UP_WORKER=false
UP_RESTORE_TEST=false
UP_AI_REM=false
while (( $# )); do
case $1 in
--config) CONFIG_FILE=${2:?Missing configuration}; shift 2 ;;
--foreground) UP_FOREGROUND=true; shift ;;
--install-deps) UP_INSTALL_DEPS=true; shift ;;
--enable-ai-rem) UP_AI_REM=true; shift ;;
--enable-restore-test) UP_RESTORE_TEST=true; shift ;;
--enable-gitea) UP_GITEA=true; shift ;;
--no-gitea) UP_GITEA=false; shift ;;
@@ -33,7 +35,7 @@ while (( $# )); do
--mail-dir) UP_MAIL_DIR=${2:?Missing mailbox directory}; shift 2 ;;
--mail-homes-only) UP_MAIL_HOMES=true; shift ;;
--worker) UP_WORKER=true; UP_STATE=${2:?Missing state}; shift 2 ;;
--help) echo 'Usage: sudo bash update.sh [--foreground] [--config FILE] [--rclone-config FILE] [--enable-gitea | --no-gitea] [--cron-services UNIT,...] [--mail-dir DIR | --mail-homes-only] [--install-deps] [--enable-restore-test]'; exit 0 ;;
--help) echo 'Usage: sudo bash update.sh [--foreground] [--config FILE] [--rclone-config FILE] [--enable-gitea | --no-gitea] [--cron-services UNIT,...] [--mail-dir DIR | --mail-homes-only] [--install-deps] [--enable-restore-test] [--enable-ai-rem]'; exit 0 ;;
*) die "Unknown argument: $1" ;;
esac
done
@@ -200,6 +202,40 @@ if [[ $UP_WORKER == false ]]; then
append_setting RCLONE_CONFIG "$RCLONE_CONFIG"
printf '%s\n' "$RCLONE_CONFIG" > "$UP_STATE/rclone-path"
if [[ $UP_AI_REM == true ]]; then
# Gemini's ai-rem is managed by Compose through ai-rem.service. Stop its
# schedulers and their jobs before the container; resume in reverse order.
# Append paths without reordering existing extra-N archive/restore labels.
for path in /srv/ai-rem /etc/ai-rem; do
check_source_path "$path"
found=false
for existing in "${EXTRA_PATHS[@]}"; do
if [[ $(realpath -m -- "$existing") == "$path" ]]; then found=true; break; fi
done
if [[ $found == false ]]; then EXTRA_PATHS+=("$path"); fi
done
{
printf 'EXTRA_PATHS=('
printf '%q ' "${EXTRA_PATHS[@]}"
printf ')\n'
} >> "$UP_STATE/candidate.conf"
# Repeated activation also restores the required stop order.
ai_rem_units=(ai-rem-healthcheck.timer ai-rem-backup.timer ai-rem-prune.timer
ai-rem-healthcheck.service ai-rem-backup.service ai-rem-prune.service ai-rem.service)
remaining=()
for unit in "${QUIESCE_SERVICES[@]}"; do
case ${unit%.service} in
ai-rem|ai-rem-healthcheck|ai-rem-backup|ai-rem-prune|ai-rem-healthcheck.timer|ai-rem-backup.timer|ai-rem-prune.timer) ;;
*) remaining+=("$unit") ;;
esac
done
for unit in "${ai_rem_units[@]}"; do
[[ $(systemctl show "$unit" --property=LoadState --value) == loaded ]] || die "Missing ai-rem unit: $unit"
done
QUIESCE_SERVICES=("${ai_rem_units[@]}" "${remaining[@]}")
echo 'ai-rem included: /srv/ai-rem and /etc/ai-rem; container and maintenance jobs stopped during snapshot'
fi
if [[ -n $UP_CRON ]]; then IFS=, read -r -a additional <<< "$UP_CRON"; QUIESCE_SERVICES+=("${additional[@]}"); fi
if [[ $ENABLE_NEXTCLOUD == true ]]; then
discover cron-units "$NC_DIR" > "$UP_STATE/cron-units"
@@ -263,7 +299,7 @@ if [[ $UP_WORKER == false ]]; then
fi
sha256sum "$UP_STATE/candidate.conf" | cut -d ' ' -f 1 > "$UP_STATE/candidate.sha256"
echo "Vorpruefung erfolgreich. Writer: $(tr '\n' ' ' < "$UP_STATE/writers")"
echo 'Jetzt folgen Installation, ein vollstaendiges Backup und Remote-Restore-Pruefung.'
echo 'Jetzt folgen Installation, ein vollstaendiges Backup und Remote-Dateipruefung.'
printf 'QUEUED\n' > "$UP_STATE/result.txt"
if [[ $UP_FOREGROUND == true ]]; then
flock -u 9; flock -u 8
@@ -311,7 +347,7 @@ worker_finish() {
trap - EXIT INT TERM
set +e
if [[ $UP_OK == true && $code == 0 ]]; then
printf 'SUCCESS\nPaket aktualisiert, Backup und Remote-Restore-Pruefung erfolgreich.\nBackup-Timer aktiv.\n' > "$UP_STATE/result.txt"
printf 'SUCCESS\nPaket aktualisiert, Backup und Remote-Dateipruefung erfolgreich.\nArchiv-Inhaltspruefung erfolgt beim monatlichen Restore-Test.\nBackup-Timer aktiv.\n' > "$UP_STATE/result.txt"
else
if [[ $UP_CHANGED == true ]]; then systemctl stop app-backup.timer app-restore-test.timer; fi
printf 'FAILED (exit %s)\nDetails: %s/update.log\n' "$code" "$UP_STATE" > "$UP_STATE/result.txt"
@@ -390,12 +426,10 @@ assert value['exit_code'] == 0
print(value['run'])
PY
)
if [[ $ENABLE_RESTORE_TEST == true ]]; then
bash /usr/local/sbin/app-restore-test.sh --config "$CONFIG_FILE" --remote-run "$backup_run"
else
bash /usr/local/sbin/app-restore.sh --config "$CONFIG_FILE" --remote-run "$backup_run" --verify-only
fi
printf '%s\n' "$backup_run" > "$UP_STATE/verified-backup-run"
# The backup already confirmed remote file presence, sizes and COMPLETE.
# Archive downloads belong to the monthly rehearsal, not update acceptance.
printf '%s\n' "$backup_run" > "$UP_STATE/uploaded-backup-run"
echo '-- Update acceptance: upload and remote metadata confirmed; archive restore deferred to monthly test'
# A missed persistent timer can fire immediately, so release the shared lock first.
unset APP_BACKUP_INHERIT_LOCK
flock -u 9