Class: Rsyncbackup
- Inherits:
-
Object
- Object
- Rsyncbackup
- Includes:
- Methadone::CLILogging
- Defined in:
- lib/rsyncbackup.rb,
lib/rsyncbackup/version.rb,
lib/rsyncbackup/utilities.rb
Constant Summary collapse
- VERSION =
"2.1.2"- DEFAULT_EXCLUSIONS =
File.('.rsyncbackup.exclusions', ENV['HOME'])
- DEFAULT_INCOMPLETE_DIR_NAME =
'.incomplete'- DEFAULT_LAST_FULL_DIR_NAME =
'.lastfull'
Instance Attribute Summary collapse
-
#error ⇒ Object
Returns the value of attribute error.
-
#options ⇒ Object
Returns the value of attribute options.
-
#output ⇒ Object
Returns the value of attribute output.
-
#source ⇒ Object
Returns the value of attribute source.
-
#status ⇒ Object
Returns the value of attribute status.
-
#target ⇒ Object
Returns the value of attribute target.
Instance Method Summary collapse
- #_run_the_command(cmd) ⇒ Object
-
#backup_dir_name ⇒ Object
returns the directory name for the current backup directory name consists of a time format: YYYY-MM-DDTHH-MM-SS.
-
#build_command ⇒ Object
returns the command string to execute with all parameters set.
- #copy_lines(str_in, str_out) ⇒ Object
- #finalize ⇒ Object
-
#full_target_path ⇒ Object
returns the full target path, including backup directory name.
-
#initialize(source, target, opts = {}) ⇒ Rsyncbackup
constructor
A new instance of Rsyncbackup.
-
#last_full_backup ⇒ Object
returns the directory name of the last full backup returns nil otherwise.
-
#rsync_executable ⇒ Object
returns the path to the rsync executable If none found, raises an Exception.
- #run ⇒ Object
-
#strip_trailing_separator_if_any(s, keep_if_symlink = false) ⇒ Object
Strip the trailing directory separator from the rsync source or target.
-
#success? ⇒ Boolean
returns true if the rsync command was successful.
-
#temp_target_path ⇒ Object
returns the temporary target path.
Constructor Details
#initialize(source, target, opts = {}) ⇒ Rsyncbackup
Returns a new instance of Rsyncbackup.
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 |
# File 'lib/rsyncbackup.rb', line 11 def initialize(source, target, opts={}) logger.level = Logger::WARN logger.level = Logger::INFO if opts[:verbose] logger.error_level = Logger::DEBUG if opts[:debug] raise "Unknown target: #{target}" unless File.exist?(target) or opts[:dry_run] @source = strip_trailing_separator_if_any(source,true) @target = strip_trailing_separator_if_any(target) @options = { :dry_run => false, :exclusions => DEFAULT_EXCLUSIONS, :archive => true, :one_file_system => true, :hard_links => true, :human_readable => true, :inplace => true, :numeric_ids => true, :delete => true, :link_dest => last_full_backup, :rsync_cmd => rsync_executable }.merge(opts) @incomplete = File.join(target,DEFAULT_INCOMPLETE_DIR_NAME) @complete = File.join(target,backup_dir_name) debug "#{caller(0,1).first} @source: #{@source}, @target: #{@target}, @options: #{@options.inspect}" end |
Instance Attribute Details
#error ⇒ Object
Returns the value of attribute error.
9 10 11 |
# File 'lib/rsyncbackup.rb', line 9 def error @error end |
#options ⇒ Object
Returns the value of attribute options.
9 10 11 |
# File 'lib/rsyncbackup.rb', line 9 def @options end |
#output ⇒ Object
Returns the value of attribute output.
9 10 11 |
# File 'lib/rsyncbackup.rb', line 9 def output @output end |
#source ⇒ Object
Returns the value of attribute source.
9 10 11 |
# File 'lib/rsyncbackup.rb', line 9 def source @source end |
#status ⇒ Object
Returns the value of attribute status.
9 10 11 |
# File 'lib/rsyncbackup.rb', line 9 def status @status end |
#target ⇒ Object
Returns the value of attribute target.
9 10 11 |
# File 'lib/rsyncbackup.rb', line 9 def target @target end |
Instance Method Details
#_run_the_command(cmd) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/rsyncbackup/utilities.rb', line 16 def _run_the_command(cmd) Open3.popen3(cmd) do |stdin, stdout, stderr, t| pid = t.pid stdin.close err_thr = Thread.new { copy_lines(stderr, $stderr) } debug "#{caller(0,1).first} Reading STDOUT" copy_lines(stdout, $stdout) err_thr.join t.value end end |
#backup_dir_name ⇒ Object
returns the directory name for the current backup directory name consists of a time format: YYYY-MM-DDTHH-MM-SS
86 87 88 |
# File 'lib/rsyncbackup/utilities.rb', line 86 def backup_dir_name @backup_dir_name ||= Time.now.strftime("%FT%H-%M-%S") end |
#build_command ⇒ Object
returns the command string to execute with all parameters set
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rsyncbackup/utilities.rb', line 41 def build_command cmd = [] cmd << [:rsync_cmd] cmd << '--dry-run' if [:dry_run] cmd << '--verbose --progress --itemize-changes' if ([:verbose] || [:debug]) cmd << '--archive' if [:archive] cmd << '--one-file-system' if [:one_file_system] cmd << '--hard-links' if [:hard_links] cmd << '--human-readable' if [:human_readable] cmd << '--inplace' if [:inplace] cmd << '--numeric-ids' if [:numeric_ids] cmd << '--delete' if [:delete] cmd << "--exclude-file #{[:exclusions]}" if File.exist?([:exclusions]) cmd << "--link-dest '#{[:link_dest]}'" if [:link_dest] cmd << ?" + @source + ?" cmd << ?" + temp_target_path + ?" cmd.join(' ') end |
#copy_lines(str_in, str_out) ⇒ Object
28 29 30 |
# File 'lib/rsyncbackup/utilities.rb', line 28 def copy_lines(str_in, str_out) str_in.each_line {|line| str_out.puts line} end |
#finalize ⇒ Object
65 66 67 68 69 |
# File 'lib/rsyncbackup.rb', line 65 def finalize File.rename(@incomplete, @complete) if File.exist?(@incomplete) File.write(File.join(@target,DEFAULT_LAST_FULL_DIR_NAME), backup_dir_name) info "Backup saved in #{@complete}" end |
#full_target_path ⇒ Object
returns the full target path, including backup directory name
91 92 93 |
# File 'lib/rsyncbackup/utilities.rb', line 91 def full_target_path @full_target_path ||= File.join(@target, backup_dir_name) end |
#last_full_backup ⇒ Object
returns the directory name of the last full backup returns nil otherwise
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/rsyncbackup/utilities.rb', line 65 def last_full_backup unless @last_full_backup lastfull = File.join(@target,DEFAULT_LAST_FULL_DIR_NAME) @last_full_backup = unless File.exist?(lastfull) nil else last_full_directory = IO.readlines(lastfull).first.chomp unless File.exist?(File.join(@target,last_full_directory)) nil else last_full_directory end end end @last_full_backup end |
#rsync_executable ⇒ Object
returns the path to the rsync executable If none found, raises an Exception
104 105 106 107 108 |
# File 'lib/rsyncbackup/utilities.rb', line 104 def rsync_executable rsync = `which rsync`.chomp raise "No rsync executable. Are you sure it\'s installed?" if rsync.empty? rsync end |
#run ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/rsyncbackup.rb', line 44 def run @cmd = build_command info "Backing up #{@source} to #{@target} on #{Time.now}" info "Rsync command: #{@cmd}" info "Dry run only" if [:dry_run] if File.exist? temp_target_path warn "Preexisting temporary target. Moving it aside." File.rename temp_target_path, "#{temp_target_path}-#{Time.now.to_i}" end # the dry run option will be passed through to the rsync command, # so we still do want to run it. self.status = _run_the_command(@cmd) debug "#{caller(0,1).first} self.status #{self.status.inspect}" raise "Rsync Error: exit status: #{self.status.exitstatus}" unless (self.status.success? || self.status.exitstatus == 23) # don't abort if some files could not be transferred finalize self end |
#strip_trailing_separator_if_any(s, keep_if_symlink = false) ⇒ Object
Strip the trailing directory separator from the rsync source or target.
- s
-
string to strip
114 115 116 117 118 119 120 121 122 |
# File 'lib/rsyncbackup/utilities.rb', line 114 def strip_trailing_separator_if_any(s,keep_if_symlink=false) s = s.to_s s_s = s.sub(%r{#{File::SEPARATOR}+$},'') unless keep_if_symlink s_s else File.symlink?(s_s) ? s : s_s end end |
#success? ⇒ Boolean
returns true if the rsync command was successful
35 36 37 |
# File 'lib/rsyncbackup/utilities.rb', line 35 def success? (@status.nil?) ? nil : @status.success? end |
#temp_target_path ⇒ Object
returns the temporary target path
96 97 98 |
# File 'lib/rsyncbackup/utilities.rb', line 96 def temp_target_path @temp_target_path ||= File.join(@target, DEFAULT_INCOMPLETE_DIR_NAME) end |