Skip to content

Instantly share code, notes, and snippets.

@patricksimpson
Created April 11, 2019 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patricksimpson/fc5e4b33383249a96324f918effeca29 to your computer and use it in GitHub Desktop.
Save patricksimpson/fc5e4b33383249a96324f918effeca29 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
$prefix = 'com.apple.TimeMachine.'
$host = 'rsync'
$repo = 'laptop'
# Where the snapshot will be mounted.
$mount = "#{Dir.home}/borg"
$ref_file = "#{Dir.home}/.borg-snapshot"
# Define exclusions here.
# https://borgbackup.readthedocs.io/en/latest/usage/help.html#borg-help-patterns
$exclude_file = "#{Dir.home}/.borg-exclude.txt"
# This is a gpg encrypted file that contains the repo password.
$password_file = "#{Dir.home}/.borg-rsync-pass.gpg"
def record_snapshot snapshot
File.new($ref_file, "w")
File.open($ref_file, "w") { |f| f.write snapshot }
end
def cleanup
puts "Cleaning up after the borg..."
ref = File.read($ref_file)
`diskutil umount #{$mount}`
`tmutil deletelocalsnapshots #{ref}`
File.delete($ref_file)
end
def run_borg
dotfiles = Dir.glob(File.expand_path('~/.*'))
.map { |file| "#{$mount}#{file}"}
.select { |f| f[-1] != "." }
.join " "
library = "#{$mount}/Users/asimpson/Library"
projects = "#{$mount}/Users/asimpson/Projects"
ENV['BORG_PASSCOMMAND'] = "gpg -dq #{$password_file}"
puts "breaking lock if there is one..."
`borg break-lock --remote-path=borg1 #{$host}:#{$repo}`
puts "starting borg create..."
`borg create --remote-path=borg1 --list -s --exclude-from #{$exclude_file} #{$host}:#{$repo}/::{now} #{dotfiles} #{library} #{projects}`
puts "pruning..."
`borg prune --remote-path=borg1 -s --keep-daily 10 --keep-monthly 6 #{$host}:#{$repo}`
end
def new
snapshot = `tmutil localsnapshot`.split(':')[1].strip
`diskutil umount #{$mount}`
`mount_apfs -s #{$prefix}#{snapshot} / #{$mount}`
record_snapshot snapshot
end
existing_snapshot_file = File.file?($ref_file) && File.read($ref_file)
local_snapshots = !`tmutil listlocalsnapshots /`.empty?
if existing_snapshot_file and local_snapshots then
puts "Found existing snapshot. Resuming..."
`mount_apfs -s #{$prefix}#{existing_snapshot_file} / #{$mount}`
else
puts "Starting new backup..."
new
end
run_borg
cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment