Skip to content

Instantly share code, notes, and snippets.

@jvkersch
Last active June 9, 2017 18:08
Show Gist options
  • Save jvkersch/9322596 to your computer and use it in GitHub Desktop.
Save jvkersch/9322596 to your computer and use it in GitHub Desktop.
Python wrapper around to rsync to facilitate backup
#!/usr/bin/env python
"""
A simple wrapper around rsync for backup.
Usage: create a text file with on each line a resource that you wish to
backup. Paths should be relative to the user's home directory. Entries
starting with '#' are ignored, as are blank lines. Call this script via
python backup_script.py -i [backup_files.txt] [rsync_target_folder]
Do ./backup_script.py -h for more info.
"""
from __future__ import print_function
import argparse
import logging
import os
from subprocess import check_call, CalledProcessError
logger = logging.getLogger(__name__)
RSYNC_CMD = "rsync"
RSYNC_ARGS = "-zvrR"
def make_all_backups(filename, target, dry_run=False):
with open(filename) as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if not line or line.startswith('#'):
continue
logger.info("Backing up resource %r to %r", line, target)
make_single_backup(line, target, dry_run)
def make_single_backup(resource, target, dry_run):
check_call_args = [RSYNC_CMD, RSYNC_ARGS, resource, target]
if not os.path.exists(resource):
logger.error("Resource does not exist: %r", resource)
return
if dry_run:
print("Would execute: %s" % ' '.join(check_call_args))
else:
logger.debug("check_call args: %r", check_call_args)
try:
check_call(check_call_args)
except CalledProcessError:
logger.error("Could not backup %s", resource)
def parse_command_line_args():
parser = argparse.ArgumentParser(
description="A Python wrapper around rsync for backup",
)
parser.add_argument(
"-v", "--verbose",
action="store_true",
default=False,
help="enable verbose logging"
)
parser.add_argument(
"-d", "--dry",
action="store_true",
default=False,
help="dry run (do not call rsync)"
)
parser.add_argument(
"filename", metavar="file", type=str,
help="file containing paths to backup"
)
parser.add_argument(
"target", type=str,
help="destination rsync folder"
)
return parser.parse_args()
def main():
args = parse_command_line_args()
if args.verbose:
logging_level = logging.DEBUG
else:
logging_level = logging.WARNING
logging.basicConfig(level=logging_level)
cwd = os.getcwd()
try:
os.chdir(os.path.expanduser('~'))
make_all_backups(args.filename, args.target, args.dry)
finally:
os.chdir(cwd)
logging.shutdown()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment