class Backup::Storage::FTP

Attributes

ip[RW]

Server IP Address and FTP port

passive_mode[RW]

Use passive mode?

password[RW]

Server credentials

port[RW]

Server IP Address and FTP port

timeout[RW]

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]
username[RW]

Server credentials

Public Class Methods

new(model, storage_id = nil) click to toggle source
Calls superclass method Backup::Storage::Base.new
# File lib/backup/storage/ftp.rb, line 29
def initialize(model, storage_id = nil)
  super

  @port         ||= 21
  @path         ||= 'backups'
  @passive_mode ||= false
  @timeout      ||= nil
  path.sub!(/^~\//, '')
end

Private Instance Methods

connection() { |ftp| ... } click to toggle source

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 48
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
create_remote_path(ftp) click to toggle source

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 99
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
remove!(package) click to toggle source

Called by the Cycler. Any error raised will be logged as a warning.

# File lib/backup/storage/ftp.rb, line 78
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
transfer!() click to toggle source
# File lib/backup/storage/ftp.rb, line 63
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