Skip to content

Instantly share code, notes, and snippets.

@aeris
Last active Aug 29, 2015
Embed
What would you like to do?
RSync snapshot
#!/usr/bin/env ruby
require 'fileutils'
load '/etc/rsync-snapshot.conf'
def protect
if File.exists? LOCK_FILE
print "#{$0} already running\n"
exit -1
end
File.new LOCK_FILE, 'w'
%w(INT TERM QUIT).each { |s| Signal.trap(s) { deprotect } }
end
def deprotect
File.delete LOCK_FILE if File.exists? LOCK_FILE
end
def rsync(from, to)
cmd = %w(/usr/bin/rsync -auxHhEAX --delete --ignore-errors)
exclude = File.join from, EXCLUDE_FILE
cmd += ['--exclude-from', exclude] if File.exists? exclude
cmd += [from, to]
system *cmd
end
def save(name, folder)
directory = File.join SNAPSHOT_DIR, name
FileUtils.makedirs directory unless Dir.exists? directory
to = File.join directory, Time.new.strftime('%Y-%m-%d')
FileUtils.remove_dir to if Dir.exists? to
old = Dir.entries(directory).reject { |name| %w(. ..).include? name }.sort
until old.size < SIZE
first = old.shift
FileUtils.remove_dir File.join directory, first
end
last = old.pop
system '/bin/cp', '-al', File.join(directory, last), to unless last.nil?
# rsync folder, to
end
unless Dir.exists? SNAPSHOT_DIR
print "#{SNAPSHOT_DIR} not existing\n"
exit -1
end
protect
processes = []
BACKUP.each do |name, folder|
p name, folder
if Dir.exists? folder
processes << Thread.new { save name, folder }
end
end
processes.each { |p| p.join }
deprotect
SNAPSHOT_DIR = '/mnt/backup/snapshots'
LOCK_FILE = "#{SNAPSHOT_DIR}/rsync-snapshot.lock"
SIZE = 52
EXCLUDE_FILE = '.rsync-snapshot.ignore';
BACKUP = {
'aeris' => '/home/aeris/'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment