class Backup::RemoteData

Attributes

script[RW]
server_command[RW]
server_host[RW]

server options

server_path[RW]
server_ssh_options[RW]
temp_dir_path[RW]

Public Class Methods

new(model, name, &block) click to toggle source
# File lib/backup/remote_data.rb, line 32
def initialize(model, name, &block)
  @model   = model
  @name    = name.to_s
  @options = {
    :sudo        => false,
    :root        => false,
    :paths       => [],
    :excludes    => [],
    :tar_options => ''
  }

  DSL.new(@options).instance_eval(&block)

  # ssh options
  self.server_host = @options[:server_host]

  # server options
  ssh_options = {}
  v = @options[:server_ssh_user]
  ssh_options[:user] = v if v

  v = @options[:server_ssh_password]
  ssh_options[:password] = v if v

  v = @options[:server_ssh_key]
  ssh_options[:key] = v if v

  v = @options[:server_ssh_port]
  ssh_options[:port] = v if v


  self.server_ssh_options = ssh_options

  # server options
  self.server_path = @options[:server_path]
  self.server_command = @options[:server_command]
  self.script = @options[:script]
  self.temp_dir_path = @options[:temp_dir_path] || '/tmp'
end

Public Instance Methods

perform!() click to toggle source
# File lib/backup/remote_data.rb, line 72
def perform!
  Logger.info "Creating Archive '#{ name }'..."

  # local archive
  path = File.join(Config.tmp_path, @model.trigger, 'archives')
  FileUtils.mkdir_p(path)

  extension = 'tar'
  #temp_archive_file = File.join(path, "#{ name }.#{ extension }")

  remote = Backup::Remote::Command.new


  remote_archive_file = server_path

  # generate backup on remote server
  remote_script = script

  if remote_script && remote_script!=""
    # use script
    # upload script

    local_script_path = File.join(Config.root_path, remote_script)

    f_remote = Tempfile.new('backup')
    remote_script_path = f_remote.path+"."+File.extname(local_script_path)

    Logger.info "upload script #{local_script_path} --> #{remote_script_path}"

    remote.ssh_upload_file(server_host, server_ssh_options, local_script_path, remote_script_path)

    cmd_remote = "chmod +x #{remote_script_path} && sh #{remote_script_path}"
    res_generate = remote.run_ssh_cmd(server_host, server_ssh_options, cmd_remote)

    # delete temp script
    cmd_delete = "rm -rf #{remote_script_path}"
    res_delete = remote.run_ssh_cmd(server_host, server_ssh_options, cmd_delete)

  else
    # use command
    cmd_remote = server_command
    res_generate = remote.run_ssh_cmd(server_host, server_ssh_options, cmd_remote)
  end

  if res_generate[:res]==0
    raise "Cannot create backup on server: #{res_generate[:error]}"
  end



  #Dir.mktmpdir do |temp_dir|

  #temp_local_file = File.join("#{temp_dir}", File.basename(server_path))

  temp_local_file = File.join("#{temp_dir_path}/#{Time.now.to_i}#{rand(1000)}/", File.basename(server_path))

  #path = File.expand_path "#{Dir.tmpdir}/#{Time.now.to_i}#{rand(1000)}/"
  FileUtils.mkdir_p File.dirname(temp_local_file)

  # download backup
  Logger.info "download from #{remote_archive_file} to #{temp_local_file}"

  res_download = remote.ssh_download_file(server_host, server_ssh_options, remote_archive_file, temp_local_file)

  if res_download[:res]==0
    raise 'Cannot download file from server'
  end

  # delete archive on server
  res_delete = remote.run_ssh_cmd(server_host, server_ssh_options, "rm #{remote_archive_file}")


  # process archive locally

  pipeline = Pipeline.new

  #temp_tar_root= tar_root
  #temp_tar_root= temp_dir_path
  temp_tar_root= File.dirname(temp_local_file)
  pipeline.add(
      "#{ tar_command } #{ tar_options } -cPf - -C #{temp_tar_root } #{ File.basename(temp_local_file) }",
      tar_success_codes
  )

  extension = 'tar'
  @model.compressor.compress_with do |command, ext|
    pipeline << command
    extension << ext
  end if @model.compressor

  pipeline << "#{ utility(:cat) } > '#{ File.join(path, "#{ name }.#{ extension }") }'"

  #puts "commands: #{pipeline.commands}"
  #exit

  pipeline.run


  if pipeline.success?
    Logger.info "Archive '#{ name }' Complete!"
  else
    raise Error, "Failed to Create Archive '#{ name }'\n" +
        pipeline.error_messages
  end

  if File.exists?(temp_local_file)
    FileUtils.rm_rf(temp_local_file)
    FileUtils.rm_rf(File.dirname(temp_local_file))
  end

end

Private Instance Methods

paths_to_exclude() click to toggle source
# File lib/backup/remote_data.rb, line 211
def paths_to_exclude
  options[:excludes].map {|path|
    "--exclude='#{ prepare_path(path) }'"
  }.join(' ')
end
paths_to_package() click to toggle source
# File lib/backup/remote_data.rb, line 195
def paths_to_package
  options[:paths].map {|path| prepare_path(path) }
end
prepare_path(path) click to toggle source
# File lib/backup/remote_data.rb, line 217
def prepare_path(path)
  options[:root] ? path : File.expand_path(path)
end
tar_command() click to toggle source
# File lib/backup/remote_data.rb, line 186
def tar_command
  tar = utility(:tar)
  options[:sudo] ? "#{ utility(:sudo) } -n #{ tar }" : tar
end
tar_options() click to toggle source
# File lib/backup/remote_data.rb, line 221
def tar_options
  args = options[:tar_options]
  gnu_tar? ? "--ignore-failed-read #{ args }".strip : args
end
tar_root() click to toggle source
# File lib/backup/remote_data.rb, line 191
def tar_root
  options[:root] ? " -C '#{ File.expand_path(options[:root]) }'" : ''
end
tar_success_codes() click to toggle source
# File lib/backup/remote_data.rb, line 226
def tar_success_codes
  gnu_tar? ? [0, 1] : [0]
end
with_files_from(paths) { |"#{ path }"| ... } click to toggle source
# File lib/backup/remote_data.rb, line 199
def with_files_from(paths)
  tmpfile = Tempfile.new('backup-archive-paths')
  paths.each {|path| tmpfile.puts path }
  tmpfile.close

  #yield "-T '#{ tmpfile.path }'"
  yield "#{ tmpfile.path }"
ensure

  tmpfile.delete
end