Created
February 9, 2011 08:46
-
-
Save comfuture/818158 to your computer and use it in GitHub Desktop.
backup daily to remote host, and delete old backups smarter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 <[email protected]>. | |
# | |
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