diff --git a/backup.gemspec b/backup.gemspec index 467ee188d..2f29c6ac9 100644 --- a/backup.gemspec +++ b/backup.gemspec @@ -1,9 +1,11 @@ +require 'date' + Gem::Specification.new do |gem| ## # Gem Specifications gem.name = 'backup' - gem.version = '2.3.2.pre2' + gem.version = '2.3.2.pre3' gem.date = Date.today.to_s gem.summary = 'Backup is a Ruby Gem that simplifies making backups for databases, files and folders.' gem.description = 'Backup is a Ruby Gem written for Unix and Rails environments. It can be used both with and without the @@ -33,7 +35,7 @@ Gem::Specification.new do |gem| ## # Dependencies - gem.add_dependency('s3', [">= 0.3.0"]) + gem.add_dependency('s3', [">= 0.3.0"]) gem.add_dependency('net-ssh', [">= 2.0.15"]) gem.add_dependency('net-scp', [">= 1.0.2"]) gem.add_dependency('net-sftp', [">= 2.0.4"]) @@ -41,4 +43,5 @@ Gem::Specification.new do |gem| gem.add_dependency('sqlite3-ruby', ["= 1.2.5"]) gem.add_dependency('hirb', [">= 0.2.9"]) gem.add_dependency('pony', [">= 0.5"]) -end \ No newline at end of file + gem.add_dependency('cloudfiles', [">= 1.4.7"]) +end diff --git a/bin/backup b/bin/backup index 03f9f6e08..45ddad258 100644 --- a/bin/backup +++ b/bin/backup @@ -23,13 +23,14 @@ optparse = OptionParser.new do |opts| backup = Backup::Setup.new(trigger, @backup_procedures) records = Array.new case backup.procedure.storage_name.to_sym - when :s3 then records = Backup::Record::S3.all :conditions => {:trigger => trigger} - when :scp then records = Backup::Record::SCP.all :conditions => {:trigger => trigger} - when :ftp then records = Backup::Record::FTP.all :conditions => {:trigger => trigger} - when :sftp then records = Backup::Record::SFTP.all :conditions => {:trigger => trigger} - when :local then records = Backup::Record::Local.all :conditions => {:trigger => trigger} + when :cloudfiles then records = Backup::Record::CloudFiles.all :conditions => {:trigger => trigger} + when :s3 then records = Backup::Record::S3.all :conditions => {:trigger => trigger} + when :scp then records = Backup::Record::SCP.all :conditions => {:trigger => trigger} + when :ftp then records = Backup::Record::FTP.all :conditions => {:trigger => trigger} + when :sftp then records = Backup::Record::SFTP.all :conditions => {:trigger => trigger} + when :local then records = Backup::Record::Local.all :conditions => {:trigger => trigger} end - + if options[:table] puts Hirb::Helpers::AutoTable.render(records) else @@ -49,11 +50,12 @@ optparse = OptionParser.new do |opts| puts "Destroying backup records with trigger: #{trigger}." backup = Backup::Setup.new(trigger, @backup_procedures) case backup.procedure.storage_name.to_sym - when :s3 then Backup::Record::S3.destroy_all_backups backup.procedure, trigger - when :scp then Backup::Record::SCP.destroy_all_backups backup.procedure, trigger - when :ftp then Backup::Record::FTP.destroy_all_backups backup.procedure, trigger - when :sftp then Backup::Record::SFTP.destroy_all_backups backup.procedure, trigger - when :local then Backup::Record::Local.destroy_all_backups backup.procedure, trigger + when :cloudfiles then Backup::Record::CloudFiles.destroy_all_backups backup.procedure, trigger + when :s3 then Backup::Record::S3.destroy_all_backups backup.procedure, trigger + when :scp then Backup::Record::SCP.destroy_all_backups backup.procedure, trigger + when :ftp then Backup::Record::FTP.destroy_all_backups backup.procedure, trigger + when :sftp then Backup::Record::SFTP.destroy_all_backups backup.procedure, trigger + when :local then Backup::Record::Local.destroy_all_backups backup.procedure, trigger end end @@ -68,11 +70,12 @@ optparse = OptionParser.new do |opts| backup = Backup::Setup.new(false, @backup_procedures) backup.procedures.each do |backup_procedure| case backup_procedure.storage_name.to_sym - when :s3 then Backup::Record::S3.destroy_all_backups backup_procedure, backup_procedure.trigger - when :scp then Backup::Record::SCP.destroy_all_backups backup_procedure, backup_procedure.trigger - when :ftp then Backup::Record::FTP.destroy_all_backups backup_procedure, backup_procedure.trigger - when :sftp then Backup::Record::SFTP.destroy_all_backups backup_procedure, backup_procedure.trigger - when :local then Backup::Record::Local.destroy_all_backups backup.procedure, backup_procedure.trigger + when :cloudfiles then Backup::Record::CloudFiles.destroy_all_backups backup_procedure, backup_procedure.trigger + when :s3 then Backup::Record::S3.destroy_all_backups backup_procedure, backup_procedure.trigger + when :scp then Backup::Record::SCP.destroy_all_backups backup_procedure, backup_procedure.trigger + when :ftp then Backup::Record::FTP.destroy_all_backups backup_procedure, backup_procedure.trigger + when :sftp then Backup::Record::SFTP.destroy_all_backups backup_procedure, backup_procedure.trigger + when :local then Backup::Record::Local.destroy_all_backups backup.procedure, backup_procedure.trigger end end end diff --git a/lib/backup.rb b/lib/backup.rb index aafc12f6f..9a8d75762 100644 --- a/lib/backup.rb +++ b/lib/backup.rb @@ -51,20 +51,22 @@ module Adapters end module Storage - autoload :S3, 'backup/storage/s3' - autoload :SCP, 'backup/storage/scp' - autoload :FTP, 'backup/storage/ftp' - autoload :SFTP, 'backup/storage/sftp' - autoload :Local, 'backup/storage/local' + autoload :CloudFiles, 'backup/storage/cloudfiles' + autoload :S3, 'backup/storage/s3' + autoload :SCP, 'backup/storage/scp' + autoload :FTP, 'backup/storage/ftp' + autoload :SFTP, 'backup/storage/sftp' + autoload :Local, 'backup/storage/local' end module Record - autoload :Base, 'backup/record/base' - autoload :S3, 'backup/record/s3' - autoload :SCP, 'backup/record/scp' - autoload :FTP, 'backup/record/ftp' - autoload :SFTP, 'backup/record/sftp' - autoload :Local, 'backup/record/local' + autoload :Base, 'backup/record/base' + autoload :CloudFiles, 'backup/record/cloudfiles' + autoload :S3, 'backup/record/s3' + autoload :SCP, 'backup/record/scp' + autoload :FTP, 'backup/record/ftp' + autoload :SFTP, 'backup/record/sftp' + autoload :Local, 'backup/record/local' end class Setup diff --git a/lib/backup/configuration/base.rb b/lib/backup/configuration/base.rb index cc8ad1291..29ba80f11 100644 --- a/lib/backup/configuration/base.rb +++ b/lib/backup/configuration/base.rb @@ -25,21 +25,23 @@ def storage(storage, &block) # Initializes the storing process depending on the store settings def initialize_storage(adapter) case @storage_name.to_sym - when :s3 then Backup::Storage::S3.new(adapter) - when :scp then Backup::Storage::SCP.new(adapter) - when :ftp then Backup::Storage::FTP.new(adapter) - when :sftp then Backup::Storage::SFTP.new(adapter) - when :local then Backup::Storage::Local.new(adapter) + when :cloudfiles then Backup::Storage::CloudFiles.new(adapter) + when :s3 then Backup::Storage::S3.new(adapter) + when :scp then Backup::Storage::SCP.new(adapter) + when :ftp then Backup::Storage::FTP.new(adapter) + when :sftp then Backup::Storage::SFTP.new(adapter) + when :local then Backup::Storage::Local.new(adapter) end end def initialize_record case @storage_name.to_sym - when :s3 then Backup::Record::S3.new - when :scp then Backup::Record::SCP.new - when :ftp then Backup::Record::FTP.new - when :sftp then Backup::Record::SFTP.new - when :local then Backup::Record::Local.new + when :cloudfiles then Backup::Record::CloudFiles.new + when :s3 then Backup::Record::S3.new + when :scp then Backup::Record::SCP.new + when :ftp then Backup::Record::FTP.new + when :sftp then Backup::Record::SFTP.new + when :local then Backup::Record::Local.new end end diff --git a/lib/backup/configuration/storage.rb b/lib/backup/configuration/storage.rb index adde77efa..f1c1f8be1 100644 --- a/lib/backup/configuration/storage.rb +++ b/lib/backup/configuration/storage.rb @@ -2,7 +2,7 @@ module Backup module Configuration class Storage extend Backup::Configuration::Attributes - generate_attributes %w(ip user password path access_key_id secret_access_key use_ssl bucket) + generate_attributes %w(ip user password path access_key_id secret_access_key use_ssl bucket username api_key container) end end end diff --git a/lib/backup/connection/cloudfiles.rb b/lib/backup/connection/cloudfiles.rb new file mode 100644 index 000000000..8f1afc9e0 --- /dev/null +++ b/lib/backup/connection/cloudfiles.rb @@ -0,0 +1,75 @@ +require 'cloudfiles' + +module Backup + module Connection + class CloudFiles + + attr_accessor :adapter, :procedure, :api_key, :username, :cf_container, :final_file, :tmp_path + + # Initializes the Cloud Files connection, setting the values using the + # Cloud Files adapter + def initialize(adapter = false) + if adapter + self.adapter = adapter + self.procedure = adapter.procedure + self.final_file = adapter.final_file + self.tmp_path = adapter.tmp_path.gsub('\ ', ' ') + load_storage_configuration_attributes + end + end + + # Sets values from a procedure, rather than from the adapter object + def static_initialize(procedure) + self.procedure = procedure + load_storage_configuration_attributes(true) + end + + # Establishes a connection with Rackspace Cloud Files using the + # credentials provided by the user + def connect + connection + end + + # Wrapper for the Connection object + def connection + ::CloudFiles::Connection.new(username, api_key) + end + + # Wrapper for the Container object + def container + connection.container(cf_container) + end + + # Initializes the file transfer to Rackspace Cloud Files + # This can only run after a connection has been made using the #connect method + def store + object = container.create_object(final_file) + object.write(open(File.join(tmp_path, final_file))) + end + + # Destroys file from a bucket on Amazon S3 + def destroy(file, c) + c = connection.container(c) + c.delete_object(file) + end + + private + + def load_storage_configuration_attributes(static = false) + %w(api_key username).each do |attribute| + if static + send("#{attribute}=", procedure.get_storage_configuration.attributes[attribute]) + else + send("#{attribute}=", adapter.procedure.get_storage_configuration.attributes[attribute]) + end + end + + if static + self.cf_container = procedure.get_storage_configuration.attributes['container'] + else + self.cf_container = adapter.procedure.get_storage_configuration.attributes['container'] + end + end + end + end +end diff --git a/lib/backup/record/cloudfiles.rb b/lib/backup/record/cloudfiles.rb new file mode 100644 index 000000000..f26f6d514 --- /dev/null +++ b/lib/backup/record/cloudfiles.rb @@ -0,0 +1,28 @@ +require 'backup/connection/cloudfiles' + +module Backup + module Record + class CloudFiles < Backup::Record::Base + + alias_attribute :container, :bucket + + def load_specific_settings(adapter) + self.container = adapter.procedure.get_storage_configuration.attributes['container'] + end + + private + + def self.destroy_backups(procedure, backups) + cf = Backup::Connection::CloudFiles.new + cf.static_initialize(procedure) + cf.connect + backups.each do |backup| + puts "\nDestroying backup \"#{backup.filename}\" from container \"#{backup.container}\"." + cf.destroy(backup.filename, backup.container) + backup.destroy + end + end + + end + end +end diff --git a/lib/backup/storage/cloudfiles.rb b/lib/backup/storage/cloudfiles.rb new file mode 100644 index 000000000..cad9edb3f --- /dev/null +++ b/lib/backup/storage/cloudfiles.rb @@ -0,0 +1,16 @@ +require 'backup/connection/cloudfiles' + +module Backup + module Storage + class CloudFiles + + # Stores the backup file on the remote server using Rackspace Cloud Files + def initialize(adapter) + cf = Backup::Connection::CloudFiles.new(adapter) + cf.connect + cf.store + end + + end + end +end