Skip to content

Instantly share code, notes, and snippets.

@tobiastom
Forked from anonymous/rsync_backup.py
Created October 18, 2011 10:56
Show Gist options
  • Save tobiastom/1295159 to your computer and use it in GitHub Desktop.
Save tobiastom/1295159 to your computer and use it in GitHub Desktop.
Hardlink backup with rsync
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys, os, popen2, time, subprocess
SRC = "/"
HOST = "user@host"
DEST = "/backup_module/%(DATE)s/"
LINK_DEST = "/%(LAST_DATE)s"
EXCLUDE = ["/home/henryk/_secure", "/home/henryk/mnt", "/tmp", "/home/henryk/tmp"]
OPTIONS = ["-HAXax", "--stats", "--delete", "-b"]
TIMESTAMP_FILE = "/home/henryk/.backup_dates/%(host)s__%(src)s__%(dest)s"
#PASSWORD = "REDACTED"
PASSWORD = None
def check_host(hostname):
cmd = ["rsync", "rsync://%s/" % hostname]
p = popen2.Popen3(cmd)
return p.wait() == 0
def _format_timestamp_file(host, src, dest):
host = host.replace("/", "_")
src = src.replace("/", "_")
dest = dest.replace("/", "_")
return TIMESTAMP_FILE % locals()
def get_last_date(*args, **kwargs):
if TIMESTAMP_FILE is None: return None
fname = _format_timestamp_file(*args, **kwargs)
result = None
try:
fp = file(fname, "r")
result = fp.read().strip()
fp.close()
except: pass
return result
def set_last_date(last_date, *args, **kwargs):
if TIMESTAMP_FILE is None: return None
fname = _format_timestamp_file(*args, **kwargs)
try:
fp = file(fname, "w")
fp.write(last_date)
fp.close()
except:
print >>sys.stderr, "Warning: Couldn't write timestamp file"
def prepare_exclude(exclude, src):
result = []
for name in exclude:
if name.startswith(src):
name = name[len(src):]
if not name.startswith("/"): name = "/" + name
result.append("--exclude=%s" % name)
return result
if __name__ == "__main__":
DATE = time.strftime("%Y-%m-%d",time.gmtime())
LAST_DATE = get_last_date(HOST, SRC, DEST)
if LAST_DATE is not None:
if cmp(LAST_DATE, DATE) != -1:
print >>sys.stderr, "Error: Last Backup is not at least one day away, aborting"
sys.exit(1)
if not check_host(HOST):
print >>sys.stderr, "Error: Rsync not available, aborting"
sys.exit(1)
print "Start %s" % time.strftime("%a, %d %b %Y %H:%M:%S %z")
command = ["rsync"] + OPTIONS + prepare_exclude(EXCLUDE, SRC)
if LINK_DEST is not None:
if "%(LAST_DATE)s" in LINK_DEST and LAST_DATE is None:
pass
else:
command.append( "--link-dest=%s" % (LINK_DEST % locals()) )
if PASSWORD is not None:
rpipe, wpipe = os.pipe()
os.write(wpipe, PASSWORD+"\n")
command.append("--password-file=/dev/fd/%i" % rpipe)
command.append(SRC)
command.append("rsync://%s%s" % (HOST, DEST % locals()))
retcode = subprocess.call(command)
print "Stop %s" % time.strftime("%a, %d %b %Y %H:%M:%S %z")
if retcode in [0,23,24]:
set_last_date(DATE, HOST, SRC, DEST)
sys.exit(retcode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment