namxam-backup 2.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. data/CHANGELOG +131 -0
  2. data/LICENSE +20 -0
  3. data/README.md +122 -0
  4. data/bin/backup +108 -0
  5. data/generators/backup/backup_generator.rb +69 -0
  6. data/generators/backup/templates/backup.rake +56 -0
  7. data/generators/backup/templates/backup.rb +253 -0
  8. data/generators/backup/templates/create_backup_tables.rb +18 -0
  9. data/generators/backup_update/backup_update_generator.rb +50 -0
  10. data/generators/backup_update/templates/migrations/update_backup_tables.rb +27 -0
  11. data/lib/backup.rb +132 -0
  12. data/lib/backup/adapters/archive.rb +34 -0
  13. data/lib/backup/adapters/base.rb +167 -0
  14. data/lib/backup/adapters/custom.rb +41 -0
  15. data/lib/backup/adapters/mongo_db.rb +139 -0
  16. data/lib/backup/adapters/mysql.rb +60 -0
  17. data/lib/backup/adapters/postgresql.rb +56 -0
  18. data/lib/backup/adapters/sqlite.rb +25 -0
  19. data/lib/backup/command_helper.rb +14 -0
  20. data/lib/backup/configuration/adapter.rb +21 -0
  21. data/lib/backup/configuration/adapter_options.rb +8 -0
  22. data/lib/backup/configuration/attributes.rb +19 -0
  23. data/lib/backup/configuration/base.rb +75 -0
  24. data/lib/backup/configuration/helpers.rb +24 -0
  25. data/lib/backup/configuration/mail.rb +20 -0
  26. data/lib/backup/configuration/smtp.rb +8 -0
  27. data/lib/backup/configuration/storage.rb +8 -0
  28. data/lib/backup/connection/cloudfiles.rb +75 -0
  29. data/lib/backup/connection/dropbox.rb +62 -0
  30. data/lib/backup/connection/s3.rb +88 -0
  31. data/lib/backup/core_ext/object.rb +5 -0
  32. data/lib/backup/environment/base.rb +12 -0
  33. data/lib/backup/environment/rails_configuration.rb +15 -0
  34. data/lib/backup/environment/unix_configuration.rb +109 -0
  35. data/lib/backup/mail/base.rb +97 -0
  36. data/lib/backup/mail/mail.txt +7 -0
  37. data/lib/backup/record/base.rb +65 -0
  38. data/lib/backup/record/cloudfiles.rb +28 -0
  39. data/lib/backup/record/dropbox.rb +27 -0
  40. data/lib/backup/record/ftp.rb +39 -0
  41. data/lib/backup/record/local.rb +26 -0
  42. data/lib/backup/record/s3.rb +25 -0
  43. data/lib/backup/record/scp.rb +33 -0
  44. data/lib/backup/record/sftp.rb +38 -0
  45. data/lib/backup/storage/base.rb +10 -0
  46. data/lib/backup/storage/cloudfiles.rb +16 -0
  47. data/lib/backup/storage/dropbox.rb +12 -0
  48. data/lib/backup/storage/ftp.rb +38 -0
  49. data/lib/backup/storage/local.rb +22 -0
  50. data/lib/backup/storage/s3.rb +15 -0
  51. data/lib/backup/storage/scp.rb +30 -0
  52. data/lib/backup/storage/sftp.rb +31 -0
  53. data/lib/backup/version.rb +3 -0
  54. data/lib/generators/backup/USAGE +10 -0
  55. data/lib/generators/backup/backup_generator.rb +47 -0
  56. data/lib/generators/backup/templates/backup.rake +56 -0
  57. data/lib/generators/backup/templates/backup.rb +236 -0
  58. data/lib/generators/backup/templates/create_backup_tables.rb +18 -0
  59. data/setup/backup.rb +255 -0
  60. data/setup/backup.sqlite3 +0 -0
  61. metadata +278 -0
@@ -0,0 +1,25 @@
1
+ module Backup
2
+ module Adapters
3
+ class SQLite < Base
4
+
5
+ attr_accessor :database
6
+
7
+ private
8
+
9
+ # Compress the sqlite file
10
+ def perform
11
+ log system_messages[:sqlite]
12
+ run "gzip -c --best #{database} > #{File.join(tmp_path, compressed_file)}"
13
+ end
14
+
15
+ def load_settings
16
+ self.database = procedure.get_adapter_configuration.attributes['database']
17
+ end
18
+
19
+ def performed_file_extension
20
+ ""
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ module Backup
2
+ module CommandHelper
3
+ def run(command, opts={})
4
+ opts[:exit_on_failure] ||= false
5
+ output = `#{command}`
6
+ exit 1 if opts[:exit_on_failure] && !$?.success?
7
+ output
8
+ end
9
+
10
+ def log(command)
11
+ puts "Backup (#{Time.now.strftime("%Y-%m-%d %H:%M:%S %Z")}) => #{command}"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ module Backup
2
+ module Configuration
3
+ class Adapter
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(files exclude user password database tables skip_tables commands additional_options backup_method)
6
+
7
+ def initialize
8
+ @options = Backup::Configuration::AdapterOptions.new
9
+ end
10
+
11
+ def options(&block)
12
+ @options.instance_eval &block
13
+ end
14
+
15
+ def get_options
16
+ @options
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ module Backup
2
+ module Configuration
3
+ class AdapterOptions
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(host port socket)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module Backup
2
+ module Configuration
3
+ module Attributes
4
+
5
+ def generate_attributes(*attrs)
6
+ define_method :attributes do
7
+ @attributes ||= {}
8
+ end
9
+
10
+ attrs.flatten.each do |att|
11
+ define_method att do |value|
12
+ self.attributes[att.to_s] = value
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,75 @@
1
+ module Backup
2
+ module Configuration
3
+ class Base
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(encrypt_with_password encrypt_with_gpg_public_key keep_backups notify)
6
+
7
+ attr_accessor :trigger, :storage_name, :adapter_name, :before_backup_block, :after_backup_block
8
+
9
+ def initialize(trigger)
10
+ @trigger = trigger
11
+ @adapter_configuration = Backup::Configuration::Adapter.new
12
+ @storage_configuration = Backup::Configuration::Storage.new
13
+ end
14
+
15
+ def adapter(adapter, &block)
16
+ @adapter_name = adapter
17
+ @adapter_configuration.instance_eval &block
18
+ end
19
+
20
+ def storage(storage, &block)
21
+ @storage_name = storage
22
+ @storage_configuration.instance_eval &block
23
+ end
24
+
25
+ def before_backup(&block)
26
+ @before_backup_block = block
27
+ end
28
+
29
+ def after_backup(&block)
30
+ @after_backup_block = block
31
+ end
32
+
33
+ def storage_class
34
+ case @storage_name.to_sym
35
+ when :cloudfiles then Backup::Storage::CloudFiles
36
+ when :s3 then Backup::Storage::S3
37
+ when :scp then Backup::Storage::SCP
38
+ when :ftp then Backup::Storage::FTP
39
+ when :sftp then Backup::Storage::SFTP
40
+ when :local then Backup::Storage::Local
41
+ when :dropbox then Backup::Storage::Dropbox
42
+ end
43
+ end
44
+
45
+ def record_class
46
+ case @storage_name.to_sym
47
+ when :cloudfiles then Backup::Record::CloudFiles
48
+ when :s3 then Backup::Record::S3
49
+ when :scp then Backup::Record::SCP
50
+ when :ftp then Backup::Record::FTP
51
+ when :sftp then Backup::Record::SFTP
52
+ when :local then Backup::Record::Local
53
+ when :dropbox then Backup::Record::Dropbox
54
+ end
55
+ end
56
+
57
+ # Initializes the storing process depending on the store settings
58
+ def initialize_storage(adapter)
59
+ storage_class.new(adapter)
60
+ end
61
+
62
+ def initialize_record
63
+ record_class.new
64
+ end
65
+
66
+ def get_adapter_configuration
67
+ @adapter_configuration
68
+ end
69
+
70
+ def get_storage_configuration
71
+ @storage_configuration
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,24 @@
1
+ module Backup
2
+ module Configuration
3
+ module Helpers
4
+
5
+ # A helper method for the config/backup.rb configuration file
6
+ # Expects a trigger in argument one (STRING)
7
+ # Expects a block of settings
8
+ def backup(trigger, &block)
9
+ backup = Backup::Configuration::Base.new(trigger)
10
+ backup.instance_eval &block
11
+ @backup_procedures ||= Array.new
12
+ @backup_procedures << backup
13
+ end
14
+
15
+ # A helper method for the config/mail.rb configuration file
16
+ # Takes a block containing the mail options
17
+ def notifier_settings(&block)
18
+ @mail_configuration = Backup::Configuration::Mail.new
19
+ @mail_configuration.instance_eval &block
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module Backup
2
+ module Configuration
3
+ class Mail
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(from to smtp)
6
+
7
+ def initialize
8
+ @smtp_configuration = Backup::Configuration::SMTP.new
9
+ end
10
+
11
+ def smtp(&block)
12
+ @smtp_configuration.instance_eval &block
13
+ end
14
+
15
+ def get_smtp_configuration
16
+ @smtp_configuration
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ module Backup
2
+ module Configuration
3
+ class SMTP
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(host port username password authentication domain tls)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Backup
2
+ module Configuration
3
+ class Storage
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(ip user password path access_key_id secret_access_key host use_ssl bucket username api_key container)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,75 @@
1
+ require 'cloudfiles'
2
+
3
+ module Backup
4
+ module Connection
5
+ class CloudFiles
6
+
7
+ attr_accessor :adapter, :procedure, :api_key, :username, :cf_container, :final_file, :tmp_path
8
+
9
+ # Initializes the Cloud Files connection, setting the values using the
10
+ # Cloud Files adapter
11
+ def initialize(adapter = false)
12
+ if adapter
13
+ self.adapter = adapter
14
+ self.procedure = adapter.procedure
15
+ self.final_file = adapter.final_file
16
+ self.tmp_path = adapter.tmp_path.gsub('\ ', ' ')
17
+ load_storage_configuration_attributes
18
+ end
19
+ end
20
+
21
+ # Sets values from a procedure, rather than from the adapter object
22
+ def static_initialize(procedure)
23
+ self.procedure = procedure
24
+ load_storage_configuration_attributes(true)
25
+ end
26
+
27
+ # Establishes a connection with Rackspace Cloud Files using the
28
+ # credentials provided by the user
29
+ def connect
30
+ connection
31
+ end
32
+
33
+ # Wrapper for the Connection object
34
+ def connection
35
+ ::CloudFiles::Connection.new(username, api_key)
36
+ end
37
+
38
+ # Wrapper for the Container object
39
+ def container
40
+ connection.container(cf_container)
41
+ end
42
+
43
+ # Initializes the file transfer to Rackspace Cloud Files
44
+ # This can only run after a connection has been made using the #connect method
45
+ def store
46
+ object = container.create_object(final_file)
47
+ object.write(open(File.join(tmp_path, final_file)))
48
+ end
49
+
50
+ # Destroys file from a bucket on Amazon S3
51
+ def destroy(file, c)
52
+ c = connection.container(c)
53
+ c.delete_object(file)
54
+ end
55
+
56
+ private
57
+
58
+ def load_storage_configuration_attributes(static = false)
59
+ %w(api_key username).each do |attribute|
60
+ if static
61
+ send("#{attribute}=", procedure.get_storage_configuration.attributes[attribute])
62
+ else
63
+ send("#{attribute}=", adapter.procedure.get_storage_configuration.attributes[attribute])
64
+ end
65
+ end
66
+
67
+ if static
68
+ self.cf_container = procedure.get_storage_configuration.attributes['container']
69
+ else
70
+ self.cf_container = adapter.procedure.get_storage_configuration.attributes['container']
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,62 @@
1
+ require 'dropbox'
2
+
3
+ module Backup
4
+ module Connection
5
+ class Dropbox
6
+
7
+ attr_accessor :adapter, :procedure, :final_file, :tmp_path, :api_key, :secret_access_key, :username, :password, :path
8
+
9
+ def initialize(adapter=false)
10
+ if adapter
11
+ self.adapter = adapter
12
+ self.procedure = adapter.procedure
13
+ self.final_file = adapter.final_file
14
+ self.tmp_path = adapter.tmp_path.gsub('\ ', ' ')
15
+
16
+ load_storage_configuration_attributes
17
+ end
18
+ end
19
+
20
+ def static_initialize(procedure)
21
+ self.procedure = procedure
22
+ load_storage_configuration_attributes(true)
23
+ end
24
+
25
+ def session
26
+ @session ||= ::Dropbox::Session.new(api_key, secret_access_key)
27
+ unless @session.authorized?
28
+ @session.authorizing_user = username
29
+ @session.authorizing_password = password
30
+ @session.authorize!
31
+ end
32
+
33
+ @session
34
+ end
35
+
36
+ def connect
37
+ session
38
+ end
39
+
40
+ def path
41
+ @path || "backups"
42
+ end
43
+
44
+ def store
45
+ path_to_file = File.join(tmp_path, final_file)
46
+ session.upload(path_to_file, path, :mode => :dropbox)
47
+ end
48
+
49
+ private
50
+
51
+ def load_storage_configuration_attributes(static=false)
52
+ %w(api_key secret_access_key username password path).each do |attribute|
53
+ if static
54
+ send("#{attribute}=", procedure.get_storage_configuration.attributes[attribute])
55
+ else
56
+ send("#{attribute}=", adapter.procedure.get_storage_configuration.attributes[attribute])
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,88 @@
1
+ require "fog"
2
+
3
+ module Backup
4
+ module Connection
5
+ class S3
6
+ include Backup::CommandHelper
7
+
8
+ MAX_S3_FILE_SIZE = 5368709120 - 1
9
+
10
+ attr_accessor :adapter, :procedure, :access_key_id, :secret_access_key, :host, :s3_bucket, :use_ssl, :final_file, :tmp_path
11
+
12
+ # Initializes the S3 connection, setting the values using the S3 adapter
13
+ def initialize(adapter = false)
14
+ if adapter
15
+ self.adapter = adapter
16
+ self.procedure = adapter.procedure
17
+ self.final_file = adapter.final_file
18
+ self.tmp_path = adapter.tmp_path.gsub('\ ', ' ')
19
+ load_storage_configuration_attributes
20
+ end
21
+ end
22
+
23
+ # Sets values from a procedure, rather than from the adapter object
24
+ def static_initialize(procedure)
25
+ self.procedure = procedure
26
+ load_storage_configuration_attributes(true)
27
+ end
28
+
29
+ # Establishes a connection with Amazon S3 using the credentials provided by the user
30
+ def connection
31
+ @_connection ||= Fog::AWS::Storage.new(
32
+ :aws_access_key_id => access_key_id,
33
+ :aws_secret_access_key => secret_access_key
34
+ )
35
+ end
36
+
37
+ # Initializes the file transfer to Amazon S3
38
+ # This can only run after a connection has been made using the #connect method
39
+ def store
40
+ #TODO: need to add logic like this to restore: `cat /mnt/backups/part.xx >>restore.tgz`
41
+ tmp_file_path = File.join(tmp_path, final_file)
42
+ store_files = []
43
+ if File.stat(File.join(tmp_path, final_file)).size >= MAX_S3_FILE_SIZE
44
+ #we need to split!
45
+ `split -b #{MAX_S3_FILE_SIZE} #{tmp_file_path} #{tmp_file_path}.`
46
+ store_files += `ls #{tmp_file_path}.*`.split
47
+ log("Splitting '#{final_file}' into #{store_files.length} parts as it is too large for s3.")
48
+ else
49
+ store_files << tmp_file_path
50
+ end
51
+
52
+ #lets make sure it exists
53
+ self.connection.put_bucket(s3_bucket)
54
+
55
+ store_files.each do |tmp_file|
56
+ file_name = File.basename(tmp_file)
57
+ log("Saving '#{file_name}' to s3 bucket '#{s3_bucket}'")
58
+ self.connection.put_object(s3_bucket, file_name, open(tmp_file))
59
+ end
60
+ end
61
+
62
+ # Destroys file from a bucket on Amazon S3
63
+ def destroy(file, bucket_as_string)
64
+ self.connection.put_bucket(s3_bucket)
65
+ connection.delete_object(s3_bucket, file)
66
+ end
67
+
68
+ private
69
+
70
+ def load_storage_configuration_attributes(static = false)
71
+ %w(access_key_id secret_access_key use_ssl host).each do |attribute|
72
+ if static
73
+ send("#{attribute}=", procedure.get_storage_configuration.attributes[attribute])
74
+ else
75
+ send("#{attribute}=", adapter.procedure.get_storage_configuration.attributes[attribute])
76
+ end
77
+ end
78
+
79
+ if static
80
+ self.s3_bucket = procedure.get_storage_configuration.attributes['bucket']
81
+ else
82
+ self.s3_bucket = adapter.procedure.get_storage_configuration.attributes['bucket']
83
+ end
84
+ end
85
+
86
+ end
87
+ end
88
+ end