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,12 +1,13 @@
1
1
  class CreateBackupTables < ActiveRecord::Migration
2
2
  def self.up
3
3
  create_table :backup do |t|
4
- t.string :storage
5
4
  t.string :trigger
6
5
  t.string :adapter
7
6
  t.string :filename
7
+ t.string :md5sum
8
8
  t.string :path
9
9
  t.string :bucket
10
+ t.string :type
10
11
  t.timestamps
11
12
  end
12
13
  end
@@ -14,4 +15,4 @@ class CreateBackupTables < ActiveRecord::Migration
14
15
  def self.down
15
16
  drop_table :backup
16
17
  end
17
- end
18
+ end
@@ -12,10 +12,11 @@ namespace :backup do
12
12
  backup = Backup::Setup.new(ENV['trigger'], @backup_procedures)
13
13
  records = Array.new
14
14
  case backup.procedure.storage_name.to_sym
15
- when :s3 then records = Backup::Record::S3.all :conditions => {:trigger => ENV['trigger']}
16
- when :scp then records = Backup::Record::SCP.all :conditions => {:trigger => ENV['trigger']}
17
- when :ftp then records = Backup::Record::FTP.all :conditions => {:trigger => ENV['trigger']}
18
- when :sftp then records = Backup::Record::SFTP.all :conditions => {:trigger => ENV['trigger']}
15
+ when :s3 then records = Backup::Record::S3.all :conditions => {:trigger => ENV['trigger']}
16
+ when :scp then records = Backup::Record::SCP.all :conditions => {:trigger => ENV['trigger']}
17
+ when :ftp then records = Backup::Record::FTP.all :conditions => {:trigger => ENV['trigger']}
18
+ when :sftp then records = Backup::Record::SFTP.all :conditions => {:trigger => ENV['trigger']}
19
+ when :local then records = Backup::Record::Local.all :conditions => {:trigger => ENV['trigger']}
19
20
  end
20
21
 
21
22
  if ENV['table'].eql?("true")
@@ -30,19 +31,13 @@ namespace :backup do
30
31
  desc "Truncates all records for the specified \"trigger\", excluding the physical files on s3 or the remote server."
31
32
  task :truncate => :environment do
32
33
  puts "Truncating backup records with trigger: #{ENV['trigger']}."
33
- Backup::Record::S3.destroy_all :trigger => ENV['trigger'], :storage => 's3'
34
- Backup::Record::SCP.destroy_all :trigger => ENV['trigger'], :storage => 'scp'
35
- Backup::Record::FTP.destroy_all :trigger => ENV['trigger'], :storage => 'ftp'
36
- Backup::Record::SFTP.destroy_all :trigger => ENV['trigger'], :storage => 'sftp'
34
+ Backup::Record::Base.destroy_all :trigger => ENV['trigger']
37
35
  end
38
36
 
39
37
  desc "Truncates everything."
40
38
  task :truncate_all => :environment do
41
39
  puts "Truncating all backup records."
42
- Backup::Record::S3.destroy_all
43
- Backup::Record::SCP.destroy_all
44
- Backup::Record::FTP.destroy_all
45
- Backup::Record::SFTP.destroy_all
40
+ Backup::Record::Base.destroy_all
46
41
  end
47
42
 
48
43
  desc "Destroys all records for the specified \"trigger\", including the physical files on s3 or the remote server."
@@ -50,10 +45,11 @@ namespace :backup do
50
45
  puts "Destroying backup records with trigger: #{ENV['trigger']}."
51
46
  backup = Backup::Setup.new(ENV['trigger'], @backup_procedures)
52
47
  case backup.procedure.storage_name.to_sym
53
- when :s3 then Backup::Record::S3.destroy_all_backups backup.procedure, ENV['trigger']
54
- when :scp then Backup::Record::SCP.destroy_all_backups backup.procedure, ENV['trigger']
55
- when :ftp then Backup::Record::FTP.destroy_all_backups backup.procedure, ENV['trigger']
56
- when :sftp then Backup::Record::SFTP.destroy_all_backups backup.procedure, ENV['trigger']
48
+ when :s3 then Backup::Record::S3.destroy_all_backups backup.procedure, ENV['trigger']
49
+ when :scp then Backup::Record::SCP.destroy_all_backups backup.procedure, ENV['trigger']
50
+ when :ftp then Backup::Record::FTP.destroy_all_backups backup.procedure, ENV['trigger']
51
+ when :sftp then Backup::Record::SFTP.destroy_all_backups backup.procedure, ENV['trigger']
52
+ when :local then Backup::Record::Local.destroy_all_backups backup.procedure, ENV['trigger']
57
53
  end
58
54
  end
59
55
 
@@ -67,8 +63,9 @@ namespace :backup do
67
63
  when :scp then Backup::Record::SCP.destroy_all_backups backup_procedure, backup_procedure.trigger
68
64
  when :ftp then Backup::Record::FTP.destroy_all_backups backup_procedure, backup_procedure.trigger
69
65
  when :sftp then Backup::Record::SFTP.destroy_all_backups backup_procedure, backup_procedure.trigger
66
+ when :local then Backup::Record::Local.destroy_all_backups backup_procedure, backup_procedure.trigger
70
67
  end
71
68
  end
72
69
  end
73
70
 
74
- end
71
+ end
@@ -0,0 +1,50 @@
1
+ class BackupUpdateGenerator < Rails::Generator::Base
2
+
3
+ # This method gets initialized when the generator gets run.
4
+ # It will receive an array of arguments inside @args
5
+ def initialize(runtime_args, runtime_options = {})
6
+ super
7
+ end
8
+
9
+ # Processes the file generation/templating
10
+ # This will automatically be run after the initialize method
11
+ def manifest
12
+ record do |m|
13
+
14
+ # Generates the database update migration file
15
+ m.migration_template "migrations/update_backup_tables.rb",
16
+ "db/migrate",
17
+ :migration_file_name => "update_backup_tables"
18
+
19
+ # Outputs the generators message to the terminal
20
+ puts message
21
+ end
22
+ end
23
+
24
+ def message
25
+ <<-MESSAGE
26
+
27
+
28
+
29
+ ==============================================================
30
+ Backup's update files have been generated!
31
+ ==============================================================
32
+
33
+ Please follow these instructions Backup:
34
+
35
+ 1: Please migrate the database to finish the update!
36
+
37
+ rake db:migrate
38
+
39
+
40
+ For More Information:
41
+ http://github.com/meskyanichi/backup
42
+
43
+ ==============================================================
44
+
45
+
46
+
47
+ MESSAGE
48
+ end
49
+
50
+ end
@@ -0,0 +1,27 @@
1
+ class UpdateBackupTables < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :backup do |t|
4
+ t.rename :storage, :type # will use STI from now
5
+ t.string :md5sum
6
+ end
7
+
8
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::FTP' WHERE type='ftp'"
9
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::Local' WHERE type='local'"
10
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::S3' WHERE type='s3'"
11
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::SCP' WHERE type='scp'"
12
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::SFTP' WHERE type='sftp'"
13
+ end
14
+
15
+ def self.down
16
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='ftp' WHERE type='Backup::Record::FTP'"
17
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='local' WHERE type='Backup::Record::Local'"
18
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='s3' WHERE type='Backup::Record::S3'"
19
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='scp' WHERE type='Backup::Record::SCP'"
20
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='sftp' WHERE type='Backup::Record::SFTP'"
21
+
22
+ change_table :backup do |t|
23
+ t.rename :type, :storage
24
+ t.remove :md5sum
25
+ end
26
+ end
27
+ end
data/lib/backup.rb CHANGED
@@ -1,10 +1,4 @@
1
1
  # Load Gems
2
- require 'net/ssh'
3
- require 'net/scp'
4
- require 'net/ftp'
5
- require 'net/sftp'
6
- require 'aws/s3'
7
- require 'pony'
8
2
  require 'hirb'
9
3
 
10
4
  # Load Environments
@@ -13,6 +7,7 @@ require 'backup/environment/unix'
13
7
  require 'backup/environment/rails'
14
8
 
15
9
  # Load Configuration
10
+ require 'backup/configuration/attributes'
16
11
  require 'backup/configuration/base'
17
12
  require 'backup/configuration/adapter'
18
13
  require 'backup/configuration/adapter_options'
@@ -21,7 +16,9 @@ require 'backup/configuration/mail'
21
16
  require 'backup/configuration/smtp'
22
17
  require 'backup/configuration/helpers'
23
18
 
24
- # Include the Configuration adn Environment Helpers
19
+ require 'backup/command_helper'
20
+
21
+ # Include the Configuration and Environment Helpers
25
22
  include Backup::Configuration::Helpers
26
23
  include Backup::Environment::Base
27
24
 
@@ -42,31 +39,34 @@ require 'backup/mail/base'
42
39
  # Set Mail Configuration (extracted from the backup.rb configuration file) inside the Mail Class
43
40
  Backup::Mail::Base.setup(@mail_configuration)
44
41
 
45
- # Load Adapters
46
- require 'backup/adapters/base'
47
- require 'backup/adapters/mysql'
48
- require 'backup/adapters/postgresql'
49
- require 'backup/adapters/archive'
50
- require 'backup/adapters/custom'
51
-
52
- # Load Connectors
53
- require 'backup/connection/s3'
54
-
55
- # Load Storage
56
- require 'backup/storage/s3'
57
- require 'backup/storage/scp'
58
- require 'backup/storage/ftp'
59
- require 'backup/storage/sftp'
42
+ # Backup Module
43
+ module Backup
44
+ module Adapters
45
+ autoload :Base, 'backup/adapters/base'
46
+ autoload :MySQL, 'backup/adapters/mysql'
47
+ autoload :SQLite, 'backup/adapters/sqlite'
48
+ autoload :PostgreSQL, 'backup/adapters/postgresql'
49
+ autoload :Archive, 'backup/adapters/archive'
50
+ autoload :Custom, 'backup/adapters/custom'
51
+ end
60
52
 
61
- # Backup Recorders
62
- require 'backup/record/s3'
63
- require 'backup/record/scp'
64
- require 'backup/record/ftp'
65
- require 'backup/record/sftp'
53
+ module Storage
54
+ autoload :S3, 'backup/storage/s3'
55
+ autoload :SCP, 'backup/storage/scp'
56
+ autoload :FTP, 'backup/storage/ftp'
57
+ autoload :SFTP, 'backup/storage/sftp'
58
+ autoload :Local, 'backup/storage/local'
59
+ end
66
60
 
61
+ module Record
62
+ autoload :Base, 'backup/record/base'
63
+ autoload :S3, 'backup/record/s3'
64
+ autoload :SCP, 'backup/record/scp'
65
+ autoload :FTP, 'backup/record/ftp'
66
+ autoload :SFTP, 'backup/record/sftp'
67
+ autoload :Local, 'backup/record/local'
68
+ end
67
69
 
68
- # Backup Module
69
- module Backup
70
70
  class Setup
71
71
 
72
72
  attr_accessor :trigger, :procedures, :procedure
@@ -83,6 +83,7 @@ module Backup
83
83
  def initialize_adapter
84
84
  case procedure.adapter_name.to_sym
85
85
  when :mysql then Backup::Adapters::MySQL.new trigger, procedure
86
+ when :sqlite then Backup::Adapters::SQLite.new trigger, procedure
86
87
  when :postgresql then Backup::Adapters::PostgreSQL.new trigger, procedure
87
88
  when :archive then Backup::Adapters::Archive.new trigger, procedure
88
89
  when :custom then Backup::Adapters::Custom.new trigger, procedure
@@ -108,4 +109,4 @@ module Backup
108
109
  end
109
110
 
110
111
  end
111
- end
112
+ end
@@ -2,68 +2,33 @@ module Backup
2
2
  module Adapters
3
3
  class Archive < Backup::Adapters::Base
4
4
 
5
- attr_accessor :archived_file, :compressed_file, :encrypted_file
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 archive and compress every folder/file
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
- targz
25
- encrypt
26
- store
27
- record
28
- notify
29
- ensure
30
- remove_tmp_files
31
- end
32
- end
5
+ attr_accessor :files, :exclude
33
6
 
34
7
  private
35
-
8
+
36
9
  # Archives and Compresses all files
37
- def targz
38
- files = procedure.get_adapter_configuration.attributes['files']
39
- if files.is_a?(Array)
40
- puts system_messages[:archiving]; puts system_messages[:compressing]
41
- %x{ tar -czf #{File.join(tmp_path, compressed_file)} #{files.map{|f| f.gsub(' ', '\ ')}.join(' ')} }
42
- elsif files.is_a?(String)
43
- puts system_messages[:archiving]; puts system_messages[:compressing]
44
- %x{ tar -czf #{File.join(tmp_path, compressed_file)} #{files.gsub(' ', '\ ')} }
45
- end
46
- end
47
-
48
- # Encrypts the Archive
49
- def encrypt
50
- if encrypt_with_password.is_a?(String)
51
- puts system_messages[:encrypting]
52
- %x{ openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password} }
53
- self.final_file = encrypted_file
54
- end
10
+ def perform
11
+ log system_messages[:archiving]; log system_messages[:compressing]
12
+ run "tar -czf #{File.join(tmp_path, compressed_file)} #{exclude_files} #{tar_files}"
55
13
  end
56
14
 
57
- # Loads the initial settings
58
15
  def load_settings
59
- self.trigger = procedure.trigger
16
+ self.files = procedure.get_adapter_configuration.attributes['files']
17
+ self.exclude = procedure.get_adapter_configuration.attributes['exclude']
18
+ end
60
19
 
61
- self.archived_file = "#{timestamp}.#{trigger.gsub(' ', '-')}.tar"
62
- self.compressed_file = "#{archived_file}.gz"
63
- self.encrypted_file = "#{compressed_file}.enc"
64
- self.final_file = compressed_file
20
+ def performed_file_extension
21
+ ".tar"
65
22
  end
66
23
 
24
+ def tar_files
25
+ [*files].map{|f| f.gsub(' ', '\ ')}.join(' ')
26
+ end
27
+
28
+ def exclude_files
29
+ [*exclude].compact.map{|x| "--exclude=#{x}"}.join(' ')
30
+ end
31
+
67
32
  end
68
33
  end
69
- end
34
+ end
@@ -2,6 +2,8 @@ module Backup
2
2
  module Adapters
3
3
  class Base
4
4
 
5
+ include Backup::CommandHelper
6
+
5
7
  attr_accessor :procedure, :timestamp, :options, :tmp_path, :encrypt_with_password, :keep_backups, :trigger
6
8
 
7
9
  # IMPORTANT
@@ -13,8 +15,21 @@ module Backup
13
15
  # myfile.gz.enc
14
16
  #
15
17
  # It is important that, whatever the final filename of the file will be, that :final_file will contain it.
16
- attr_accessor :final_file
18
+ attr_accessor :performed_file, :compressed_file, :encrypted_file, :final_file
17
19
 
20
+ # Initializes the Backup Process
21
+ #
22
+ # This will first load in any prefixed settings from the Backup::Adapters::Base
23
+ # Then it will add it's own settings.
24
+ #
25
+ # First it will call the 'perform' method. This method is concerned with the backup, and must
26
+ # be implemented by derived classes!
27
+ # Then it will optionally encrypt the backed up file
28
+ # Then it will store it to the specified storage location
29
+ # Then it will record the data to the database
30
+ # Once this is all done, all the temporary files will be removed
31
+ #
32
+ # Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
18
33
  def initialize(trigger, procedure)
19
34
  self.trigger = trigger
20
35
  self.procedure = procedure
@@ -22,54 +37,58 @@ module Backup
22
37
  self.tmp_path = File.join(BACKUP_PATH.gsub(' ', '\ '), 'tmp', 'backup', trigger)
23
38
  self.encrypt_with_password = procedure.attributes['encrypt_with_password']
24
39
  self.keep_backups = procedure.attributes['keep_backups']
25
- create_tmp_folder
40
+
41
+ self.performed_file = "#{timestamp}.#{trigger.gsub(' ', '-')}#{performed_file_extension}"
42
+ self.compressed_file = "#{performed_file}.gz"
43
+ self.encrypted_file = "#{compressed_file}.enc"
44
+ self.final_file = compressed_file
45
+
46
+ begin
47
+ create_tmp_folder
48
+ load_settings # if respond_to?(:load_settings)
49
+ perform
50
+ encrypt
51
+ store
52
+ record
53
+ notify
54
+ ensure
55
+ remove_tmp_files
56
+ end
26
57
  end
27
58
 
28
59
  # Creates the temporary folder for the specified adapter
29
60
  def create_tmp_folder
30
- %x{ mkdir -p #{tmp_path} }
61
+ run "mkdir -p #{tmp_path}"
62
+ end
63
+
64
+ # TODO make methods in derived classes public? respond_to cannot identify private methods
65
+ def load_settings
31
66
  end
32
67
 
33
68
  # Removes the files inside the temporary folder
34
69
  def remove_tmp_files
35
- %x{ rm #{File.join(tmp_path, '*')} }
70
+ run "rm #{File.join(tmp_path, '*')}"
36
71
  end
37
72
 
38
- # Initializes the storing process depending on the store settings
39
- # Options:
40
- # Amazon (S3)
41
- # Remote Server (SCP)
42
- # Remote Server (FTP)
43
- # Remote Server (SFTP)
44
- def store
45
- case procedure.storage_name.to_sym
46
- when :s3 then Backup::Storage::S3.new(self)
47
- when :scp then Backup::Storage::SCP.new(self)
48
- when :ftp then Backup::Storage::FTP.new(self)
49
- when :sftp then Backup::Storage::SFTP.new(self)
73
+ # Encrypts the archive file
74
+ def encrypt
75
+ if encrypt_with_password.is_a?(String)
76
+ log system_messages[:encrypting]
77
+ run "openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password}"
78
+ self.final_file = encrypted_file
50
79
  end
51
80
  end
52
81
 
82
+ # Initializes the storing process
83
+ def store
84
+ procedure.initialize_storage(self)
85
+ end
86
+
53
87
  # Records data on every individual file to the database
54
88
  def record
55
- case procedure.storage_name.to_sym
56
- when :s3
57
- record = Backup::Record::S3.new
58
- record.load_adapter(self)
59
- record.save
60
- when :scp
61
- record = Backup::Record::SCP.new
62
- record.load_adapter(self)
63
- record.save
64
- when :ftp
65
- record = Backup::Record::FTP.new
66
- record.load_adapter(self)
67
- record.save
68
- when :sftp
69
- record = Backup::Record::SFTP.new
70
- record.load_adapter(self)
71
- record.save
72
- end
89
+ record = procedure.initialize_record
90
+ record.load_adapter(self)
91
+ record.save
73
92
  end
74
93
 
75
94
  # Delivers a notification by email regarding the successfully stored backup
@@ -85,9 +104,10 @@ module Backup
85
104
  :encrypting => "Encrypting backup..",
86
105
  :mysqldump => "Creating MySQL dump..",
87
106
  :pgdump => "Creating PostgreSQL dump..",
107
+ :sqlite => "Copying and compressing SQLite database..",
88
108
  :commands => "Executing commands.." }
89
109
  end
90
110
 
91
111
  end
92
112
  end
93
- end
113
+ end