ghickman / rrsync forked from RichGuk/rrsync

Simple rsync backup script written in Ruby

This URL has Read+Write access

rrsync / rrsync.rb
100755 77 lines (70 sloc) 3.258 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/ruby
require 'rubygems'
require 'Logger'
require 'benchmark'
require 'ping'
require 'FileUtils'
require 'open3'
 
#============================= OPTIONS ==============================#
# == Options for local machine.
SSH_APP = 'ssh'
RSYNC_APP = 'rsync'
 
EXCLUDE_FILE = '/Users/madnashua/.rsyncignore'
DIR_TO_BACKUP = '/Users/madnashua/'
LOG_FILE = '/Users/madnashua/.log/rrsync/backup_home.log'
LOG_AGE = 'daily'
 
EMPTY_DIR = '/tmp/empty_rsync_dir/' #NEEDS TRAILING SLASH.
# == Options for the remote machine.
SSH_USER = 'madnashua'
SSH_SERVER = '192.168.0.2'
SSH_PORT = '' #Leave blank for default (port 22).
BACKUP_ROOT = '/share/backup/hubris'
BACKUP_DIR = BACKUP_ROOT + '/' + Time.now.strftime('%A').downcase
RSYNC_VERBOSE = '-v'
RSYNC_OPTS = "--force --ignore-errors --delete-excluded --exclude-from=#{EXCLUDE_FILE} --delete --backup --backup-dir=#{BACKUP_DIR} -a"
# == Options to control output
DEBUG = true #If true output to screen else output is sent to log file.
SILENT = false #Total silent = no log or screen output.
#========================== END OF OPTIONS ==========================#
 
if DEBUG && !SILENT
  logger = Logger.new(STDOUT, LOG_AGE)
elsif LOG_FILE != '' && !SILENT
  logger = Logger.new(LOG_FILE, LOG_AGE)
else
  logger = Logger.new(nil)
end
ssh_port = SSH_PORT.empty? ? '' : "-e 'ssh -p #{SSH_PORT}'"
rsync_cleanout_cmd = "#{RSYNC_APP} #{RSYNC_VERBOSE} #{ssh_port} --delete -a #{EMPTY_DIR} #{SSH_USER}@#{SSH_SERVER}:#{BACKUP_DIR}"
rsync_cmd = "#{RSYNC_APP} #{RSYNC_VERBOSE} #{ssh_port} #{RSYNC_OPTS} #{DIR_TO_BACKUP} #{SSH_USER}@#{SSH_SERVER}:#{BACKUP_ROOT}/current"
 
logger.info("Started running at: #{Time.now}")
`growlnotify -t RRsync --image icons/pending.png -m 'Started running at: #{Time.now}'`
run_time = Benchmark.realtime do
  begin
    raise Exception, "Unable to find remote host (#{SSH_SERVER})" unless Ping.pingecho(SSH_SERVER)
       
    FileUtils.mkdir_p("#{EMPTY_DIR}")
    Open3::popen3("#{rsync_cleanout_cmd}") { |stdin, stdout, stderr|
      tmp_stdout = stdout.read.strip
      tmp_stderr = stderr.read.strip
      logger.info("#{rsync_cleanout_cmd}\n#{tmp_stdout}") unless tmp_stdout.empty?
      unless tmp_stderr.empty?
        logger.error("#{rsync_cleanout_cmd}\n#{tmp_stderr}")
        `growlnotify -t RRsync --image icons/fail.png -m 'An error occurred: #{tmp_stderr}'`
      end
    }
    Open3::popen3("#{rsync_cmd}") { |stdin, stdout, stderr|
      tmp_stdout = stdout.read.strip
      tmp_stderr = stderr.read.strip
      logger.info("#{rsync_cmd}\n#{tmp_stdout}") unless tmp_stdout.empty?
      unless tmp_stderr.empty?
        logger.error("#{rsync_cmd}\n#{tmp_stderr}")
        `growlnotify -t RRsync --image icons/fail.png -m 'An error occurred: #{tmp_stderr}'`
      end
    }
    FileUtils.rmdir("#{EMPTY_DIR}")
  rescue Errno::EACCES, Errno::ENOENT, Errno::ENOTEMPTY, Exception => e
    logger.fatal(e.to_s)
    `growlnotify -t RRsync --image icons/fail.png -m 'An error occurred: #{e.to_s}'`
  end
end
logger.info("Finished running at: #{Time.now} - Execution time: #{run_time.to_s[0, 5]}")
`growlnotify -t RRsync --image icons/pass.png -m 'Finished running at: #{Time.now} - Execution time: #{run_time.to_s[0, 5]}'`