Class: S3TarBackup::Backup
- Inherits:
-
Object
- Object
- S3TarBackup::Backup
- Defined in:
- lib/s3_tar_backup/backup.rb
Constant Summary collapse
- COMPRESSIONS =
{ :none => {:flag => '', :ext => 'tar'}, :gzip => {:flag => '-z', :ext => 'tar.gz'}, :bzip2 => {:flag => '-j', :ext => 'tar.bz2'}, :lzma => {:flag => '--lzma', :ext => 'tar.lzma'}, :lzma2 => {:flag => '-J', :ext => 'tar.xz'} }
- ENCRYPTED_EXTENSIONS =
{ :gpg_key => 'asc', :password_file => 'gpg' }
- PASSPHRASE_CIPHER_ALGO =
'AES256'
Class Method Summary collapse
- .parse_object(object, profile) ⇒ Object
-
.restore_cmd(restore_into, restore_from, verbose = false, password_file = nil) ⇒ Object
No real point in creating a whole new class for this one.
Instance Method Summary collapse
- #archive ⇒ Object
- #backup_cmd(verbose = false) ⇒ Object
-
#initialize(backup_dir, name, sources, exclude, compression = :bzip2, encryption = nil) ⇒ Backup
constructor
A new instance of Backup.
- #snar ⇒ Object
- #snar_exists? ⇒ Boolean
- #snar_path ⇒ Object
- #tmp_snar_path ⇒ Object
Constructor Details
#initialize(backup_dir, name, sources, exclude, compression = :bzip2, encryption = nil) ⇒ Backup
Returns a new instance of Backup.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/s3_tar_backup/backup.rb', line 28 def initialize(backup_dir, name, sources, exclude, compression=:bzip2, encryption=nil) @backup_dir, @name = backup_dir, name raise "Unknown compression #{compression}. Valid options are #{COMPRESSIONS.keys.join(', ')}" unless COMPRESSIONS.has_key?(compression) @compression_flag = COMPRESSIONS[compression][:flag] @compression_ext = COMPRESSIONS[compression][:ext] @time = Time.now @encryption = encryption @sources = [*sources].map{ |x| x.gsub('\\', '/') } @exclude = [*exclude].map{ |x| x.gsub('\\', '/') } # If the backup dir is inside any of the sources, exclude it absolute_backup_dir = File.absolute_path(backup_dir) # I cannot for the life of me get tar to accept absolute paths to directories. Passing a path relative to the CWD seems to work though @exclude.push(*@sources.select{ |x| absolute_backup_dir.start_with?(File.absolute_path(x)) }.map{ |x| Pathname.new(absolute_backup_dir).relative_path_from(Pathname.new(Dir.pwd)).to_s }) FileUtils.mkdir_p(@backup_dir) unless File.directory?(@backup_dir) end |
Class Method Details
.parse_object(object, profile) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/s3_tar_backup/backup.rb', line 84 def self.parse_object(object, profile) name = File.basename(object.path) match = name.match(/^backup-([\w\-]+)-(\d\d\d\d)(\d\d)(\d\d)_(\d\d)(\d\d)(\d\d)-(\w+)\.(.*?)(?:\.(#{ENCRYPTED_EXTENSIONS.values.join('|')}))?$/) return nil unless match && match[1] == profile return { :type => match[8].to_sym, :date => Time.new(match[2].to_i, match[3].to_i, match[4].to_i, match[5].to_i, match[6].to_i, match[7].to_i), :name => name, :ext => match[9], :size => object.size, :profile => match[1], :compression => COMPRESSIONS.find{ |k,v| v[:ext] == match[9] }[0], :encryption => match[10].nil? ? nil : ENCRYPTED_EXTENSIONS.key(match[10]) } end |
.restore_cmd(restore_into, restore_from, verbose = false, password_file = nil) ⇒ Object
No real point in creating a whole new class for this one
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/s3_tar_backup/backup.rb', line 102 def self.restore_cmd(restore_into, restore_from, verbose=false, password_file=nil) ext, encryption_ext = restore_from.match(/[^\.\\\/]+\.(.*?)(?:\.(#{ENCRYPTED_EXTENSIONS.values.join('|')}))?$/)[1..2] encryption = ENCRYPTED_EXTENSIONS.key(encryption_ext) compression_flag = COMPRESSIONS.find{ |k,v| v[:ext] == ext }[1][:flag] tar_archive = encryption ? '' : "f \"#{restore_from}\"" gpg_cmd = encryption.nil? ? '' : case encryption when :gpg_key "gpg --yes -d \"#{restore_from}\" | " when :password_file flag = password_file && !password_file.empty? ? " --passphrase-file \"#{password_file}\"" : '' "gpg --yes#{flag} -d \"#{restore_from}\" | " end "#{gpg_cmd}tar xp#{verbose ? 'v' : ''}#{tar_archive} #{compression_flag} -G -C #{restore_into}" end |
Instance Method Details
#archive ⇒ Object
63 64 65 66 67 68 |
# File 'lib/s3_tar_backup/backup.rb', line 63 def archive return @archive if @archive type = snar_exists? ? 'incr' : 'full' encrypted_bit = @encryption ? ".#{ENCRYPTED_EXTENSIONS[@encryption[:type]]}" : '' File.join(@backup_dir, "backup-#{@name}-#{@time.strftime('%Y%m%d_%H%M%S')}-#{type}.#{@compression_ext}#{encrypted_bit}") end |
#backup_cmd(verbose = false) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/s3_tar_backup/backup.rb', line 70 def backup_cmd(verbose=false) exclude = @exclude.map{ |e| " --exclude \"#{e}\""}.join sources = @sources.map{ |s| "\"#{s}\""}.join(' ') @archive = archive tar_archive = @encryption ? '' : "f \"#{@archive}\"" gpg_cmd = @encryption.nil? ? '' : case @encryption[:type] when :gpg_key " | gpg -r #{@encryption[:gpg_key]} -o \"#{@archive}\" --always-trust --yes --batch --no-tty -e" when :password_file " | gpg -c --passphrase-file \"#{@encryption[:password_file]}\" --cipher-algo #{PASSPHRASE_CIPHER_ALGO} -o \"#{@archive}\" --batch --yes --no-tty" end "tar c#{verbose ? 'v' : ''}#{tar_archive} #{@compression_flag} -g \"#{tmp_snar_path}\"#{exclude} --no-check-device #{sources}#{gpg_cmd}" end |
#snar ⇒ Object
47 48 49 |
# File 'lib/s3_tar_backup/backup.rb', line 47 def snar "backup-#{@name}.snar" end |
#snar_exists? ⇒ Boolean
59 60 61 |
# File 'lib/s3_tar_backup/backup.rb', line 59 def snar_exists? File.exists?(snar_path) end |
#snar_path ⇒ Object
51 52 53 |
# File 'lib/s3_tar_backup/backup.rb', line 51 def snar_path File.join(@backup_dir, snar) end |
#tmp_snar_path ⇒ Object
55 56 57 |
# File 'lib/s3_tar_backup/backup.rb', line 55 def tmp_snar_path snar_path + '.tmp' end |