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
@@ -2,78 +2,40 @@ module Backup
2
2
  module Adapters
3
3
  class Custom < Backup::Adapters::Base
4
4
 
5
- attr_accessor :archived_file, :compressed_file, :encrypted_file, :commands
5
+ attr_accessor :commands
6
6
 
7
- # Initializes the Backup Process
8
- #
9
- # This will first load in any prefixed settings from the Backup::Adapters::Base
10
- # Then it will add it's own settings.
11
- #
12
- # First it will execute any given commands
13
- # Then it will archive and compress every folder/file
14
- # Then it will optionally encrypt the backed up file
15
- # Then it will store it to the specified storage location
16
- # Then it will record the data to the database
17
- # Once this is all done, all the temporary files will be removed
18
- #
19
- # Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
20
- def initialize(trigger, procedure)
21
- super
22
- load_settings
23
-
24
- begin
7
+ private
8
+
9
+ # Execute any given commands, then archive and compress every folder/file
10
+ def perform
25
11
  execute_commands
26
12
  targz
27
- encrypt
28
- store
29
- record
30
- notify
31
- ensure
32
- remove_tmp_files
33
13
  end
34
- end
35
-
36
- private
37
14
 
38
15
  # Executes the commands
39
16
  def execute_commands
40
- if commands.is_a?(Array)
41
- puts system_messages[:commands]
42
- commands.each do |command|
43
- %x{ #{command.gsub(':tmp_path', tmp_path)} }
44
- end
45
- elsif commands.is_a?(String)
46
- puts system_messages[:commands]
47
- %x{ #{commands.gsub(':tmp_path', tmp_path)} }
17
+ return unless commands
18
+ log system_messages[:commands]
19
+ [*commands].each do |command|
20
+ run "#{command.gsub(':tmp_path', tmp_path)}"
48
21
  end
49
22
  end
50
23
 
51
24
  # Archives and Compresses
52
25
  def targz
53
- puts system_messages[:archiving]; puts system_messages[:compressing]
54
- %x{ tar -czf #{File.join(tmp_path, compressed_file)} #{File.join(tmp_path, '*')} }
26
+ log system_messages[:archiving]; log system_messages[:compressing]
27
+ run "tar -czf #{File.join(tmp_path, compressed_file)} #{File.join(tmp_path, '*')}"
55
28
  end
56
29
 
57
- # Encrypts the archive file
58
- def encrypt
59
- if encrypt_with_password.is_a?(String)
60
- puts system_messages[:encrypting]
61
- %x{ openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password} }
62
- self.final_file = encrypted_file
63
- end
30
+ def performed_file_extension
31
+ ".tar"
64
32
  end
65
-
33
+
66
34
  # Loads the initial settings
67
35
  def load_settings
68
- self.trigger = procedure.trigger
69
36
  self.commands = procedure.get_adapter_configuration.attributes['commands']
70
-
71
- self.archived_file = "#{timestamp}.#{trigger.gsub(' ', '-')}.tar"
72
- self.compressed_file = "#{archived_file}.gz"
73
- self.encrypted_file = "#{compressed_file}.enc"
74
- self.final_file = compressed_file
75
37
  end
76
38
 
77
39
  end
78
40
  end
79
- end
41
+ end
@@ -2,68 +2,36 @@ module Backup
2
2
  module Adapters
3
3
  class MySQL < Backup::Adapters::Base
4
4
 
5
- attr_accessor :dumped_file, :compressed_file, :encrypted_file, :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options
6
-
7
- # Initializes the Backup Process
8
- #
9
- # This will first load in any prefixed settings from the Backup::Adapters::Base
10
- # Then it will add it's own settings.
11
- #
12
- # First it will create a compressed MySQL dump
13
- # Then it will optionally encrypt the backed up file
14
- # Then it will store it to the specified storage location
15
- # Then it will record the data to the database
16
- # Once this is all done, all the temporary files will be removed
17
- #
18
- # Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
19
- def initialize(trigger, procedure)
20
- super
21
- load_settings
22
-
23
- begin
24
- mysqldump
25
- encrypt
26
- store
27
- record
28
- notify
29
- ensure
30
- remove_tmp_files
31
- end
32
- end
5
+ attr_accessor :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options, :tables
33
6
 
34
7
  private
35
-
8
+
36
9
  # Dumps and Compresses the MySQL file
10
+ def perform
11
+ log system_messages[:mysqldump]; log system_messages[:compressing]
12
+ run "#{mysqldump} -u #{user} --password='#{password}' #{options} #{additional_options} #{database} #{tables_to_include} #{tables_to_skip} | gzip -f --best > #{File.join(tmp_path, compressed_file)}"
13
+ end
14
+
37
15
  def mysqldump
38
- puts system_messages[:mysqldump]; puts system_messages[:compressing]
39
- %x{ mysqldump -u #{user} --password='#{password}' #{options} #{additional_options} #{database} #{tables_to_skip} | gzip -f --best > #{File.join(tmp_path, compressed_file)} }
16
+ # try to determine the full path, and fall back to myqsldump if not found
17
+ cmd = `which mysqldump`.chomp
18
+ cmd = 'mysqldump' if cmd.empty?
19
+ cmd
40
20
  end
41
21
 
42
- # Encrypts the MySQL file
43
- def encrypt
44
- if encrypt_with_password.is_a?(String)
45
- puts system_messages[:encrypting]
46
- %x{ openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password} }
47
- self.final_file = encrypted_file
48
- end
22
+ def performed_file_extension
23
+ ".sql"
49
24
  end
50
-
25
+
51
26
  # Loads the initial settings
52
27
  def load_settings
53
- self.trigger = procedure.trigger
54
-
55
- %w(user password database skip_tables additional_options).each do |attribute|
28
+ %w(user password database tables skip_tables additional_options).each do |attribute|
56
29
  send(:"#{attribute}=", procedure.get_adapter_configuration.attributes[attribute])
57
30
  end
58
31
 
59
32
  %w(host port socket).each do |attribute|
60
33
  send(:"#{attribute}=", procedure.get_adapter_configuration.get_options.attributes[attribute])
61
34
  end
62
-
63
- self.dumped_file = "#{timestamp}.#{trigger.gsub(' ', '-')}.sql"
64
- self.compressed_file = "#{dumped_file}.gz"
65
- self.encrypted_file = "#{compressed_file}.enc"
66
- self.final_file = compressed_file
67
35
  end
68
36
 
69
37
  # Returns a list of options in MySQL syntax
@@ -77,15 +45,16 @@ module Backup
77
45
 
78
46
  # Returns a list of tables to skip in MySQL syntax
79
47
  def tables_to_skip
80
- if skip_tables.is_a?(Array)
81
- skip_tables.map {|table| " --ignore-table='#{database}.#{table}' "}
82
- elsif skip_tables.is_a?(String)
83
- " --ignore-table='#{database}.#{skip_tables}' "
84
- else
85
- ""
86
- end
48
+ return "" unless skip_tables
49
+ [*skip_tables].map {|table| " --ignore-table='#{database}.#{table}' "}
50
+ end
51
+
52
+ # Returns a list of tables to include in MySQL syntax
53
+ def tables_to_include
54
+ return "" unless tables
55
+ [*tables].join(" ")
87
56
  end
88
57
 
89
58
  end
90
59
  end
91
- end
60
+ end
@@ -2,56 +2,31 @@ module Backup
2
2
  module Adapters
3
3
  class PostgreSQL < Backup::Adapters::Base
4
4
 
5
- attr_accessor :dumped_file, :compressed_file, :encrypted_file, :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options
6
-
7
- # Initializes the Backup Process
8
- #
9
- # This will first load in any prefixed settings from the Backup::Adapters::Base
10
- # Then it will add it's own settings.
11
- #
12
- # First it will create a compressed PostgreSQL dump
13
- # Then it will optionally encrypt the backed up file
14
- # Then it will store it to the specified storage location
15
- # Then it will record the data to the database
16
- # Once this is all done, all the temporary files will be removed
17
- #
18
- # Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
19
- def initialize(trigger, procedure)
20
- super
21
- load_settings
22
-
23
- begin
24
- pg_dump
25
- encrypt
26
- store
27
- record
28
- notify
29
- ensure
30
- remove_tmp_files
31
- end
32
- end
5
+ attr_accessor :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options
33
6
 
34
7
  private
35
-
8
+
36
9
  # Dumps and Compresses the PostgreSQL file
10
+ def perform
11
+ log system_messages[:pgdump]; log system_messages[:compressing]
12
+ ENV['PGPASSWORD'] = password
13
+ run "#{pg_dump} -U #{user} #{options} #{additional_options} #{tables_to_skip} #{database} | gzip -f --best > #{File.join(tmp_path, compressed_file)}"
14
+ ENV['PGPASSWORD'] = nil
15
+ end
16
+
37
17
  def pg_dump
38
- puts system_messages[:pgdump]; puts system_messages[:compressing]
39
- %x{ pg_dump -U #{user} #{options} #{additional_options} #{tables_to_skip} #{database} | gzip -f --best > #{File.join(tmp_path, compressed_file)} }
18
+ # try to determine the full path, and fall back to pg_dump if not found
19
+ cmd = `which pg_dump`.chomp
20
+ cmd = 'pg_dump' if cmd.empty?
21
+ cmd
40
22
  end
41
23
 
42
- # Encrypts the PostgreSQL file
43
- def encrypt
44
- if encrypt_with_password.is_a?(String)
45
- puts system_messages[:encrypting]
46
- %x{ openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password} }
47
- self.final_file = encrypted_file
48
- end
24
+ def performed_file_extension
25
+ ".sql"
49
26
  end
50
-
27
+
51
28
  # Loads the initial settings
52
29
  def load_settings
53
- self.trigger = procedure.trigger
54
-
55
30
  %w(user password database skip_tables additional_options).each do |attribute|
56
31
  send(:"#{attribute}=", procedure.get_adapter_configuration.attributes[attribute])
57
32
  end
@@ -59,11 +34,6 @@ module Backup
59
34
  %w(host port socket).each do |attribute|
60
35
  send(:"#{attribute}=", procedure.get_adapter_configuration.get_options.attributes[attribute])
61
36
  end
62
-
63
- self.dumped_file = "#{timestamp}.#{trigger.gsub(' ', '-')}.sql"
64
- self.compressed_file = "#{dumped_file}.gz"
65
- self.encrypted_file = "#{compressed_file}.enc"
66
- self.final_file = compressed_file
67
37
  end
68
38
 
69
39
  # Returns a list of options in PostgreSQL syntax
@@ -77,15 +47,10 @@ module Backup
77
47
 
78
48
  # Returns a list of tables to skip in PostgreSQL syntax
79
49
  def tables_to_skip
80
- if skip_tables.is_a?(Array)
81
- skip_tables.map {|table| " -T \"#{table}\" "}
82
- elsif skip_tables.is_a?(String)
83
- " -T \"#{skip_tables}\" "
84
- else
85
- ""
86
- end
50
+ return "" unless skip_tables
51
+ [*skip_tables].map {|table| " -T \"#{table}\" "}
87
52
  end
88
53
 
89
54
  end
90
55
  end
91
- end
56
+ end
@@ -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,11 @@
1
+ module Backup
2
+ module CommandHelper
3
+ def run(command)
4
+ Kernel.system command
5
+ end
6
+
7
+ def log(command)
8
+ puts "Backup => #{command}"
9
+ end
10
+ end
11
+ end
@@ -1,18 +1,11 @@
1
1
  module Backup
2
2
  module Configuration
3
3
  class Adapter
4
-
5
- attr_accessor :attributes
6
-
7
- %w(files user password database skip_tables commands additional_options).each do |method|
8
- define_method method do |value|
9
- attributes[method] = value
10
- end
11
- end
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(files exclude user password database tables skip_tables commands additional_options)
12
6
 
13
7
  def initialize
14
- @attributes = {}
15
- @options = Backup::Configuration::AdapterOptions.new
8
+ @options = Backup::Configuration::AdapterOptions.new
16
9
  end
17
10
 
18
11
  def options(&block)
@@ -25,4 +18,4 @@ module Backup
25
18
 
26
19
  end
27
20
  end
28
- end
21
+ end
@@ -1,19 +1,8 @@
1
1
  module Backup
2
2
  module Configuration
3
3
  class AdapterOptions
4
-
5
- attr_accessor :attributes
6
-
7
- %w(host port socket).each do |method|
8
- define_method method do |value|
9
- attributes[method] = 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 socket)
17
6
  end
18
7
  end
19
- 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
+
@@ -1,16 +1,12 @@
1
1
  module Backup
2
2
  module Configuration
3
3
  class Base
4
- attr_accessor :attributes, :trigger, :storage_name, :adapter_name
5
-
6
- %w(encrypt_with_password keep_backups notify).each do |method|
7
- define_method method do |value|
8
- attributes[method] = value
9
- end
10
- end
4
+ extend Backup::Configuration::Attributes
5
+ generate_attributes %w(encrypt_with_password keep_backups notify)
6
+
7
+ attr_accessor :trigger, :storage_name, :adapter_name
11
8
 
12
9
  def initialize(trigger)
13
- @attributes = {}
14
10
  @trigger = trigger
15
11
  @adapter_configuration = Backup::Configuration::Adapter.new
16
12
  @storage_configuration = Backup::Configuration::Storage.new
@@ -25,6 +21,27 @@ module Backup
25
21
  @storage_name = storage
26
22
  @storage_configuration.instance_eval &block
27
23
  end
24
+
25
+ # Initializes the storing process depending on the store settings
26
+ def initialize_storage(adapter)
27
+ case @storage_name.to_sym
28
+ when :s3 then Backup::Storage::S3.new(adapter)
29
+ when :scp then Backup::Storage::SCP.new(adapter)
30
+ when :ftp then Backup::Storage::FTP.new(adapter)
31
+ when :sftp then Backup::Storage::SFTP.new(adapter)
32
+ when :local then Backup::Storage::Local.new(adapter)
33
+ end
34
+ end
35
+
36
+ def initialize_record
37
+ case @storage_name.to_sym
38
+ when :s3 then Backup::Record::S3.new
39
+ when :scp then Backup::Record::SCP.new
40
+ when :ftp then Backup::Record::FTP.new
41
+ when :sftp then Backup::Record::SFTP.new
42
+ when :local then Backup::Record::Local.new
43
+ end
44
+ end
28
45
 
29
46
  def get_adapter_configuration
30
47
  @adapter_configuration
@@ -35,4 +52,4 @@ module Backup
35
52
  end
36
53
  end
37
54
  end
38
- end
55
+ end