1#!/bin/sh 2 3TARSNAP_CMD=/usr/local/bin/tarsnap 4 5path2name() { 6 res=$(echo "$1" | sed -E -e 's,/+,/,g' -e 's,/$|^/,,g' -e 's,/,-,g') 7 if [ -z "$res" ]; then 8 res='ROOT' 9 fi 10 echo $res 11} 12 13something_wrong=0 14 15# make the appropriately named backup 16create_backup() 17{ 18 path=$1 19 type=$2 20 21 case "$type" in 22 daily) 23 now=$(date +"$type-%Y-%m-%d") 24 ;; 25 weekly) 26 now=$(date +"$type-%Y-%U") 27 ;; 28 monthly) 29 now=$(date +"$type-%Y-%m") 30 ;; 31 yearly) 32 now=$(date +"$type-%Y") 33 ;; 34 *) 35 echo "unknown backup type: $type" 36 exit 1 37 esac 38 39 fullname="$(path2name "$path")-$now" 40 # look for an existing backup with this name 41 if $TARSNAP_CMD --list-archives | grep -q "^${fullname}$"; then 42 echo "* backup $fullname already exists, skipping..." 43 else 44 echo " * making backup: $fullname" 45 $TARSNAP_CMD -c -f "$fullname" "$path" || something_wrong=1 46 fi 47} 48 49# delete the named backup 50delete_backup() 51{ 52 backup=$1 53 echo " * deleting old backup: $backup" 54 $TARSNAP_CMD -d -f "$backup" 55} 56 57# make a $type backup of path, cleaning up old ones 58do_path() 59{ 60 path=$1 61 keep=$2 62 type=$3 63 64 name="$(path2name "$path")" 65 66 # create the regex matching the type of backup we're currently working on 67 case "$type" in 68 daily) 69 # $name-daily-2009-01-01 70 regex="^$name-$type-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$" 71 ;; 72 weekly) 73 # weekly-2009-01 74 regex="^$name-$type-[0-9][0-9][0-9][0-9]-[0-9][0-9]$" 75 ;; 76 monthly) 77 # monthly-2009-01 78 regex="^$name-$type-[0-9][0-9][0-9][0-9]-[0-9][0-9]$" 79 ;; 80 yearly) 81 # yearly-2009 82 regex="^$name-$type-[0-9][0-9][0-9][0-9]$" 83 ;; 84 *) 85 echo "unknown backup type: $type" 86 exit 1 87 esac 88 89 create_backup "$path" "$type" 90 91 # get a list of all of the backups of this type sorted alpha, which 92 # effectively is increasing date/time 93 backups=$($TARSNAP_CMD --list-archives | grep "$regex" | sort) 94 count=$(echo "$backups" | wc -l) 95 if [ "$count" -ge 0 ]; then 96 # how many items should we delete 97 delete=$((count - keep)) 98 count=0 99 # walk through the backups, deleting them until we've trimmed deleted 100 for backup in $backups; do 101 if [ $count -ge $delete ]; then 102 break 103 fi 104 delete_backup "$backup" 105 count=$((count + 1)) 106 done 107 fi 108} 109 110# make $type backups, for paths, cleaning up old ones 111do_backups() 112{ 113 paths=$1 114 keep=$2 115 type=$3 116 117 echo "" 118 echo "Doing tarsnap $type backups:" 119 for path in $paths; do 120 do_path "$path" "$keep" "$type" 121 done 122 if [ -n "$something_wrong" ]; then 123 exit 3 124 fi 125} 126 127if [ $# -ne 3 ]; then 128 echo "Usage: $0 \"<paths>\" <keep> daily|weekly|monthly|yearly" 129 exit 2 130fi 131 132# FreeBSD 12.0 adds an anticongestion function 133if [ -n "$anticongestion_sleeptime" ]; then 134 anticongestion 135fi 136 137do_backups "$1" "$2" "$3" 138