gitea-backup-pull: switch vlda-01 retention from a fixed count to a 30-day rotation

KEEP=30 (last 30 archives) approximated 30 days only if there was
exactly one dump per day. Prune by file mtime instead (find -mtime +30)
so a catch-up burst after time offline doesn't prematurely evict
recent dumps, and a quiet stretch doesn't hoard month-old ones.
This commit is contained in:
2026-07-26 20:30:02 +02:00
parent 45856f48f8
commit 2b86579fb8
3 changed files with 20 additions and 8 deletions
+8 -2
View File
@@ -479,8 +479,14 @@ The SSH keypair needed no special handling: Unraid already auto-mirrors
relying on the file's own (nonexistent) `+x`. relying on the file's own (nonexistent) `+x`.
- Lands in `/mnt/disks/WSD2L840/git/` — an **Unassigned Device** (external - Lands in `/mnt/disks/WSD2L840/git/` — an **Unassigned Device** (external
disk, not part of the protected array), not the RAM-backed root — keeps disk, not part of the protected array), not the RAM-backed root — keeps
the last 30 locally, now the real long-term history given alpha deletes a rolling 30 calendar days locally (by file `mtime`, not a fixed file
its own copies right after a verified pull. count — a burst of catch-up pulls after being offline a while shouldn't
prematurely evict genuinely recent dumps, and a quiet stretch shouldn't
keep month-old ones around just for lack of newer arrivals), now the
real long-term history given alpha deletes its own copies right after a
verified pull. Verified live: a synthetic 40-day-old dump + its
checksum file were correctly pruned while a genuine 20-day-old one and
everything newer were left untouched.
- **The device isn't guaranteed to already be mounted** when the script - **The device isn't guaranteed to already be mounted** when the script
runs, so it resolves the disk by filesystem label (`findfs runs, so it resolves the disk by filesystem label (`findfs
LABEL=WSD2L840`, not a hardcoded `/dev/sdX` — USB/Unassigned-Device LABEL=WSD2L840`, not a hardcoded `/dev/sdX` — USB/Unassigned-Device
+1 -1
View File
@@ -39,7 +39,7 @@ of every script here, so it's worth stating plainly before anything else:
| File here | Deployed path | Purpose | | File here | Deployed path | Purpose |
|---|---|---| |---|---|---|
| `user-scripts/gitea-backup-pull/script` | `/boot/config/plugins/user.scripts/scripts/gitea-backup-pull/script` | Pulls new `gitea-dump` archives from `alpha` via the restricted `giteabackup` SFTP account, verifies each one's sha256 checksum, deletes both files on `alpha` only after a confirmed match, prunes its own local retention (30). Resolves and mounts the `WSD2L840` Unassigned Device itself first, and unmounts it again afterward — but only if this run is the one that mounted it, never disturbing a mount it found already in place, and only if nothing else is using the disk at that moment (checked via `fuser -m`; `rc.unassigned umount`'s own lazy unmount never refuses on its own, so this script checks first and just leaves it mounted, no error, if something else is still on it). See the script's own header comment for the full reasoning. | | `user-scripts/gitea-backup-pull/script` | `/boot/config/plugins/user.scripts/scripts/gitea-backup-pull/script` | Pulls new `gitea-dump` archives from `alpha` via the restricted `giteabackup` SFTP account, verifies each one's sha256 checksum, deletes both files on `alpha` only after a confirmed match, prunes its own local retention (rolling 30 calendar days, by file `mtime` - not a fixed count). Resolves and mounts the `WSD2L840` Unassigned Device itself first, and unmounts it again afterward — but only if this run is the one that mounted it, never disturbing a mount it found already in place, and only if nothing else is using the disk at that moment (checked via `fuser -m`; `rc.unassigned umount`'s own lazy unmount never refuses on its own, so this script checks first and just leaves it mounted, no error, if something else is still on it). See the script's own header comment for the full reasoning. |
| `user-scripts/gitea-backup-pull/description` | `.../gitea-backup-pull/description` | Shown in the User Scripts UI. | | `user-scripts/gitea-backup-pull/description` | `.../gitea-backup-pull/description` | Shown in the User Scripts UI. |
| `user-scripts/gitea-backup-pull-onboot/script` | `.../gitea-backup-pull-onboot/script` | One-line wrapper: `bash`-invokes the script above. Exists only because `schedule.json` supports one schedule per script *path* — this is how the "also run once at every restart" requirement was added alongside the existing daily `03:30` schedule without disturbing it. | | `user-scripts/gitea-backup-pull-onboot/script` | `.../gitea-backup-pull-onboot/script` | One-line wrapper: `bash`-invokes the script above. Exists only because `schedule.json` supports one schedule per script *path* — this is how the "also run once at every restart" requirement was added alongside the existing daily `03:30` schedule without disturbing it. |
| `user-scripts/gitea-backup-pull-onboot/description` | `.../gitea-backup-pull-onboot/description` | Shown in the User Scripts UI. | | `user-scripts/gitea-backup-pull-onboot/description` | `.../gitea-backup-pull-onboot/description` | Shown in the User Scripts UI. |
@@ -28,7 +28,7 @@ REMOTE_PORT=10022
UD_LABEL=WSD2L840 UD_LABEL=WSD2L840
UD_MOUNTPOINT=/mnt/disks/WSD2L840 UD_MOUNTPOINT=/mnt/disks/WSD2L840
LOCAL_DIR="$UD_MOUNTPOINT/git" LOCAL_DIR="$UD_MOUNTPOINT/git"
KEEP=30 KEEP_DAYS=30
# WSD2L840 is an Unassigned Device, not part of the array - not # WSD2L840 is an Unassigned Device, not part of the array - not
# guaranteed to already be mounted when this runs. Resolve by label # guaranteed to already be mounted when this runs. Resolve by label
@@ -150,11 +150,17 @@ if [ -s "$DEL_BATCH" ]; then
fi fi
fi fi
# prune to the last $KEEP archives (vlda-01 has far more headroom than # prune anything older than $KEEP_DAYS calendar days (vlda-01 has far
# alpha, so this is the real long-term history now that alpha deletes # more headroom than alpha, so this is the real long-term history now
# its own copies right after a verified pull) # that alpha deletes its own copies right after a verified pull). A
# calendar-day window rather than a fixed count on purpose: a burst of
# catch-up pulls after being offline a while shouldn't prematurely evict
# genuinely recent dumps just because there are suddenly more than a
# fixed count, and a quiet stretch with few new dumps shouldn't keep
# month-old ones around just because too few newer ones have arrived to
# push them out.
cd "$LOCAL_DIR" || exit 1 cd "$LOCAL_DIR" || exit 1
ls -1t gitea-dump-*.zip 2>/dev/null | tail -n +$((KEEP + 1)) | while read -r old; do find . -maxdepth 1 -name 'gitea-dump-*.zip' -mtime +"$KEEP_DAYS" -print0 | while IFS= read -r -d '' old; do
rm -f "$old" "${old}.sha256" rm -f "$old" "${old}.sha256"
done done