Skip to content

Instantly share code, notes, and snippets.

@comfuture
Created February 9, 2011 08:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save comfuture/818158 to your computer and use it in GitHub Desktop.
Save comfuture/818158 to your computer and use it in GitHub Desktop.
backup daily to remote host, and delete old backups smarter
#!/bin/bash
date=`date "+%Y-%m-%dT%H_%M_%S"`
HOME=/YOUR/LOCALHOME
SERVER=ID@HOST
DIR=backup
rsync -azP \
--bwlimit=500 \
--delete \
--delete-excluded \
--exclude-from=$HOME/.rsync/exclude \
--link-dest=../current \
$HOME $SERVER:$DIR/incomplete_back-$date \
&& ssh $SERVER \
"mv $DIR/incomplete_back-$date $DIR/back-$date \
&& rm -f $DIR/current \
&& ln -s back-$date $DIR/current"
#!/usr/bin/env python
#
# This script cleans up your rsync backup storage like how TimeMachine does.
#
# It is distributed as a public domain, you can use it at any condition you
# need with your own risks. For comments or patches, write to
# Hyeshik Chang <hyeshik@snu.ac.kr>.
#
import os
import glob
import shutil
from datetime import datetime, timedelta
BACKUPDIR = '/PATH/TO/BACKUP'
CURRENTLINK = 'current'
DIRPATTERN = '*/*'
TIMEFORMAT = '%Y-%m/%d-%H:%M:%S'
DIREXCEPTIONS = []
KEEPINGRULE = [
# (time from now, interval)
(timedelta(days=1), None),
(timedelta(days=7), timedelta(days=1)),
(timedelta(days=30), timedelta(days=7)),
(timedelta(days=365), timedelta(days=30)),
(timedelta(days=1100), timedelta(days=365)),
]
def dirname2datetime(dirname):
return datetime.strptime(dirname, TIMEFORMAT)
def get_snapshots():
r = []
for dirname in glob.glob(DIRPATTERN):
if dirname.startswith(CURRENTLINK):
continue
if not os.path.isdir(dirname) or dirname in DIREXCEPTIONS:
continue
r.append((dirname, dirname2datetime(dirname)))
return sorted(r, reverse=True)
def main():
os.chdir(BACKUPDIR)
snaps = get_snapshots()
curtime = datetime.now()
revrules = KEEPINGRULE[::-1]
rules = zip(revrules, revrules[1:] + [(timedelta(0), None)])
for (period, interval), (nextperiod, _) in rules:
if interval is None:
continue
tmlimit = curtime - nextperiod
newest = curtime - period - interval # accept the first in every period
while snaps and tmlimit > snaps[-1][1]:
dirname, dirtm = snaps.pop()
if dirtm - newest < interval:
shutil.rmtree(dirname)
else:
newest = dirtm
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment