class Backup::Storage::RSync

Attributes

additional_rsync_options[RW]

Additional String or Array of options for the rsync cli

additional_ssh_options[RW]

Additional SSH Options

Used to supply a String or Array of options to be passed to the SSH command in `:ssh` and `:ssh_daemon` modes.

For example, if you need to supply a specific SSH key for the `ssh_user`, you would set this to: “-i '/path/to/id_rsa'”. Which would produce:

rsync -e "ssh -p 22 -i '/path/to/id_rsa'"

Arguments may be single-quoted, but should not contain any double-quotes.

Used only for `:ssh` and `:ssh_daemon` modes.

compress[RW]

Flag for compressing (only compresses for the transfer)

host[RW]

Server Address

If not specified, the storage operation will be local.

mode[RW]

Mode of operation

:ssh (default)

Connects to the remote via SSH. Does not use an rsync daemon on the remote.

:ssh_daemon

Connects to the remote via SSH. Spawns a single-use daemon on the remote, which allows certain daemon features (like modules) to be used.

:rsync_daemon

Connects directly to an rsync daemon via TCP. Data transferred is not encrypted.

path[RW]

Path to store the synced backup package file(s) to.

If no host is specified, then path will be local, and the only other used option would be additional_rsync_options. path will be expanded, so '~/my_path' will expand to '$HOME/my_path'.

If a host is specified, this will be a path on the host. If mode is `:ssh` (default), then any relative path, or path starting with '~/' will be relative to the directory the ssh_user is logged into. For `:ssh_daemon` or `:rsync_daemon` modes, this would reference an rsync module/path.

In :ssh_daemon and :rsync_daemon modes, path (or path defined by your rsync module) must already exist.

In :ssh mode or local operation (no host specified), path will be created if needed - either locally, or on the remote for :ssh mode.

port[RW]

SSH or RSync port

For `:ssh` or `:ssh_daemon` mode, this specifies the SSH port to use and defaults to 22.

For `:rsync_daemon` mode, this specifies the TCP port to use and defaults to 873.

rsync_password[RW]

RSync Password

If specified, Backup will write the password to a temporary file and use it with rsync's `–password-file` option for daemon authentication.

Note that setting this will override `rsync_password_file`.

Used only for `:ssh_daemon` and `:rsync_daemon` modes.

rsync_password_file[RW]

RSync Password File

If specified, this path will be passed to rsync's `–password-file` option for daemon authentication.

Used only for `:ssh_daemon` and `:rsync_daemon` modes.

rsync_user[RW]

RSync User

If the user running the backup is not the same user that needs to authenticate with the rsync daemon, specify the user here.

Used only for `:ssh_daemon` and `:rsync_daemon` modes.

ssh_user[RW]

SSH User

If the user running the backup is not the same user that needs to authenticate with the remote server, specify the user here.

The user must have SSH keys setup for passphrase-less access to the remote. If the SSH User does not have passphrase-less keys, or no default keys in their `~/.ssh` directory, you will need to use the `-i` option in `:additional_ssh_options` to specify the passphrase-less key to use.

Used only for `:ssh` and `:ssh_daemon` modes.

Public Class Methods

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

  @mode ||= :ssh
  @port ||= mode == :rsync_daemon ? 873 : 22
  @compress ||= false
  @path ||= '~/backups'
end

Private Instance Methods

compress_option() click to toggle source
# File lib/backup/storage/rsync.rb, line 208
def compress_option
  compress ? ' --compress' : ''
end
create_remote_path() click to toggle source

Runs a 'mkdir -p' command on the host (or locally) to ensure the dest_path exists. This is used because we're transferring a single file, and rsync won't attempt to create the intermediate directories.

This is only applicable locally and in :ssh mode. In :ssh_daemon and :rsync_daemon modes the `path` would include a module name that must define a path on the remote that already exists.

# File lib/backup/storage/rsync.rb, line 177
def create_remote_path
  if host
    run("#{ utility(:ssh) } #{ ssh_transport_args } #{ host } " +
            %Q["mkdir -p '#{ remote_path }'"]) if mode == :ssh
  else
    FileUtils.mkdir_p(remote_path)
  end
end
host_options() click to toggle source
# File lib/backup/storage/rsync.rb, line 186
def host_options
  @host_options ||= begin
    if !host
      ''
    elsif mode == :ssh
      "#{ host }:"
    else
      user = "#{ rsync_user }@" if rsync_user
      "#{ user }#{ host }::"
    end
  end
end
password_option() click to toggle source
# File lib/backup/storage/rsync.rb, line 212
def password_option
  return '' if mode == :ssh

  path = @password_file ? @password_file.path : rsync_password_file
  path ? " --password-file='#{ File.expand_path(path) }'" : ''
end
remote_path() click to toggle source

Other storages add an additional timestamp directory to this path. This is not desired here, since we need to transfer the package files to the same location each time.

# File lib/backup/storage/rsync.rb, line 159
def remote_path
  @remote_path ||= begin
    if host
      path.sub(/^~\//, '').sub(/\/$/, '')
    else
      File.expand_path(path)
    end
  end
end
remove_password_file() click to toggle source
# File lib/backup/storage/rsync.rb, line 242
def remove_password_file
  @password_file.delete if @password_file
end
rsync_command() click to toggle source
# File lib/backup/storage/rsync.rb, line 199
def rsync_command
  @rsync_command ||= begin
    cmd = utility(:rsync) << ' --archive' <<
        " #{ Array(additional_rsync_options).join(' ') }".rstrip
    cmd << compress_option << password_option << transport_options if host
    cmd
  end
end
ssh_transport_args() click to toggle source
# File lib/backup/storage/rsync.rb, line 227
def ssh_transport_args
  args = "-p #{ port } "
  args << "-l #{ ssh_user } " if ssh_user
  args << Array(additional_ssh_options).join(' ')
  args.rstrip
end
transfer!() click to toggle source
# File lib/backup/storage/rsync.rb, line 141
def transfer!
  write_password_file
  create_remote_path

  package.filenames.each do |filename|
    src = "'#{ File.join(Config.tmp_path, filename) }'"
    dest = "#{ host_options }'#{ File.join(remote_path, filename) }'"
    Logger.info "Syncing to #{ dest }..."
    run("#{ rsync_command } #{ src } #{ dest }")
  end
ensure
  remove_password_file
end
transport_options() click to toggle source
# File lib/backup/storage/rsync.rb, line 219
def transport_options
  if mode == :rsync_daemon
    " --port #{ port }"
  else
    %Q[ -e "#{ utility(:ssh) } #{ ssh_transport_args }"]
  end
end
write_password_file() click to toggle source
# File lib/backup/storage/rsync.rb, line 234
def write_password_file
  return unless host && rsync_password && mode != :ssh

  @password_file = Tempfile.new('backup-rsync-password')
  @password_file.write(rsync_password)
  @password_file.close
end