Skip to content

Instantly share code, notes, and snippets.

@hradec
Created July 15, 2021 17:18
Show Gist options
  • Save hradec/8e131e9211d408bc4884e997b5e00194 to your computer and use it in GitHub Desktop.
Save hradec/8e131e9211d408bc4884e997b5e00194 to your computer and use it in GitHub Desktop.
A simple and handy script to automate backups using rsync. I use it on synology NAS to backup data every night for 6 hours max, limiting the max bandwidth.
#!/usr/bin/env python
import os, sys, datetime
import argparse
rsync='''rsync -avpPW %s --no-compress --inplace --delete --stats --exclude '#*' --exclude 'mirror.log' -e 'ssh -T -c [email protected] -o Compression=no -x -p %s' %s/ %s/ '''
# fbbackup01.myds.me
parser = argparse.ArgumentParser(description='Backup folders to backup nas')
parser.add_argument('source', help='a source path to copy files from.')
parser.add_argument('target', help='the target path to copy files to. default=%(default)s', nargs='?', default="/volume1/netbakup01/3D/")
parser.add_argument('--nas', help='the hostname of the nas to connect to. default=%(default)s', default=None)
parser.add_argument('--nas-user', help='the username to use to log into the nas. default: %(default)s', default="<nas>u")
parser.add_argument('--list', help='a text file with a list of folder names in the <source> path, to be copied over to <target>.', default=None)
parser.add_argument('--port', help='ssh port to use', default='62022')
parser.add_argument('-n', help='dry run', action='store_true', default=None)
parser.add_argument('-nn', help='dry run rsync', action='store_true', default=None)
parser.add_argument('-b', help='bandwidth limit', default=None)
parser.add_argument('-t', help='number of time to run the backup for. Use "h" suffix for hours and "m" suffix for minutes. ex: 1h30m', default=None)
args = parser.parse_args()
target = args.target
if args.nas:
target = "%s@%s:%s" % (args.nas_user.replace("<nas>",args.nas.split('.')[0].replace('fbb','fbB')), args.nas, args.target)
sources = [ args.source.rstrip('/') ]
if args.list:
sources = [ args.source.rstrip('/')+'/'+x.strip().strip('/') for x in open(args.list).readlines() if x.strip()[0] != '#' ]
extra = ''
pre = ''
if args.nn:
extra+=' -n '
if args.b:
extra+=' --bwlimit=%s ' % int(float(args.b)*1024)
if args.t:
h=0
m=0
if 'h' not in args.t:
m = float(args.t.split('m')[0])
else:
split=args.t.split('h')
h=float(split[0])
if split[1]:
m=split[1].split('m')[0]
if m:
m = float(m)
pre = 'timeout %s ' % ( int(h*60*60) + int(m*60) )
for s in sources:
t = target.rstrip('/')+'/'+os.path.basename(s)
cmd = pre + rsync % (extra, args.port, s, t)
print('='*120)
print(datetime.datetime.now())
print(cmd)
sys.stdout.flush()
if not args.n:
os.system(cmd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment