class Backup::Storage::FTP
Attributes
Server IP Address and FTP
port
Use passive mode?
Server credentials
Server IP Address and FTP
port
Configure connection open and read timeouts. Net::FTP’s open_timeout and read_timeout will both be configured using this setting. @!attribute [rw] timeout
@param [Integer|Float] @return [Integer|Float]
Server credentials
Public Class Methods
Backup::Storage::Base::new
# File lib/backup/storage/ftp.rb, line 30 def initialize(model, storage_id = nil) super @port ||= 21 @path ||= 'backups' @passive_mode ||= false @timeout ||= nil path.sub!(/^~\//, '') end
Private Instance Methods
Establishes a connection to the remote server
Note: Since the FTP
port is defined as a constant in the Net::FTP class, and might be required to change by the user, we dynamically remove and re-add the constant with the provided port value
# File lib/backup/storage/ftp.rb, line 49 def connection if Net::FTP.const_defined?(:FTP_PORT) Net::FTP.send(:remove_const, :FTP_PORT) end; Net::FTP.send(:const_set, :FTP_PORT, port) Net::FTP.open(ip, username, password) do |ftp| if timeout ftp.open_timeout = timeout ftp.read_timeout = timeout end ftp.passive = true if passive_mode yield ftp end end
Creates (if they don’t exist yet) all the directories on the remote server in order to upload the backup file. Net::FTP does not support paths to directories that don’t yet exist when creating new directories. Instead, we split the parts up in to an array (for each ‘/’) and loop through that to create the directories one by one. Net::FTP raises an exception when the directory it’s trying to create already exists, so we have rescue it
# File lib/backup/storage/ftp.rb, line 100 def create_remote_path(ftp) path_parts = Array.new remote_path.split('/').each do |path_part| path_parts << path_part begin ftp.mkdir(path_parts.join('/')) rescue Net::FTPPermError; end end end
Called by the Cycler
. Any error raised will be logged as a warning.
# File lib/backup/storage/ftp.rb, line 79 def remove!(package) Logger.info "Removing backup package dated #{ package.time }..." remote_path = remote_path_for(package) connection do |ftp| package.filenames.each do |filename| ftp.delete(File.join(remote_path, filename)) end ftp.rmdir(remote_path) end end
# File lib/backup/storage/ftp.rb, line 64 def transfer! connection do |ftp| create_remote_path(ftp) package.filenames.each do |filename| src = File.join(Config.tmp_path, filename) dest = File.join(remote_path, filename) Logger.info "Storing '#{ ip }:#{ dest }'..." ftp.put(src, dest) end end end