dmitryv-backup 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/CHANGELOG +125 -0
  2. data/LICENSE +20 -0
  3. data/README.md +180 -0
  4. data/VERSION +1 -0
  5. data/bin/backup +108 -0
  6. data/generators/backup/backup_generator.rb +69 -0
  7. data/generators/backup/templates/backup.rake +56 -0
  8. data/generators/backup/templates/backup.rb +229 -0
  9. data/generators/backup/templates/create_backup_tables.rb +18 -0
  10. data/generators/backup_update/backup_update_generator.rb +50 -0
  11. data/generators/backup_update/templates/migrations/update_backup_tables.rb +27 -0
  12. data/lib/backup.rb +131 -0
  13. data/lib/backup/adapters/archive.rb +34 -0
  14. data/lib/backup/adapters/base.rb +138 -0
  15. data/lib/backup/adapters/custom.rb +41 -0
  16. data/lib/backup/adapters/mysql.rb +60 -0
  17. data/lib/backup/adapters/postgresql.rb +56 -0
  18. data/lib/backup/adapters/sqlite.rb +25 -0
  19. data/lib/backup/command_helper.rb +11 -0
  20. data/lib/backup/compressors/base.rb +7 -0
  21. data/lib/backup/compressors/gzip.rb +9 -0
  22. data/lib/backup/compressors/seven_zip.rb +9 -0
  23. data/lib/backup/configuration/adapter.rb +21 -0
  24. data/lib/backup/configuration/adapter_options.rb +8 -0
  25. data/lib/backup/configuration/attributes.rb +19 -0
  26. data/lib/backup/configuration/base.rb +77 -0
  27. data/lib/backup/configuration/helpers.rb +24 -0
  28. data/lib/backup/configuration/mail.rb +20 -0
  29. data/lib/backup/configuration/smtp.rb +8 -0
  30. data/lib/backup/configuration/storage.rb +8 -0
  31. data/lib/backup/connection/cloudfiles.rb +75 -0
  32. data/lib/backup/connection/s3.rb +85 -0
  33. data/lib/backup/environment/base.rb +12 -0
  34. data/lib/backup/environment/rails_configuration.rb +15 -0
  35. data/lib/backup/environment/unix_configuration.rb +109 -0
  36. data/lib/backup/mail/base.rb +97 -0
  37. data/lib/backup/mail/mail.txt +7 -0
  38. data/lib/backup/record/base.rb +65 -0
  39. data/lib/backup/record/cloudfiles.rb +28 -0
  40. data/lib/backup/record/ftp.rb +39 -0
  41. data/lib/backup/record/local.rb +26 -0
  42. data/lib/backup/record/s3.rb +26 -0
  43. data/lib/backup/record/scp.rb +33 -0
  44. data/lib/backup/record/sftp.rb +38 -0
  45. data/lib/backup/storage/base.rb +10 -0
  46. data/lib/backup/storage/cloudfiles.rb +16 -0
  47. data/lib/backup/storage/ftp.rb +38 -0
  48. data/lib/backup/storage/local.rb +22 -0
  49. data/lib/backup/storage/s3.rb +17 -0
  50. data/lib/backup/storage/scp.rb +30 -0
  51. data/lib/backup/storage/sftp.rb +31 -0
  52. data/lib/generators/backup/USAGE +10 -0
  53. data/lib/generators/backup/backup_generator.rb +47 -0
  54. data/lib/generators/backup/templates/backup.rake +56 -0
  55. data/lib/generators/backup/templates/backup.rb +229 -0
  56. data/lib/generators/backup/templates/create_backup_tables.rb +18 -0
  57. data/setup/backup.rb +231 -0
  58. data/setup/backup.sqlite3 +0 -0
  59. metadata +271 -0
@@ -0,0 +1,56 @@
1
+ namespace :backup do
2
+
3
+ task :boot => :environment do
4
+ Backup::System.boot!
5
+ end
6
+
7
+ desc "Run Backup Procedure."
8
+ task :run => :boot do
9
+ puts "Running: #{ENV['trigger']}."
10
+ Backup::Setup.new(ENV['trigger'], @backup_procedures).initialize_adapter
11
+ end
12
+
13
+ desc "Finds backup records by trigger"
14
+ task :find => :boot do
15
+ puts "Finding backup records with trigger: #{ENV['trigger']}."
16
+ backup = Backup::Setup.new(ENV['trigger'], @backup_procedures)
17
+ records = backup.procedure.record_class.all( :conditions => {:trigger => ENV['trigger']} )
18
+
19
+ if ENV['table'].eql?("true")
20
+ puts Hirb::Helpers::AutoTable.render(records)
21
+ else
22
+ records.each do |record|
23
+ puts record.to_yaml
24
+ end
25
+ end
26
+ end
27
+
28
+ desc "Truncates all records for the specified \"trigger\", excluding the physical files on s3 or the remote server."
29
+ task :truncate => :boot do
30
+ puts "Truncating backup records with trigger: #{ENV['trigger']}."
31
+ Backup::Record::Base.destroy_all :trigger => ENV['trigger']
32
+ end
33
+
34
+ desc "Truncates everything."
35
+ task :truncate_all => :boot do
36
+ puts "Truncating all backup records."
37
+ Backup::Record::Base.destroy_all
38
+ end
39
+
40
+ desc "Destroys all records for the specified \"trigger\", including the physical files on s3 or the remote server."
41
+ task :destroy => :boot do
42
+ puts "Destroying backup records with trigger: #{ENV['trigger']}."
43
+ backup = Backup::Setup.new(ENV['trigger'], @backup_procedures)
44
+ backup.procedure.record_class.destroy_all_backups( backup.procedure, ENV['trigger'] )
45
+ end
46
+
47
+ desc "Destroys all records for the specified \"trigger\", including the physical files on s3 or the remote server."
48
+ task :destroy_all => :boot do
49
+ puts "Destroying all backup records."
50
+ backup = Backup::Setup.new(false, @backup_procedures)
51
+ backup.procedures.each do |backup_procedure|
52
+ backup_procedure.record_class.destroy_all_backups( backup_procedure, backup_procedure.trigger )
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,229 @@
1
+ # Backup Configuration File
2
+ #
3
+ # Use the "backup" block to add backup settings to the configuration file.
4
+ # The argument before the "do" in (backup "argument" do) is called a "trigger".
5
+ # This acts as the identifier for the configuration.
6
+ #
7
+ # In the example below we have a "mysql-backup-s3" trigger for the backup setting.
8
+ # All the configuration is done inside this block. To initialize the backup process for this block,
9
+ # you invoke it using the following rake task:
10
+ #
11
+ # rake backup:run trigger="mysql-backup-s3"
12
+ #
13
+ # You can add as many backup block settings as you want, just be sure every trigger is unique and you can run
14
+ # each of them separately.
15
+ #
16
+ # ADAPTERS
17
+ # - MySQL
18
+ # - PostgreSQL
19
+ # - SQLite
20
+ # - Archive
21
+ # - Custom
22
+ #
23
+ # STORAGE METHODS
24
+ # - S3 (Amazon)
25
+ # - CF (Rackspace Cloud Files)
26
+ # - SCP (Remote Server)
27
+ # - FTP (Remote Server)
28
+ # - SFTP (Remote Server)
29
+ # - LOCAL (Local Server)
30
+ #
31
+ # GLOBAL OPTIONS
32
+ # - Keep Backups (keep_backups)
33
+ # - Encrypt With Pasword (encrypt_with_password)
34
+ # - Encrypt With GPG Public Key (encrypt_with_gpg_public_key)
35
+ # - Notify (notify)
36
+ #
37
+ # This is the "decrypt" command for all encrypted backups:
38
+ # sudo backup --decrypt /path/to/encrypted/file
39
+ #
40
+ # Each Backup Setting can contain:
41
+ # - 1 Adapter
42
+ # - 1 Storage Method
43
+ # - Multiple Global Options
44
+ #
45
+ # The combination of these, however, do not matter! So experiment with it.
46
+ #
47
+ # You can also let Backup notify you by email on successfully created backups.
48
+ # - Just uncomment the block of code below (notifier_settings) and fill in your credentials.
49
+ # - Then for set "notify" to "true" in each (backup) block you wish to be notified of.
50
+ #
51
+ # For more information on "Backup", please refer to the wiki on github
52
+ # http://wiki.github.com/meskyanichi/backup/configuration-file
53
+
54
+
55
+ # Notifier
56
+ # Uncomment this if you want to enable notification by email on successful backup runs
57
+ # You will also have to set "notify true" inside each backup block below to enable it for that particular backup
58
+ # notifier_settings do
59
+ #
60
+ # to "example1@gmail.com"
61
+ # from "example2@gmail.com"
62
+ #
63
+ # smtp do
64
+ # host "smtp.gmail.com"
65
+ # port "587"
66
+ # username "example1@gmail.com"
67
+ # password "example1password"
68
+ # authentication "plain"
69
+ # domain "localhost.localdomain"
70
+ # tls true
71
+ # end
72
+ #
73
+ # end
74
+
75
+
76
+ # Initialize with:
77
+ # rake backup:run trigger='mysql-backup-s3'
78
+ backup 'mysql-backup-s3' do
79
+
80
+ adapter :mysql do
81
+ user 'user'
82
+ password 'password'
83
+ database 'database'
84
+
85
+ # skip_tables ['table1', 'table2', 'table3']
86
+ #
87
+ # options do
88
+ # host '123.45.678.90'
89
+ # port '80'
90
+ # socket '/tmp/socket.sock'
91
+ # end
92
+ # additional_options '--single-transaction --quick'
93
+ end
94
+
95
+ storage :s3 do
96
+ access_key_id 'access_key_id'
97
+ secret_access_key 'secret_access_key'
98
+ bucket '/bucket/backups/mysql/'
99
+ use_ssl true
100
+ end
101
+
102
+ keep_backups 25
103
+ encrypt_with_password 'password'
104
+ notify false
105
+
106
+ end
107
+
108
+ # Initialize with:
109
+ # rake backup:run trigger='mysql-backup-cloudfiles'
110
+ backup 'mysql-backup-cloudfiles' do
111
+
112
+ adapter :mysql do
113
+ user 'user'
114
+ password 'password'
115
+ database 'database'
116
+ end
117
+
118
+ storage :cloudfiles do
119
+ username 'username'
120
+ api_key 'api_key'
121
+ container 'mysql_backup'
122
+ end
123
+
124
+ encrypt_with_gpg_public_key <<-KEY
125
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
126
+ Version: GnuPG v1.4.7 (Darwin)
127
+
128
+ Your very long public key goes here
129
+ -----END PGP PUBLIC KEY BLOCK-----
130
+ KEY
131
+
132
+ end
133
+
134
+ # Initialize with:
135
+ # rake backup:run trigger='postgresql-backup-s3'
136
+ backup 'postgresql-backup-scp' do
137
+
138
+ adapter :postgresql do
139
+ user 'user'
140
+ database 'database'
141
+
142
+ # skip_tables ['table1', 'table2', 'table3']
143
+
144
+ # options do
145
+ # host '123.45.678.90'
146
+ # port '80'
147
+ # socket '/tmp/socket.sock'
148
+ # end
149
+ # additional_options '--clean --blobs'
150
+ end
151
+
152
+ storage :scp do
153
+ ip 'example.com'
154
+ user 'user'
155
+ password 'password'
156
+ path '/var/backups/postgresql/'
157
+ end
158
+
159
+ keep_backups :all
160
+ encrypt_with_password false
161
+ notify false
162
+
163
+ end
164
+
165
+
166
+ # Initialize with:
167
+ # rake backup:run trigger='archive-backup-ftp'
168
+ backup 'archive-backup-ftp' do
169
+
170
+ adapter :archive do
171
+ files ["#{RAILS_ROOT}/log", "#{RAILS_ROOT}/db"]
172
+ end
173
+
174
+ storage :ftp do
175
+ ip 'example.com'
176
+ user 'user'
177
+ password 'password'
178
+ path '/var/backups/archive/'
179
+ end
180
+
181
+ keep_backups 10
182
+ encrypt_with_password false
183
+ notify false
184
+
185
+ end
186
+
187
+
188
+ # Initialize with:
189
+ # rake backup:run trigger='custom-backup-sftp'
190
+ backup 'custom-backup-sftp' do
191
+
192
+ adapter :custom do
193
+ commands \
194
+ [ "mysqldump [options] [database] > :tmp_path/my_mysql_dump.sql",
195
+ "pg_dump [options] [database] > :tmp_path/my_postgresql_dump.sql",
196
+ "any_other_db_format [options] [database] > :tmp_path/my_any_other_db_format.sql" ]
197
+ end
198
+
199
+ storage :sftp do
200
+ ip 'example.com'
201
+ user 'user'
202
+ password 'password'
203
+ path '/var/backups/custom/'
204
+ end
205
+
206
+ keep_backups :all
207
+ encrypt_with_password 'password'
208
+ notify false
209
+
210
+ end
211
+
212
+
213
+ # Initializ with:
214
+ # rake backup:run trigger='sqlite-backup-local'
215
+ backup 'sqlite-backup-local' do
216
+
217
+ adapter :sqlite do
218
+ database "#{RAILS_ROOT}/db/production.sqlite3"
219
+ end
220
+
221
+ storage :local do
222
+ path "/path/to/storage/location/"
223
+ end
224
+
225
+ keep_backups :all
226
+ encrypt_with_password false
227
+ notify false
228
+
229
+ end
@@ -0,0 +1,18 @@
1
+ class CreateBackupTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :backup do |t|
4
+ t.string :trigger
5
+ t.string :adapter
6
+ t.string :filename
7
+ t.string :md5sum
8
+ t.string :path
9
+ t.string :bucket
10
+ t.string :type
11
+ t.timestamps
12
+ end
13
+ end
14
+
15
+ def self.down
16
+ drop_table :backup
17
+ end
18
+ 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
@@ -0,0 +1,131 @@
1
+ BACKUP_SYSTEM = Proc.new do
2
+ # Load Gems
3
+ require 'hirb'
4
+
5
+ # Load Environments
6
+ require 'backup/environment/base'
7
+ require 'backup/environment/unix_configuration'
8
+ require 'backup/environment/rails_configuration'
9
+
10
+ # Load Configuration
11
+ require 'backup/configuration/attributes'
12
+ require 'backup/configuration/base'
13
+ require 'backup/configuration/adapter'
14
+ require 'backup/configuration/adapter_options'
15
+ require 'backup/configuration/storage'
16
+ require 'backup/configuration/mail'
17
+ require 'backup/configuration/smtp'
18
+ require 'backup/configuration/helpers'
19
+
20
+ require 'backup/command_helper'
21
+
22
+ # Include the Configuration and Environment Helpers
23
+ include Backup::Configuration::Helpers
24
+ include Backup::Environment::Base
25
+
26
+ # Load either UNIX or RAILS environment configuration
27
+ case current_environment
28
+ when :unix then include Backup::Environment::UnixConfiguration
29
+ when :rails then include Backup::Environment::RailsConfiguration
30
+ end
31
+
32
+ # Load configuration
33
+ if File.exist?(File.join(BACKUP_PATH, 'config', 'backup.rb'))
34
+ require File.join(BACKUP_PATH, 'config', 'backup.rb')
35
+ end
36
+
37
+ # Load Mail Notifier
38
+ require 'backup/mail/base'
39
+
40
+ # Set Mail Configuration (extracted from the backup.rb configuration file) inside the Mail Class
41
+ Backup::Mail::Base.setup(@mail_configuration)
42
+ end
43
+
44
+ # Backup Module
45
+ module Backup
46
+
47
+ class System
48
+ def self.boot!
49
+ BACKUP_SYSTEM.call
50
+ true
51
+ end
52
+ end
53
+
54
+ module Adapters
55
+ autoload :Base, 'backup/adapters/base'
56
+ autoload :MySQL, 'backup/adapters/mysql'
57
+ autoload :SQLite, 'backup/adapters/sqlite'
58
+ autoload :PostgreSQL, 'backup/adapters/postgresql'
59
+ autoload :Archive, 'backup/adapters/archive'
60
+ autoload :Custom, 'backup/adapters/custom'
61
+ end
62
+
63
+ module Compressors
64
+ autoload :Base, 'backup/compressors/base'
65
+ autoload :Gzip, 'backup/compressors/gzip'
66
+ autoload :SevenZip, 'backup/compressors/seven_zip'
67
+ end
68
+
69
+ module Storage
70
+ autoload :Base, 'backup/storage/base'
71
+ autoload :CloudFiles, 'backup/storage/cloudfiles'
72
+ autoload :S3, 'backup/storage/s3'
73
+ autoload :SCP, 'backup/storage/scp'
74
+ autoload :FTP, 'backup/storage/ftp'
75
+ autoload :SFTP, 'backup/storage/sftp'
76
+ autoload :Local, 'backup/storage/local'
77
+ end
78
+
79
+ module Record
80
+ autoload :Base, 'backup/record/base'
81
+ autoload :CloudFiles, 'backup/record/cloudfiles'
82
+ autoload :S3, 'backup/record/s3'
83
+ autoload :SCP, 'backup/record/scp'
84
+ autoload :FTP, 'backup/record/ftp'
85
+ autoload :SFTP, 'backup/record/sftp'
86
+ autoload :Local, 'backup/record/local'
87
+ end
88
+
89
+ class Setup
90
+
91
+ attr_accessor :trigger, :procedures, :procedure
92
+
93
+ # Sets the Trigger and All Available Procedures.
94
+ # Will not find a specific procedure if the "trigger" argument is set to false.
95
+ def initialize(trigger, procedures)
96
+ self.trigger = trigger
97
+ self.procedures = procedures
98
+ self.procedure = find_triggered_procedure unless trigger.eql?(false)
99
+ end
100
+
101
+ # Initializes one of the few adapters and start the backup process
102
+ def initialize_adapter
103
+ case procedure.adapter_name.to_sym
104
+ when :mysql then Backup::Adapters::MySQL.new trigger, procedure
105
+ when :sqlite then Backup::Adapters::SQLite.new trigger, procedure
106
+ when :postgresql then Backup::Adapters::PostgreSQL.new trigger, procedure
107
+ when :archive then Backup::Adapters::Archive.new trigger, procedure
108
+ when :custom then Backup::Adapters::Custom.new trigger, procedure
109
+ else
110
+ puts "Unknown Adapter: \"#{procedure.adapter_name}\"."
111
+ exit
112
+ end
113
+ end
114
+
115
+ # Scans through all the backup settings and returns the backup setting
116
+ # that was specified in the "trigger" argument.
117
+ # If an non-existing trigger is specified, it will raise an error and display
118
+ # all the available triggers.
119
+ def find_triggered_procedure
120
+ procedures.each do |procedure|
121
+ if procedure.trigger.eql?(trigger)
122
+ return procedure
123
+ end
124
+ end
125
+ available_triggers = procedures.map {|procedure| "- #{procedure.trigger}\n" }
126
+ puts "Could not find a backup procedure with the trigger \"#{trigger}\". \nHere's a list of available triggers:\n#{available_triggers}"
127
+ exit
128
+ end
129
+
130
+ end
131
+ end