class Backup::Archive
Attributes
Public Class Methods
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 52 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
# File lib/backup/archive.rb, line 65 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" if @model.compressor @model.compressor.compress_with do |command, ext| pipeline << command extension << ext end end 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
# File lib/backup/archive.rb, line 124 def paths_to_exclude options[:excludes].map do |path| "--exclude='#{prepare_path(path)}'" end.join(" ") end
# File lib/backup/archive.rb, line 111 def paths_to_package options[:paths].map { |path| prepare_path(path) } end
# File lib/backup/archive.rb, line 130 def prepare_path(path) options[:root] ? path : File.expand_path(path) end
# File lib/backup/archive.rb, line 102 def tar_command tar = utility(:tar) options[:sudo] ? "#{utility(:sudo)} -n #{tar}" : tar end
# File lib/backup/archive.rb, line 134 def tar_options args = options[:tar_options] gnu_tar? ? "--ignore-failed-read #{args}".strip : args end
# File lib/backup/archive.rb, line 107 def tar_root options[:root] ? " -C '#{File.expand_path(options[:root])}'" : "" end
# File lib/backup/archive.rb, line 139 def tar_success_codes gnu_tar? ? [0, 1] : [0] end
# 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