Skip to content

Commit

Permalink
Make the number of each backup type configurable (#31)
Browse files Browse the repository at this point in the history
A value of 0 means to keep indefinitely.
  • Loading branch information
assistcontrol committed Jun 14, 2019
1 parent c134871 commit d8f907a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 33 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ design goals:
- Calendar-based backup schedule
- Portable, small, code footprint.

One Tarsnap archive is created per-target per-run. 31 daily, 12 monthly,
and indefinite yearly backups are kept.
One Tarsnap archive is created per-target per-run. By default,
31 daily and 12 monthly backups are kept, and yearly backups are
kept indefinitely.

Download
--------
Expand All @@ -40,7 +41,7 @@ Notes on behaviour:
- If no monthly backup for the current month exists, create a
monthly backup.
- Otherwise, create a daily backup.
- Archives are deleted using the following logic:
- Archives are deleted using the following logic by default:
- If any backups failed, delete nothing.
- Keep the most recent 31 daily backups, and delete any older
ones.
Expand Down
63 changes: 33 additions & 30 deletions acts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ postbackupscript="${postbackupscript=}"
tarsnap="${tarsnap:=tarsnap}"
tarsnapbackupoptions="${tarsnapbackupoptions=}"
lockfile="${lockfile=/var/run/acts}"
dailybackups="${dailybackups:=31}"
monthlybackups="${monthlybackups:=12}"
yearlybackups="${yearlybackups:=0}"
LANG="${LANG=en_US.UTF-8}"
export LANG

Expand All @@ -113,6 +116,10 @@ else
die "config-error message=\"invalid \$uselocaltime in acts.conf; valid options are 0 (for UTC) or 1 (for local time).\""
fi

[ $(( dailybackups )) = "$dailybackups" ] || die "config-error message=\"Invalid \$dailybackups; must be a number.\""
[ $(( monthlybackups )) = "$monthlybackups" ] || die "config-error message=\"Invalid \$monthlybackups; must be a number.\""
[ $(( yearlybackups )) = "$yearlybackups" ] || die "config-error message=\"Invalid \$yearlybackups; must be a number.\""

# Create the lock. mkdir is atomic test/set, so use that instead of the typical test -f/touch combo
if [ -d "$lockfile" ]; then
die "acts-error message=\"$lockfile exists referencing PID $(cat "$lockfile/pid" 2>/dev/null || echo "<none>"). Hint: If acts is not already running, rm -rf $lockfile.\""
Expand Down Expand Up @@ -191,40 +198,36 @@ if [ "$backuprc" != "0" ]; then
die "acts-tarsnap-error One of the backups failed -- not deleting old backups"
fi

for dir in $backuptargets; do
log_debug "message=\"Checking $dir for old backups to delete\""
nicedirname=$(echo "$dir" | tr -d '/')
# We don't delete any yearly backups

# We keep 12 monthly backups
monthlybackups=$(echo "$archives" | grep "$hostname-monthly-.+-$nicedirname$" | sort -rn)
if [ "$(echo "$monthlybackups" | wc -l)" -gt 12 ]; then
log_debug 'message="More than 12 monthly backups, deleting the oldest"'
echo "$monthlybackups" | tail -n +13 | while read -r archiveprefixtodel; do
log_verbose "message=\"Deleting backup prefix $archiveprefixtodel*\""
echo "$archives" | grep -E "^$archiveprefixtodel" | while read -r archivetodel; do
log_debug "message=\"Deleting backup $archivetodel\""
$tarsnap -d -f "$archivetodel"
prune_backups() {
backuplevel=$1 max=$2

if [ "$max" -gt 0 ]; then
backupslist=$(echo "$archives" | grep -E "$hostname-$backuplevel-.+-$nicedirname$" | sort -rn)
numberofbackups=$(echo "$backupslist" | awk 'END{print NR}')
if [ "$numberofbackups" -gt "$max" ]; then
log_debug "message=\"More than $max $backuplevel backups, deleting the oldest\""
echo "$backupslist" | tail -n +"$(( max+1 ))" | while read -r archiveprefixtodel; do
log_verbose "message=\"Deleting backup prefix $archiveprefixtodel*\""
echo "$archives" | grep -E "^$archiveprefixtodel" | while read -r archivetodel; do
log_debug "message=\"Deleting backup $archivetodel\""
$tarsnap -d -f "$archivetodel"
done
done
done
else
log_debug "message=\"Found $numberofbackups $backuplevel backups, not deleting\""
fi
else
log_debug "message=\"Found $(echo "$monthlybackups" | wc -l) monthly backups, not deleting\""
log_debug "message=\"Keeping all $backuplevel backups indefinitely; not deleting any\""
fi
}

# We keep 31 daily backups
dailybackups=$(echo "$archives" | grep "$hostname-daily-.+-$nicedirname$" | sort -rn)
if [ "$(echo "$dailybackups" | wc -l)" -gt 31 ]; then
log_debug "message=\"More than 30 daily backups, deleting the oldest\""
echo "$dailybackups" | tail -n +32 | while read -r archiveprefixtodel; do
log_verbose "message=\"Deleting backup prefix $archiveprefixtodel*\""
echo "$archives" | grep -E "^$archiveprefixtodel" | while read -r archivetodel; do
log_debug "message=\"Deleting backup $archivetodel\""
$tarsnap -d -f "$archivetodel"
done
done
else
log_debug "message=\"Found $(echo "$dailybackups" | wc -l) daily backups, not deleting any\""
fi
for dir in $backuptargets; do
log_debug "message=\"Checking $dir for old backups to delete\""
nicedirname=$(echo "$dir" | tr -d '/')

prune_backups yearly $yearlybackups
prune_backups monthly $monthlybackups
prune_backups daily $dailybackups
done

# Run the post-backup script
Expand Down
7 changes: 7 additions & 0 deletions acts.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ verbose=1
# Where acts should write its lockfile.
# Default: /var/run/acts
#lockfile=/tmp/acts

# How many backups of each type to keep
# For all limits, 0 means keep indefinitely
# Defaults: 31 daily, 12 monthly, and yearly indefinitely
# dailybackups=31
# monthlybackups=12
# yearlybackups=0

0 comments on commit d8f907a

Please sign in to comment.