- Published on
Borg Backup (replacing rdiff-backup)
- Authors
- Name
- Martin Andrews
- @mdda123
Over the past n years, I've used rdiff-backup
as my backup solution. However, this has grown increasingly irritating because :
- If a backup gets terminated early, 'reverting' the incomplete backup takes a long time
- Backups would always complain about bad access modes (MSDOS backup disk vs Linux host system?)
- My backup scripts were written in
Perl
, which is feeling/looking like a weakness now - My backup scripts were due for an overhaul anyway, since new disks/repos have appeared, and old machines have been retired.
Checking online shows that a number of new solutions have appeared, and so I decided to test one out (and actually switch if successful).
The key requirements were :
- Backups should be incremental
- Backup media should be encrypted (so that I can rotate two sets of media, and store one 'insecurely' off-site without worrying)
- Decent include/exclude mechanism for files/folders
- Ability to back up accross network
- Simple tools to get access to my data in the future (or a disaster scenario)
- Support in main-line Fedora
Fortunately, borgbackup
met all these criteria.
Single package required
NB: All the below needs to be done as root
, so that all paths are traversible, and all permissions are preserved
dnf install borgbackup
Mount the media
It makes sense to create a consistent mount-point for the media, since that simplifies all the subsequent scripts :
mkdir -p /media/disk
mount /dev/sdd1 /media/disk
Initialise the repo
First time only (and this will require inventing a decently strong password, with which a keyfile stored with the repo will be secured) :
touch /media/disk/.mounted # enables media presence to be checked easily
borg init --encryption=repokey /media/disk/borg-home
Basic approach using Python
Check that the media is there :
import os
# Need to make sure backup drive is mounted...
disk = '/media/disk'
if not os.path.isfile( os.path.join( disk, '.mounted')):
print("Error : Need to mount %s" % (disk,))
exit(1)
export
the password locally
This gets printed out, so it can be executed on the command line easily:
repo = os.path.join( disk, 'borg-home')
print('')
print("""export BORG_PASSPHRASE=`zenity --title 'Borg Password' --entry --hide-text --text 'Please enter Borg password'`""")
print('')
And produce the command-line text
Creating the necessary command-line entries is easier, and more maintainable, in Python :
def beautify(comment, cmd):
cmd= ' '.join([ l.strip() for l in cmd.split('\n') if not l.strip().startswith('#') ]).strip()
cmd = cmd.replace('{repo}', repo)
return "echo \"%s\" && \\\n %s" % (comment, cmd)
if True:
cmd="""
borg create
--progress
# --list --dry-run
--exclude '*/.Trash*/'
--exclude '*/checkpoint*/'
{repo}::'rdai-{now}'
/mnt/rdai
"""
print(beautify("RedDragonAI", cmd))
Include some utility commands too
print(beautify("See the archives", "borg list {repo}"))
print(beautify("See the compression", "borg info {repo}"))
Check that the backup can be restored
THIS IS A VERY IMPORTANT STEP FOR ANY BACKUP SOLUTION!
Quick example with a file that I knew should be in a specific backup batch :
mkdir -p ~/tmp/
cd ~/tmp/
borg extract /media/disk/borg-home::personal-2019-01-09T01:03:27 mnt/data/Personal/Property/StreetEasy.txt
All done.