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
@@ -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