lib/backup/storage/rsync.rb in backup-3.0.19 vs lib/backup/storage/rsync.rb in backup-3.0.20

- old
+ new

@@ -9,11 +9,11 @@ Backup::Dependency.load('net-ssh') module Backup module Storage class RSync < Base - include Backup::CLI + include Backup::CLI::Helpers ## # Server credentials attr_accessor :username, :password @@ -28,118 +28,128 @@ ## # Flag to use local backups attr_accessor :local ## - # Creates a new instance of the RSync storage object - # First it sets the defaults (if any exist) and then evaluates - # the configuration block which may overwrite these defaults - def initialize(&block) - load_defaults! - - @port ||= 22 - @path ||= 'backups' - @local ||= false - - instance_eval(&block) if block_given? - write_password_file! - - @time = TIME - @path = path.sub(/^\~\//, '') - end - - ## # This is the remote path to where the backup files will be stored def remote_path File.join(path, TRIGGER) end ## # Performs the backup transfer def perform! + super + write_password_file! transfer! + ensure remove_password_file! end - ## - # Returns Rsync syntax for defining a port to connect to - def port - "-e 'ssh -p #{@port}'" - end + private ## - # Returns Rsync syntax for using a password file - def password - "--password-file='#{@password_file.path}'" unless @password.nil? + # Set configuration defaults before evaluating configuration block, + # after setting defaults from Storage::Base + def pre_configure + super + @port ||= 22 + @path ||= 'backups' + @local ||= false end ## - # RSync options - # -z = Compresses the bytes that will be transferred to reduce bandwidth usage - def options - "-z" + # Adjust configuration after evaluating configuration block, + # after adjustments from Storage::Base + def post_configure + super + @path = path.sub(/^\~\//, '') end - private - ## # Establishes a connection to the remote server and returns the Net::SSH object. - # Not doing any instance variable caching because this object gets persisted in YAML - # format to a file and will issues. This, however has no impact on performance since it only - # gets invoked once per object for a #transfer! and once for a remove! Backups run in the - # background anyway so even if it were a bit slower it shouldn't matter. def connection - Net::SSH.start(ip, username, :password => @password, :port => @port) + Net::SSH.start(ip, username, :password => password, :port => port) do |ssh| + yield ssh + end end ## # Transfers the archived file to the specified remote server def transfer! - Logger.message("#{ self.class } started transferring \"#{ remote_file }\".") create_remote_directories! - if @local - run("#{ utility(:rsync) } '#{ File.join(local_path, local_file) }' '#{ File.join(remote_path, TIME+'.'+remote_file[20..-1]) }'") + + Logger.message "#{storage_name} started transferring " + + "'#{ filename }' to '#{ ip }'." + + if local + run( + "#{ utility(:rsync) } '#{ File.join(local_path, filename) }' " + + "'#{ File.join(remote_path, filename[20..-1]) }'" + ) else - run("#{ utility(:rsync) } #{ options } #{ port } #{ password } '#{ File.join(local_path, local_file) }' '#{ username }@#{ ip }:#{ File.join(remote_path, remote_file[20..-1]) }'") + run( + "#{ utility(:rsync) } #{ rsync_options } #{ rsync_port } " + + "#{ rsync_password_file } '#{ File.join(local_path, filename) }' " + + "'#{ username }@#{ ip }:#{ File.join(remote_path, filename[20..-1]) }'" + ) end end ## - # Removes the transferred archive file from the server + # Note: RSync::Storage doesn't cycle def remove! - response = connection.exec!("rm #{ File.join(remote_path, remote_file) }") - if response =~ /No such file or directory/ - Logger.warn "Could not remove file \"#{ File.join(remote_path, remote_file) }\"." - end + nil end ## # Creates (if they don't exist yet) all the directories on the remote # server in order to upload the backup file. def create_remote_directories! if @local mkdir(remote_path) else - connection.exec!("mkdir -p '#{ remote_path }'") + connection do |ssh| + ssh.exec!("mkdir -p '#{ remote_path }'") + end end end ## # Writes the provided password to a temporary file so that # the rsync utility can read the password from this file def write_password_file! - unless @password.nil? + unless password.nil? @password_file = Tempfile.new('backup-rsync-password') - @password_file.write(@password) + @password_file.write(password) @password_file.close end end ## # Removes the previously created @password_file # (temporary file containing the password) def remove_password_file! - @password_file.unlink unless @password.nil? + @password_file.delete if @password_file + end + + ## + # Returns Rsync syntax for using a password file + def rsync_password_file + "--password-file='#{@password_file.path}'" if @password_file + end + + ## + # Returns Rsync syntax for defining a port to connect to + def rsync_port + "-e 'ssh -p #{port}'" + end + + ## + # RSync options + # -z = Compresses the bytes that will be transferred to reduce bandwidth usage + def rsync_options + "-z" end end end end