backup 2.3.1 → 2.3.2.pre

Sign up to get free protection for your applications and to get access to all the features.
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