backup 2.3.1 → 2.3.2.pre

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 (45) hide show
  1. data/CHANGELOG +16 -1
  2. data/README.textile +42 -177
  3. data/bin/backup +14 -17
  4. data/generators/backup/templates/config/backup.rb +26 -6
  5. data/generators/backup/templates/migrations/create_backup_tables.rb +3 -2
  6. data/generators/backup/templates/tasks/backup.rake +14 -17
  7. data/generators/backup_update/backup_update_generator.rb +50 -0
  8. data/generators/backup_update/templates/migrations/update_backup_tables.rb +27 -0
  9. data/lib/backup.rb +31 -30
  10. data/lib/backup/adapters/archive.rb +19 -54
  11. data/lib/backup/adapters/base.rb +55 -35
  12. data/lib/backup/adapters/custom.rb +15 -53
  13. data/lib/backup/adapters/mysql.rb +24 -55
  14. data/lib/backup/adapters/postgresql.rb +19 -54
  15. data/lib/backup/adapters/sqlite.rb +25 -0
  16. data/lib/backup/command_helper.rb +11 -0
  17. data/lib/backup/configuration/adapter.rb +4 -11
  18. data/lib/backup/configuration/adapter_options.rb +3 -14
  19. data/lib/backup/configuration/attributes.rb +19 -0
  20. data/lib/backup/configuration/base.rb +26 -9
  21. data/lib/backup/configuration/mail.rb +3 -9
  22. data/lib/backup/configuration/smtp.rb +3 -14
  23. data/lib/backup/configuration/storage.rb +3 -12
  24. data/lib/backup/connection/s3.rb +3 -1
  25. data/lib/backup/environment/unix.rb +4 -4
  26. data/lib/backup/mail/base.rb +8 -2
  27. data/lib/backup/mail/mail.txt +3 -3
  28. data/lib/backup/record/base.rb +65 -0
  29. data/lib/backup/record/ftp.rb +10 -69
  30. data/lib/backup/record/local.rb +26 -0
  31. data/lib/backup/record/s3.rb +9 -63
  32. data/lib/backup/record/scp.rb +9 -64
  33. data/lib/backup/record/sftp.rb +10 -68
  34. data/lib/backup/storage/ftp.rb +3 -1
  35. data/lib/backup/storage/local.rb +24 -0
  36. data/lib/backup/storage/s3.rb +3 -1
  37. data/lib/backup/storage/scp.rb +3 -1
  38. data/lib/backup/storage/sftp.rb +3 -1
  39. data/setup/backup.rb +27 -6
  40. data/setup/backup.sqlite3 +0 -0
  41. metadata +130 -60
  42. data/.document +0 -5
  43. data/.gitignore +0 -5
  44. data/Rakefile +0 -70
  45. data/backup.gemspec +0 -111
@@ -1,16 +1,10 @@
1
1
  module Backup
2
2
  module Configuration
3
3
  class Mail
4
- attr_accessor :attributes
5
-
6
- %w(from to smtp).each do |method|
7
- define_method method do |value|
8
- attributes[method.to_sym] = value
9
- end
10
- end
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(from to smtp)
11
6
 
12
7
  def initialize
13
- @attributes = {}
14
8
  @smtp_configuration = Backup::Configuration::SMTP.new
15
9
  end
16
10
 
@@ -23,4 +17,4 @@ module Backup
23
17
  end
24
18
  end
25
19
  end
26
- end
20
+ end
@@ -1,19 +1,8 @@
1
1
  module Backup
2
2
  module Configuration
3
3
  class SMTP
4
-
5
- attr_accessor :attributes
6
-
7
- %w(host port username password authentication domain tls).each do |method|
8
- define_method method do |value|
9
- attributes[method.to_sym] = value
10
- end
11
- end
12
-
13
- def initialize
14
- @attributes = {}
15
- end
16
-
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(host port username password authentication domain tls)
17
6
  end
18
7
  end
19
- end
8
+ end
@@ -1,17 +1,8 @@
1
1
  module Backup
2
2
  module Configuration
3
3
  class Storage
4
- attr_accessor :attributes
5
-
6
- %w(ip user password path access_key_id secret_access_key use_ssl bucket).each do |method|
7
- define_method method do |value|
8
- attributes[method] = value
9
- end
10
- end
11
-
12
- def initialize
13
- @attributes = {}
14
- end
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(ip user password path access_key_id secret_access_key use_ssl bucket)
15
6
  end
16
7
  end
17
- end
8
+ end
@@ -1,3 +1,5 @@
1
+ require 'aws/s3'
2
+
1
3
  module Backup
2
4
  module Connection
3
5
  class S3
@@ -82,4 +84,4 @@ module Backup
82
84
 
83
85
  end
84
86
  end
85
- end
87
+ end
@@ -5,13 +5,13 @@ module Backup
5
5
  require 'active_record'
6
6
  require 'optparse'
7
7
 
8
- # Sets BACKUP_PATH equal to /opt/backup
9
- BACKUP_PATH = "/opt/backup"
8
+ # Sets BACKUP_PATH
9
+ BACKUP_PATH = ENV['BACKUP_PATH'] || "/opt/backup"
10
10
 
11
11
  # Sets DB_CONNECTION_SETTINGS
12
12
  DB_CONNECTION_SETTINGS = {
13
13
  :adapter => "sqlite3",
14
- :database => "/opt/backup/backup.sqlite3",
14
+ :database => "#{BACKUP_PATH}/backup.sqlite3",
15
15
  :pool => 5,
16
16
  :timeout => 5000
17
17
  }
@@ -32,7 +32,7 @@ module Backup
32
32
 
33
33
  1: Set up some "Backup Settings" inside the configuration file!
34
34
 
35
- /opt/backup/config/backup.rb
35
+ #{BACKUP_PATH}/config/backup.rb
36
36
 
37
37
 
38
38
  2: Run the backups!
@@ -1,3 +1,5 @@
1
+ require 'pony'
2
+
1
3
  module Backup
2
4
  module Mail
3
5
  class Base
@@ -77,8 +79,12 @@ module Backup
77
79
  line.gsub!(':time', Time.now.strftime("%r"))
78
80
  line.gsub!(':adapter', @backup.procedure.adapter_name.to_s)
79
81
  line.gsub!(':location', bucket || path)
80
- line.gsub!(':remote', bucket ? "Amazon S3" : "the remote server (#{ip})")
81
82
  line.gsub!(':backup', @backup.final_file)
83
+ case @backup.procedure.storage_name.to_sym
84
+ when :s3 then line.gsub!(':remote', "on Amazon S3")
85
+ when :local then line.gsub!(':remote', "on the local server")
86
+ when :scp, :sftp, :ftp then line.gsub!(':remote', "on the remote server (#{ip})")
87
+ end
82
88
  @content ||= String.new
83
89
  @content << line
84
90
  end
@@ -86,4 +92,4 @@ module Backup
86
92
 
87
93
  end
88
94
  end
89
- end
95
+ end
@@ -1,7 +1,7 @@
1
- A backup was successfully created for ":trigger"!
1
+ A backup was successfully created for the trigger: ":trigger"!
2
2
 
3
- The backup was created on ":day of :month :year at :time".
3
+ The backup was created on ":day of :month :year at :time", using the ":adapter" adapter.
4
4
 
5
- It has been stored using the ":adapter" adapter, and the file was stored in :location on :remote.
5
+ The Backup was stored in ":location" :remote.
6
6
 
7
7
  The following backup was stored: ":backup"
@@ -0,0 +1,65 @@
1
+ module Backup
2
+ module Record
3
+ class Base < ActiveRecord::Base
4
+
5
+ if DB_CONNECTION_SETTINGS
6
+ establish_connection(DB_CONNECTION_SETTINGS)
7
+ end
8
+
9
+ set_table_name 'backup'
10
+
11
+ default_scope :order => 'created_at desc'
12
+
13
+ # Callbacks
14
+ after_save :clean_backups
15
+
16
+ # Attributes
17
+ attr_accessor :adapter_config, :keep_backups
18
+
19
+ # Receives the options hash and stores it
20
+ def load_adapter(adapter)
21
+ self.adapter_config = adapter
22
+ self.trigger = adapter.procedure.trigger
23
+ self.adapter = adapter.procedure.adapter_name.to_s
24
+ self.filename = adapter.final_file
25
+ self.keep_backups = adapter.procedure.attributes['keep_backups']
26
+
27
+ # TODO calculate md5sum of file
28
+ load_specific_settings(adapter) if respond_to?(:load_specific_settings)
29
+ end
30
+
31
+ # Destroys all backups for the specified trigger from Remote Server (FTP)
32
+ def self.destroy_all_backups(procedure, trigger)
33
+ backups = self.all(:conditions => {:trigger => trigger})
34
+ unless backups.empty?
35
+ # Derived classes must implement this method!
36
+ self.destroy_backups(procedure, backups)
37
+
38
+ puts "\nAll \"#{procedure.trigger}\" backups destroyed.\n\n"
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ # Maintains the backup file amount on the remote server
45
+ # This is invoked after a successful record save
46
+ # This deletes the oldest files when the backup limit has been exceeded
47
+ def clean_backups
48
+ if keep_backups.is_a?(Integer)
49
+ backups = self.class.all(:conditions => {:trigger => trigger})
50
+ backups_to_destroy = backups[keep_backups, backups.size] || []
51
+
52
+ unless backups_to_destroy.empty?
53
+ # Derived classes must implement this method!
54
+ self.class.destroy_backups(adapter_config.procedure, backups_to_destroy)
55
+
56
+ puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
57
+ puts "\nThe #{keep_backups} most recent backups are now stored on the remote server.\n\n"
58
+ end
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+
@@ -1,41 +1,20 @@
1
+ require 'net/ftp'
2
+
1
3
  module Backup
2
4
  module Record
3
- class FTP < ActiveRecord::Base
4
-
5
- if DB_CONNECTION_SETTINGS
6
- establish_connection(DB_CONNECTION_SETTINGS)
7
- end
8
-
9
- set_table_name 'backup'
10
- default_scope \
11
- :order => 'created_at desc',
12
- :conditions => {:storage => 'ftp'}
13
-
14
- # Callbacks
15
- after_save :clean_backups
5
+ class FTP < Backup::Record::Base
16
6
 
17
- # Attributes
18
- attr_accessor :adapter_config, :keep_backups, :ip, :user, :password
7
+ attr_accessor :ip, :user, :password
19
8
 
20
- # Receives the options hash and stores it
21
- # Sets the FTP values
22
- def load_adapter(adapter)
23
- self.adapter_config = adapter
24
- self.storage = 'ftp'
25
- self.trigger = adapter.procedure.trigger
26
- self.adapter = adapter.procedure.adapter_name.to_s
27
- self.filename = adapter.final_file
28
- self.keep_backups = adapter.procedure.attributes['keep_backups']
29
-
9
+ def load_specific_settings(adapter)
30
10
  %w(ip user password path).each do |method|
31
11
  send(:"#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
32
12
  end
33
13
  end
34
14
 
35
- # Destroys all backups for the specified trigger from Remote Server (FTP)
36
- def self.destroy_all_backups(procedure, trigger)
37
- backups = Backup::Record::FTP.all(:conditions => {:trigger => trigger})
38
- unless backups.empty?
15
+ private
16
+
17
+ def self.destroy_backups(procedure, backups)
39
18
  ip = procedure.get_storage_configuration.attributes['ip']
40
19
  user = procedure.get_storage_configuration.attributes['user']
41
20
  password = procedure.get_storage_configuration.attributes['password']
@@ -48,51 +27,13 @@ module Backup
48
27
  ftp.delete(backup.filename)
49
28
  backup.destroy
50
29
  rescue
30
+ puts "Could not find backup #{backup.path}/#{backup.filename}."
51
31
  backup.destroy
52
32
  end
53
33
  end
54
34
  end
55
-
56
- puts "\nAll \"#{trigger}\" backups destroyed.\n\n"
57
- end
58
- end
59
-
60
- private
61
-
62
- # Maintains the backup file amount on the remote server
63
- # This is invoked after a successful record save
64
- # This deletes the oldest files when the backup limit has been exceeded
65
- def clean_backups
66
- if keep_backups.is_a?(Integer)
67
- backups = Backup::Record::FTP.all(:conditions => {:trigger => trigger})
68
- backups_to_destroy = Array.new
69
- backups.each_with_index do |backup, index|
70
- if index >= keep_backups then
71
- backups_to_destroy << backup
72
- end
73
- end
74
-
75
- unless backups_to_destroy.empty?
76
- Net::FTP.open(ip, user, password) do |ftp|
77
- backups_to_destroy.each do |backup|
78
- puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
79
- begin
80
- ftp.chdir(backup.path)
81
- ftp.delete(backup.filename)
82
- backup.destroy
83
- rescue
84
- puts "Could not find backup #{backup.path}/#{backup.filename}.."
85
- backup.destroy
86
- end
87
- end
88
- end
89
-
90
- puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
91
- puts "\nThe #{keep_backups} most recent backups are now stored on the remote server.\n\n"
92
- end
93
- end
94
35
  end
95
36
 
96
37
  end
97
38
  end
98
- end
39
+ end
@@ -0,0 +1,26 @@
1
+ module Backup
2
+ module Record
3
+ class Local < Backup::Record::Base
4
+
5
+ def load_specific_settings(adapter)
6
+ self.path = adapter.procedure.get_storage_configuration.attributes['path']
7
+ end
8
+
9
+ private
10
+
11
+ class << self
12
+ include Backup::CommandHelper
13
+
14
+ def destroy_backups(procedure, backups)
15
+ backups.each do |backup|
16
+ puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
17
+ run "rm #{File.join(backup.path, backup.filename)}"
18
+ backup.destroy
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+
@@ -1,38 +1,16 @@
1
+ require 'backup/connection/s3'
2
+
1
3
  module Backup
2
4
  module Record
3
- class S3 < ActiveRecord::Base
5
+ class S3 < Backup::Record::Base
4
6
 
5
- if DB_CONNECTION_SETTINGS
6
- establish_connection(DB_CONNECTION_SETTINGS)
7
+ def load_specific_settings(adapter)
8
+ self.bucket = adapter.procedure.get_storage_configuration.attributes['bucket']
7
9
  end
8
10
 
9
- set_table_name 'backup'
10
- default_scope \
11
- :order => 'created_at desc',
12
- :conditions => {:storage => 's3'}
13
-
14
- # Callbacks
15
- after_save :clean_backups
16
-
17
- # Attributes
18
- attr_accessor :adapter_config, :keep_backups
19
-
20
- # Receives the options hash and stores it
21
- # Sets the S3 values
22
- def load_adapter(adapter)
23
- self.adapter_config = adapter
24
- self.storage = 's3'
25
- self.trigger = adapter.procedure.trigger
26
- self.adapter = adapter.procedure.adapter_name.to_s
27
- self.filename = adapter.final_file
28
- self.bucket = adapter.procedure.get_storage_configuration.attributes['bucket']
29
- self.keep_backups = adapter.procedure.attributes['keep_backups']
30
- end
31
-
32
- # Destroys all backups for the specified trigger from Amazon S3
33
- def self.destroy_all_backups(procedure, trigger)
34
- backups = Backup::Record::S3.all(:conditions => {:trigger => trigger})
35
- unless backups.empty?
11
+ private
12
+
13
+ def self.destroy_backups(procedure, backups)
36
14
  s3 = Backup::Connection::S3.new
37
15
  s3.static_initialize(procedure)
38
16
  s3.connect
@@ -41,40 +19,8 @@ module Backup
41
19
  s3.destroy(backup.filename, backup.bucket)
42
20
  backup.destroy
43
21
  end
44
- puts "\nAll \"#{trigger}\" backups destroyed.\n\n"
45
- end
46
- end
47
-
48
- private
49
-
50
- # Maintains the backup file amount on S3
51
- # This is invoked after a successful record save
52
- # This deletes the oldest files when the backup limit has been exceeded
53
- def clean_backups
54
- if keep_backups.is_a?(Integer)
55
- backups = Backup::Record::S3.all(:conditions => {:trigger => trigger})
56
- backups_to_destroy = Array.new
57
- backups.each_with_index do |backup, index|
58
- if index >= keep_backups then
59
- backups_to_destroy << backup
60
- end
61
- end
62
-
63
- unless backups_to_destroy.empty?
64
- s3 = Backup::Connection::S3.new(adapter_config)
65
- s3.connect
66
- backups_to_destroy.each do |backup|
67
- puts "\nDestroying backup \"#{backup.filename}\" from bucket \"#{backup.bucket}\"."
68
- s3.destroy(backup.filename, backup.bucket)
69
- backup.destroy
70
- end
71
-
72
- puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
73
- puts "\nThe #{keep_backups} most recent backups are now stored on S3.\n\n"
74
- end
75
- end
76
22
  end
77
23
 
78
24
  end
79
25
  end
80
- end
26
+ end
@@ -1,41 +1,20 @@
1
+ require 'net/scp'
2
+
1
3
  module Backup
2
4
  module Record
3
- class SCP < ActiveRecord::Base
4
-
5
- if DB_CONNECTION_SETTINGS
6
- establish_connection(DB_CONNECTION_SETTINGS)
7
- end
5
+ class SCP < Backup::Record::Base
8
6
 
9
- set_table_name 'backup'
10
- default_scope \
11
- :order => 'created_at desc',
12
- :conditions => {:storage => 'scp'}
13
-
14
- # Callbacks
15
- after_save :clean_backups
16
-
17
- # Attributes
18
- attr_accessor :adapter_config, :keep_backups, :ip, :user, :password
7
+ attr_accessor :ip, :user, :password
19
8
 
20
- # Receives the options hash and stores it
21
- # Sets the SCP values
22
- def load_adapter(adapter)
23
- self.adapter_config = adapter
24
- self.storage = 'scp'
25
- self.trigger = adapter.procedure.trigger
26
- self.adapter = adapter.procedure.adapter_name.to_s
27
- self.filename = adapter.final_file
28
- self.keep_backups = adapter.procedure.attributes['keep_backups']
29
-
9
+ def load_specific_settings(adapter)
30
10
  %w(ip user password path).each do |method|
31
11
  send(:"#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
32
12
  end
33
13
  end
34
14
 
35
- # Destroys all backups for the specified trigger from Remote Server (SCP)
36
- def self.destroy_all_backups(procedure, trigger)
37
- backups = Backup::Record::SCP.all(:conditions => {:trigger => trigger})
38
- unless backups.empty?
15
+ private
16
+
17
+ def self.destroy_backups(procedure, backups)
39
18
  ip = procedure.get_storage_configuration.attributes['ip']
40
19
  user = procedure.get_storage_configuration.attributes['user']
41
20
  password = procedure.get_storage_configuration.attributes['password']
@@ -47,42 +26,8 @@ module Backup
47
26
  backup.destroy
48
27
  end
49
28
  end
50
- puts "\nAll \"#{trigger}\" backups destroyed.\n\n"
51
- end
52
- end
53
-
54
- private
55
-
56
- # Maintains the backup file amount on the remote server
57
- # This is invoked after a successful record save
58
- # This deletes the oldest files when the backup limit has been exceeded
59
- def clean_backups
60
- if keep_backups.is_a?(Integer)
61
- backups = Backup::Record::SCP.all(:conditions => {:trigger => trigger})
62
- backups_to_destroy = Array.new
63
- backups.each_with_index do |backup, index|
64
- if index >= keep_backups then
65
- backups_to_destroy << backup
66
- end
67
- end
68
-
69
- unless backups_to_destroy.empty?
70
-
71
- Net::SSH.start(ip, user, :password => password) do |ssh|
72
- backups_to_destroy.each do |backup|
73
- puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
74
- ssh.exec("rm #{File.join(backup.path, backup.filename)}")
75
- backup.destroy
76
- end
77
- end
78
-
79
- puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
80
- puts "\nThe #{keep_backups} most recent backups are now stored on the remote server.\n\n"
81
-
82
- end
83
- end
84
29
  end
85
30
 
86
31
  end
87
32
  end
88
- end
33
+ end