Skip to content

Instantly share code, notes, and snippets.

@creshal
Created October 15, 2015 13:44

Revisions

  1. creshal created this gist Oct 15, 2015.
    64 changes: 64 additions & 0 deletions backup-rsync
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    #! /bin/python
    import sys,os,time,glob,shutil
    import subprocess as sp

    def backup (src,dst):
    src = sys.argv[1]
    exclude_file = os.path.join (src,'.backup-exclude')
    dst = sys.argv[2]
    dst_dir = os.path.join (dst,'%i'%time.time())
    lnk_dir = get_old_backups (dst)[-1]

    try:
    rsync_call = ['rsync','-aHAxXP','--exclude=lost+found',src,dst_dir]
    if lnk_dir:
    rsync_call.append ('--link-dest='+lnk_dir)
    if ':' in dst:
    rsync_call.append ('-M--fake-super')
    if os.path.exists (exclude_file):
    rsync_call.append ('--exclude-from='+exclude_file)
    print (' '.join (rsync_call))
    sp.check_call (rsync_call)
    except sp.CalledProcessError as e:
    print (e)
    sys.exit (1)
    prune_backups (dst)


    def get_old_backups (dst):
    if os.path.isdir (dst):
    old_backups = list(map (os.path.abspath, glob.glob (dst+'/*')))
    else:
    host,directory = dst.split(':',1)
    directory = directory if directory.startswith('/') else '$PWD/'+directory
    find_call = ['ssh',host,'find',directory,'-mindepth','1','-maxdepth','1',
    '-type','d']
    old_backups = sp.check_output(find_call).decode('utf8').strip().split('\n')

    if not len (old_backups): return
    return sorted(old_backups)

    def prune_backups (dst):
    old_backups = get_old_backups (dst)
    remote = not os.path.isdir(dst)
    if remote:
    host,directory = dst.split(':',1)

    while len (old_backups) > 3:
    print ('Pruning old backup '+old_backups[0])
    if remote:
    try:
    sp.call (['ssh',host,'rm','-r',old_backups.pop (0)])
    except sp.CalledProcessError as e:
    print ('Failed to delete old backup:\n'+e)
    else:
    shutil.rmtree (old_backups.pop(0))



    if __name__ == '__main__':
    if len(sys.argv) != 3 or '-h' in sys.argv:
    print ('Usage: %s rsyncsource rsynctarget'%sys.argv[0])
    sys.exit ()

    backup (sys.argv[1],sys.argv[2])