mpbackup/mpbackup
2020-03-25 10:26:10 +01:00

90 lines
2.4 KiB
Ruby

#!/usr/bin/env ruby
require 'io/console'
require 'optparse'
require 'pathname'
require 'yaml'
ENV.delete('RESTIC_REPOSITORY')
ENV.delete('RESTIC_PASSWORD')
DEFAULT_CONFIG_FILE = Pathname.new('/etc/mpbackup.yaml')
options = {}
OptionParser.new do |parser|
parser.on("-f CONFIG_FILE", "--config-file CONFIG_FILE", "Path to config file") do |v|
options[:config_file] = v
end
parser.on("-h", "--help", "Prints this help") do
puts parser
exit
end
end.parse!
if options[:config_file]
config_file = Pathname.new(options[:config_file])
else
config_file = DEFAULT_CONFIG_FILE
end
if !Pathname.new(config_file).exist? then
STDERR.puts "Config file #{config_file} has not been found!"
exit 1
end
def do_backup(config)
ENV['RESTIC_REPOSITORY'] = config['repository']
ENV['RESTIC_PASSWORD'] = STDIN.getpass('Please put in your restic password: ')
puts "Backing up with restic…"
# https://restic.readthedocs.io/en/latest/040_backup.html#including-and-excluding-files
exclude = config.dig('backup', 'exclude')&.flat_map{|e| ['--exclude', e]} || []
paths = config.dig('backup', 'paths') || []
backup_command = ['restic', 'backup', *exclude, *paths]
puts("Command: #{backup_command.join(' ')}")
system(*backup_command)
if $?.exitstatus > 0
STDERR.puts 'Failed to do backup.'
exit 1
end
puts 'Checking restic repo…'
check_command = ['restic', 'check']
puts("Command: #{check_command.join(' ')}")
system(*check_command)
if $?.exitstatus > 0
STDERR.puts "Checking restic repository #{ENV['RESTIC_REPOSITORY']} failed."
exit 1
end
puts "Deleting unnecessary snapshots…"
flags = config['forget'].filter{|k,v| k != 'enable'}
flags = flags.flat_map{|k,v| ['--' + k, v.to_s]}
forget_command = ['restic', 'forget'] + flags
puts("Command: #{forget_command.join(' ')}")
system(*forget_command)
# Data will only be deleted when `restic prune` is executed or when
# `restic forget` is called with `--prune`.
if $?.exitstatus > 0
STDERR.puts "Forgetting snapshots failed."
exit 1
end
ENV.delete('RESTIC_REPOSITORY')
ENV.delete('RESTIC_PASSWORD')
end
configs = YAML.load_stream(File.open(config_file))
if ARGV.empty?
puts "No configuration name has been given. Using the first configuration."
do_backup(configs[0])
else
ARGV.each do |config_name|
configs.each do |config|
if config_name == config['name']
do_backup(config)
end
end
end
end