module EY module Backup class BackupSet < Struct.new(:name, :keys) include EY::Backup::Logging extend EY::Backup::Logging attr_accessor :files MULTIPART_EXTENSION = /\.part\d+/ def self.parse(objects) objects.map {|o| new(o[:name], o[:keys]) } end def self.from(database, file) backup = new(File.basename(file), []) backup.files = [file] backup end def self.cleanup(database, keep) say "Cleanup for #{database}" backups_for(database)[0...(-keep)].each do |backup| say "deleting: #{backup.name}" backup.delete! end end def self.list_all list('all', backups) end def self.backups EY::Backup.config.databases.map {|db| backups_for(db) }.flatten end def self.list(database, backups = backups_for(database)) info "Listing database backups for #{database}" info "#{backups.size} backup(s) found" backups.each_with_index do |db, i| info "#{i}:#{database} #{db.normalized_name}" end backups end def self.backups_for(database_name) s3_objects = EY::Backup.bucket_minder.list(:prefix => "#{EY::Backup.config.environment}.#{database_name}", :print => false) parse(s3_objects).sort end def self.upload(database, file) EY::Backup.bucket_minder.name = "#{EY::Backup.config.environment}.#{database}/#{File.basename(file)}" EY::Backup.bucket_minder.upload_object(file, false) end def self.download(database, index) fatal "You didn't specify a database name: e.g. 1:rails_production" if database.empty? || index.empty? backup = backups_for(database)[index.to_i] fatal "No backup found for database #{database}: requested index: #{index}" unless backup backup.download! backup end def initialize(*) super @files = [] end def parts [keys.size, files.size].max end def normalized_name normalize(name) end def upload!(database) files.each do |file| EY::Backup.bucket_minder.name = "#{EY::Backup.config.environment}.#{database}/#{File.basename(file)}" EY::Backup.bucket_minder.upload_object(file, false) info "successful upload: #{file}" end end def download! keys.each do |key| info "Downloading #{key}" filename = File.join(EY::Backup.base_path, normalize(key)) File.open(filename, 'wb') do |f| EY::Backup.bucket_minder.stream(key) do |chunk| f << chunk end end files << filename end end def delete! keys.each do |key| EY::Backup.bucket_minder.remove_object(key) end end def rm! files.each do |file| FileUtils.rm(file) end end def normalize(o) o.gsub(/^.*?\//, '') end def <=>(o) self.name <=> o.name end end end end