Source

rsync_backup / rsync_backup.py

Thomas Waldmann e642031 













Thomas Waldmann 6182bd5 
Thomas Waldmann e642031 
Thomas Waldmann 65bcd55 
Thomas Waldmann e642031 
Thomas Waldmann b4d9cdb 
Thomas Waldmann e642031 








Thomas Waldmann 6182bd5 
Thomas Waldmann e642031 
Thomas Waldmann 6182bd5 


Thomas Waldmann 65bcd55 
Thomas Waldmann e642031 
























Thomas Waldmann 6182bd5 
Thomas Waldmann e642031 

Thomas Waldmann 6182bd5 
Thomas Waldmann e642031 






Thomas Waldmann 6182bd5 





Thomas Waldmann e642031 
# -*- coding: ascii
"""
rsync-based backup with space-efficient hardlinks,
multiple generations, extra token for daily, weekly,
monthly, ... backups.

author: Thomas Waldmann
license: BSD
"""

import os
from os.path import exists, abspath
import sys
import errno
import subprocess
import shutil
from exec_cmd import exec_shell as cmd

RSYNC = "rsync -avH --numeric-ids --link-dest=%(link_dst)s %(src)s/ %(dst)s/"


def join(path, n, token):
    if n == 0:
        # there is only ONE "0" directory, no token appended
        token = ""
    return os.path.join(path, "%d%s" % (n, token))


def rsync(src, dst, link_dst, **kw):
    """backup contents of src directory into dst directory"""
    cmd(RSYNC % dict(src=abspath(src),
                     dst=abspath(dst),
                     link_dst=abspath(link_dst)),
        **kw)


def dirshift(path, n, token):
    """shift the directories below the base path:
       N-1 -> N (kill it later)
       N-2 -> N-1
       ...
       0 -> 1
       create an empty 0
    """
    for i in range(n, 0, -1):
        try:
            os.rename(join(path, i-1, token),
                      join(path, i, token))
        except OSError as err:
            if err.errno != errno.ENOENT:
                # ignore if directory does not exist,
                # otherwise raise
                raise
    os.mkdir(join(path, 0, token))
    del_dir = join(path, n, token)
    if exists(del_dir):
        shutil.rmtree(del_dir)


def backup(src, dst, n, token="", **kw):
    """do a backup from src to dst, shifting dirs first"""
    dirshift(dst, n, token)
    rsync(src, join(dst, 0, token), join(dst, 1, token), **kw)


if __name__ == "__main__":
    if len(sys.argv) != 5:
        print "rsb N token src dst"
        sys.exit(1)
    n, token, src, dst = sys.argv[1:]
    try:
        backup(src, dst, int(n), token)
    except subprocess.CalledProcessError as err:
        rc = err.returncode
    else:
        rc = 0
    sys.exit(rc)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.