class Backup::Archive

Attributes

name[R]
options[R]

Public Class Methods

new(model, name, &block) click to toggle source

Adds a new Archive to a Backup Model.

Backup::Model.new(:my_backup, 'My Backup') do
  archive :my_archive do |archive|
    archive.add 'path/to/archive'
    archive.add '/another/path/to/archive'
    archive.exclude 'path/to/exclude'
    archive.exclude '/another/path/to/exclude'
  end
end

All paths added using ‘add` or `exclude` will be expanded to their full paths from the root of the filesystem. Files will be added to the tar archive using these full paths, and their leading `/` will be preserved (using tar’s ‘-P` option).

/path/to/pwd/path/to/archive/...
/another/path/to/archive/...

When a ‘root` path is given, paths to add/exclude are taken as relative to the `root` path, unless given as absolute paths.

Backup::Model.new(:my_backup, 'My Backup') do
  archive :my_archive do |archive|
    archive.root '~/my_data'
    archive.add 'path/to/archive'
    archive.add '/another/path/to/archive'
    archive.exclude 'path/to/exclude'
    archive.exclude '/another/path/to/exclude'
  end
end

This directs ‘tar` to change directories to the `root` path to create the archive. Unless paths were given as absolute, the paths within the archive will be relative to the `root` path.

path/to/archive/...
/another/path/to/archive/...

For absolute paths added to this archive, the leading ‘/` will be preserved. Take note that when archives are extracted, leading `/` are stripped by default, so care must be taken when extracting archives with mixed relative/absolute paths.

# File lib/backup/archive.rb, line 54
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)
end

Public Instance Methods

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

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

  pipeline = Pipeline.new
  with_files_from(paths_to_package) do |files_from|
    pipeline.add(
      "#{ tar_command } #{ tar_options } -cPf -#{ tar_root } " +
      "#{ paths_to_exclude } #{ files_from }",
      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 }") }'"
    pipeline.run
  end

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

Private Instance Methods

paths_to_exclude() click to toggle source
# File lib/backup/archive.rb, line 124
def paths_to_exclude
  options[:excludes].map {|path|
    "--exclude='#{ prepare_path(path) }'"
  }.join(' ')
end
paths_to_package() click to toggle source
# File lib/backup/archive.rb, line 111
def paths_to_package
  options[:paths].map {|path| prepare_path(path) }
end
prepare_path(path) click to toggle source
# File lib/backup/archive.rb, line 130
def prepare_path(path)
  options[:root] ? path : File.expand_path(path)
end
tar_command() click to toggle source
# File lib/backup/archive.rb, line 102
def tar_command
  tar = utility(:tar)
  options[:sudo] ? "#{ utility(:sudo) } -n #{ tar }" : tar
end
tar_options() click to toggle source
# File lib/backup/archive.rb, line 134
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/archive.rb, line 107
def tar_root
  options[:root] ? " -C '#{ File.expand_path(options[:root]) }'" : ''
end
tar_success_codes() click to toggle source
# File lib/backup/archive.rb, line 139
def tar_success_codes
  gnu_tar? ? [0, 1] : [0]
end
with_files_from(paths) { |"-T '#{ path }'"| ... } click to toggle source
# File lib/backup/archive.rb, line 115
def with_files_from(paths)
  tmpfile = Tempfile.new('backup-archive-paths')
  paths.each {|path| tmpfile.puts path }
  tmpfile.close
  yield "-T '#{ tmpfile.path }'"
ensure
  tmpfile.delete
end