backup 3.0.19 → 3.0.20
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.
- data/.gitignore +4 -0
- data/Gemfile +9 -8
- data/Gemfile.lock +19 -1
- data/Guardfile +13 -9
- data/README.md +93 -31
- data/backup.gemspec +3 -3
- data/bin/backup +6 -283
- data/lib/backup.rb +101 -72
- data/lib/backup/archive.rb +21 -9
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/cleaner.rb +36 -0
- data/lib/backup/cli/helpers.rb +103 -0
- data/lib/backup/cli/utility.rb +308 -0
- data/lib/backup/compressor/base.rb +2 -2
- data/lib/backup/compressor/pbzip2.rb +76 -0
- data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
- data/lib/backup/configuration/database/riak.rb +25 -0
- data/lib/backup/configuration/encryptor/open_ssl.rb +6 -0
- data/lib/backup/configuration/helpers.rb +5 -18
- data/lib/backup/configuration/notifier/base.rb +13 -0
- data/lib/backup/configuration/notifier/hipchat.rb +41 -0
- data/lib/backup/configuration/notifier/mail.rb +38 -0
- data/lib/backup/configuration/notifier/prowl.rb +23 -0
- data/lib/backup/configuration/storage/cloudfiles.rb +4 -0
- data/lib/backup/configuration/storage/dropbox.rb +8 -4
- data/lib/backup/database/base.rb +10 -2
- data/lib/backup/database/mongodb.rb +16 -19
- data/lib/backup/database/mysql.rb +2 -2
- data/lib/backup/database/postgresql.rb +2 -2
- data/lib/backup/database/redis.rb +15 -7
- data/lib/backup/database/riak.rb +45 -0
- data/lib/backup/dependency.rb +21 -7
- data/lib/backup/encryptor/base.rb +1 -1
- data/lib/backup/encryptor/open_ssl.rb +20 -5
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/finder.rb +11 -3
- data/lib/backup/logger.rb +121 -82
- data/lib/backup/model.rb +103 -44
- data/lib/backup/notifier/base.rb +50 -0
- data/lib/backup/notifier/campfire.rb +32 -52
- data/lib/backup/notifier/hipchat.rb +99 -0
- data/lib/backup/notifier/mail.rb +100 -61
- data/lib/backup/notifier/presently.rb +31 -40
- data/lib/backup/notifier/prowl.rb +73 -0
- data/lib/backup/notifier/twitter.rb +29 -39
- data/lib/backup/packager.rb +25 -0
- data/lib/backup/splitter.rb +62 -0
- data/lib/backup/storage/base.rb +178 -18
- data/lib/backup/storage/cloudfiles.rb +34 -28
- data/lib/backup/storage/dropbox.rb +64 -67
- data/lib/backup/storage/ftp.rb +48 -40
- data/lib/backup/storage/local.rb +33 -28
- data/lib/backup/storage/ninefold.rb +40 -26
- data/lib/backup/storage/object.rb +8 -6
- data/lib/backup/storage/rsync.rb +61 -51
- data/lib/backup/storage/s3.rb +29 -27
- data/lib/backup/storage/scp.rb +56 -36
- data/lib/backup/storage/sftp.rb +49 -33
- data/lib/backup/syncer/base.rb +1 -1
- data/lib/backup/syncer/rsync.rb +1 -1
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +1 -1
- data/spec/archive_spec.rb +34 -9
- data/spec/backup_spec.rb +1 -1
- data/spec/cli/helpers_spec.rb +35 -0
- data/spec/cli/utility_spec.rb +38 -0
- data/spec/compressor/bzip2_spec.rb +1 -1
- data/spec/compressor/gzip_spec.rb +1 -1
- data/spec/compressor/lzma_spec.rb +1 -1
- data/spec/compressor/pbzip2_spec.rb +63 -0
- data/spec/configuration/base_spec.rb +1 -1
- data/spec/configuration/compressor/bzip2_spec.rb +1 -1
- data/spec/configuration/compressor/gzip_spec.rb +1 -1
- data/spec/configuration/compressor/lzma_spec.rb +1 -1
- data/spec/configuration/database/base_spec.rb +1 -1
- data/spec/configuration/database/mongodb_spec.rb +1 -1
- data/spec/configuration/database/mysql_spec.rb +1 -1
- data/spec/configuration/database/postgresql_spec.rb +1 -1
- data/spec/configuration/database/redis_spec.rb +1 -1
- data/spec/configuration/database/riak_spec.rb +31 -0
- data/spec/configuration/encryptor/gpg_spec.rb +1 -1
- data/spec/configuration/encryptor/open_ssl_spec.rb +4 -1
- data/spec/configuration/notifier/campfire_spec.rb +1 -1
- data/spec/configuration/notifier/hipchat_spec.rb +43 -0
- data/spec/configuration/notifier/mail_spec.rb +34 -22
- data/spec/configuration/notifier/presently_spec.rb +1 -1
- data/spec/configuration/notifier/prowl_spec.rb +28 -0
- data/spec/configuration/notifier/twitter_spec.rb +1 -1
- data/spec/configuration/storage/cloudfiles_spec.rb +19 -16
- data/spec/configuration/storage/dropbox_spec.rb +1 -1
- data/spec/configuration/storage/ftp_spec.rb +1 -1
- data/spec/configuration/storage/local_spec.rb +1 -1
- data/spec/configuration/storage/ninefold_spec.rb +1 -1
- data/spec/configuration/storage/rsync_spec.rb +1 -1
- data/spec/configuration/storage/s3_spec.rb +1 -1
- data/spec/configuration/storage/scp_spec.rb +1 -1
- data/spec/configuration/storage/sftp_spec.rb +1 -1
- data/spec/configuration/syncer/rsync_spec.rb +1 -1
- data/spec/configuration/syncer/s3_spec.rb +1 -1
- data/spec/database/base_spec.rb +10 -1
- data/spec/database/mongodb_spec.rb +34 -7
- data/spec/database/mysql_spec.rb +8 -7
- data/spec/database/postgresql_spec.rb +8 -7
- data/spec/database/redis_spec.rb +39 -9
- data/spec/database/riak_spec.rb +50 -0
- data/spec/encryptor/gpg_spec.rb +1 -1
- data/spec/encryptor/open_ssl_spec.rb +77 -20
- data/spec/errors_spec.rb +306 -0
- data/spec/finder_spec.rb +91 -0
- data/spec/logger_spec.rb +254 -33
- data/spec/model_spec.rb +120 -15
- data/spec/notifier/campfire_spec.rb +127 -52
- data/spec/notifier/hipchat_spec.rb +193 -0
- data/spec/notifier/mail_spec.rb +290 -74
- data/spec/notifier/presently_spec.rb +290 -73
- data/spec/notifier/prowl_spec.rb +149 -0
- data/spec/notifier/twitter_spec.rb +106 -41
- data/spec/spec_helper.rb +8 -2
- data/spec/splitter_spec.rb +71 -0
- data/spec/storage/base_spec.rb +280 -19
- data/spec/storage/cloudfiles_spec.rb +38 -22
- data/spec/storage/dropbox_spec.rb +17 -13
- data/spec/storage/ftp_spec.rb +145 -55
- data/spec/storage/local_spec.rb +6 -6
- data/spec/storage/ninefold_spec.rb +70 -29
- data/spec/storage/object_spec.rb +44 -44
- data/spec/storage/rsync_spec.rb +186 -63
- data/spec/storage/s3_spec.rb +23 -24
- data/spec/storage/scp_spec.rb +116 -41
- data/spec/storage/sftp_spec.rb +124 -46
- data/spec/syncer/rsync_spec.rb +3 -3
- data/spec/syncer/s3_spec.rb +1 -1
- data/spec/version_spec.rb +1 -1
- data/templates/cli/utility/archive +13 -0
- data/{lib/templates → templates/cli/utility}/compressor/bzip2 +1 -1
- data/{lib/templates → templates/cli/utility}/compressor/gzip +1 -1
- data/{lib/templates → templates/cli/utility}/compressor/lzma +0 -0
- data/templates/cli/utility/compressor/pbzip2 +7 -0
- data/templates/cli/utility/config +31 -0
- data/{lib/templates → templates/cli/utility}/database/mongodb +1 -1
- data/{lib/templates → templates/cli/utility}/database/mysql +1 -1
- data/{lib/templates → templates/cli/utility}/database/postgresql +1 -1
- data/{lib/templates → templates/cli/utility}/database/redis +1 -1
- data/templates/cli/utility/database/riak +8 -0
- data/{lib/templates → templates/cli/utility}/encryptor/gpg +1 -1
- data/templates/cli/utility/encryptor/openssl +9 -0
- data/templates/cli/utility/model.erb +23 -0
- data/{lib/templates → templates/cli/utility}/notifier/campfire +2 -1
- data/templates/cli/utility/notifier/hipchat +15 -0
- data/{lib/templates → templates/cli/utility}/notifier/mail +6 -1
- data/{lib/templates → templates/cli/utility}/notifier/presently +1 -0
- data/templates/cli/utility/notifier/prowl +11 -0
- data/{lib/templates → templates/cli/utility}/notifier/twitter +2 -1
- data/templates/cli/utility/splitter +7 -0
- data/templates/cli/utility/storage/cloudfiles +12 -0
- data/{lib/templates → templates/cli/utility}/storage/dropbox +1 -1
- data/{lib/templates → templates/cli/utility}/storage/ftp +0 -0
- data/templates/cli/utility/storage/local +7 -0
- data/{lib/templates → templates/cli/utility}/storage/ninefold +1 -1
- data/templates/cli/utility/storage/rsync +11 -0
- data/{lib/templates → templates/cli/utility}/storage/s3 +0 -2
- data/templates/cli/utility/storage/scp +11 -0
- data/templates/cli/utility/storage/sftp +11 -0
- data/{lib/templates → templates/cli/utility}/syncer/rsync +1 -1
- data/{lib/templates → templates/cli/utility}/syncer/s3 +1 -1
- data/templates/general/links +11 -0
- data/templates/general/version.erb +2 -0
- data/templates/notifier/mail/failure.erb +9 -0
- data/templates/notifier/mail/success.erb +7 -0
- data/templates/notifier/mail/warning.erb +9 -0
- data/templates/storage/dropbox/authorization_url.erb +6 -0
- data/templates/storage/dropbox/authorized.erb +4 -0
- data/templates/storage/dropbox/cache_file_written.erb +10 -0
- metadata +81 -45
- data/lib/backup/cli.rb +0 -110
- data/lib/backup/exception/command_failed.rb +0 -8
- data/lib/backup/exception/command_not_found.rb +0 -8
- data/lib/backup/notifier/binder.rb +0 -32
- data/lib/backup/notifier/templates/notify_failure.erb +0 -33
- data/lib/backup/notifier/templates/notify_success.erb +0 -16
- data/lib/templates/archive +0 -7
- data/lib/templates/encryptor/openssl +0 -8
- data/lib/templates/readme +0 -15
- data/lib/templates/storage/cloudfiles +0 -11
- data/lib/templates/storage/local +0 -7
- data/lib/templates/storage/rsync +0 -11
- data/lib/templates/storage/scp +0 -11
- data/lib/templates/storage/sftp +0 -11
data/lib/backup/model.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Backup
|
|
4
4
|
class Model
|
|
5
|
-
include Backup::CLI
|
|
5
|
+
include Backup::CLI::Helpers
|
|
6
6
|
|
|
7
7
|
##
|
|
8
8
|
# The trigger is used as an identifier for
|
|
@@ -41,6 +41,10 @@ module Backup
|
|
|
41
41
|
# The syncers attribute holds an array of syncer objects
|
|
42
42
|
attr_accessor :syncers
|
|
43
43
|
|
|
44
|
+
##
|
|
45
|
+
# The chunk_size attribute holds the size of the chunks in megabytes
|
|
46
|
+
attr_accessor :chunk_size
|
|
47
|
+
|
|
44
48
|
##
|
|
45
49
|
# The time when the backup initiated (in format: 2011.02.20.03.29.59)
|
|
46
50
|
attr_accessor :time
|
|
@@ -63,6 +67,10 @@ module Backup
|
|
|
63
67
|
# Use Backup::Model.current to retrieve the actual data of the model
|
|
64
68
|
attr_accessor :current
|
|
65
69
|
|
|
70
|
+
##
|
|
71
|
+
# Contains an array of chunk suffixes for a given file
|
|
72
|
+
attr_accessor :chunk_suffixes
|
|
73
|
+
|
|
66
74
|
##
|
|
67
75
|
# Returns the full path to the current file (including the current extension).
|
|
68
76
|
# To just return the filename and extension without the path, use File.basename(Backup::Model.file)
|
|
@@ -70,6 +78,12 @@ module Backup
|
|
|
70
78
|
File.join(TMP_PATH, "#{ TIME }.#{ TRIGGER }.#{ Backup::Model.extension }")
|
|
71
79
|
end
|
|
72
80
|
|
|
81
|
+
##
|
|
82
|
+
# Returns the @chunk_suffixes variable, sets it to an emtpy array if nil
|
|
83
|
+
def chunk_suffixes
|
|
84
|
+
@chunk_suffixes ||= Array.new
|
|
85
|
+
end
|
|
86
|
+
|
|
73
87
|
##
|
|
74
88
|
# Returns the temporary trigger path of the current model
|
|
75
89
|
# e.g. /Users/Michael/tmp/backup/my_trigger
|
|
@@ -99,13 +113,9 @@ module Backup
|
|
|
99
113
|
@label = label
|
|
100
114
|
@time = TIME
|
|
101
115
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
@compressors = Array.new
|
|
106
|
-
@storages = Array.new
|
|
107
|
-
@notifiers = Array.new
|
|
108
|
-
@syncers = Array.new
|
|
116
|
+
procedure_instance_variables.each do |variable|
|
|
117
|
+
instance_variable_set(variable, Array.new)
|
|
118
|
+
end
|
|
109
119
|
|
|
110
120
|
instance_eval(&block)
|
|
111
121
|
Backup::Model.all << self
|
|
@@ -157,10 +167,10 @@ module Backup
|
|
|
157
167
|
##
|
|
158
168
|
# Adds a storage method to the array of storage
|
|
159
169
|
# methods to use during the backup process
|
|
160
|
-
def store_with(storage, &block)
|
|
170
|
+
def store_with(storage, storage_id = nil, &block)
|
|
161
171
|
@storages << Backup::Storage.const_get(
|
|
162
172
|
last_constant(storage)
|
|
163
|
-
).new(&block)
|
|
173
|
+
).new(storage_id, &block)
|
|
164
174
|
end
|
|
165
175
|
|
|
166
176
|
##
|
|
@@ -172,6 +182,20 @@ module Backup
|
|
|
172
182
|
).new(&block)
|
|
173
183
|
end
|
|
174
184
|
|
|
185
|
+
##
|
|
186
|
+
# Adds a method that allows the user to set the @chunk_size.
|
|
187
|
+
# The chunk_size (in megabytes) will later determine in how many chunks the
|
|
188
|
+
# backup needs to be split
|
|
189
|
+
def split_into_chunks_of(chunk_size = nil)
|
|
190
|
+
@chunk_size = chunk_size
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
##
|
|
194
|
+
# Returns the path to the current file (including proper extension)
|
|
195
|
+
def file
|
|
196
|
+
Backup::Model.file
|
|
197
|
+
end
|
|
198
|
+
|
|
175
199
|
##
|
|
176
200
|
# Performs the backup process
|
|
177
201
|
##
|
|
@@ -182,7 +206,7 @@ module Backup
|
|
|
182
206
|
# Runs all (if any) archive objects to package all their
|
|
183
207
|
# paths in to a single tar file and places it in the backup folder
|
|
184
208
|
##
|
|
185
|
-
# [
|
|
209
|
+
# [Packaging]
|
|
186
210
|
# After all the database dumps and archives are placed inside
|
|
187
211
|
# the folder, it'll make a single .tar package (archive) out of it
|
|
188
212
|
##
|
|
@@ -192,6 +216,9 @@ module Backup
|
|
|
192
216
|
# [Compression]
|
|
193
217
|
# Optionally compresses the packaged file with one or more compressors
|
|
194
218
|
##
|
|
219
|
+
# [Splitting]
|
|
220
|
+
# Optionally splits the backup file in to multiple smaller chunks before transferring them
|
|
221
|
+
##
|
|
195
222
|
# [Storages]
|
|
196
223
|
# Runs all (if any) storage objects to store the backups to remote locations
|
|
197
224
|
# and (if configured) it'll cycle the files on the remote location to limit the
|
|
@@ -212,24 +239,49 @@ module Backup
|
|
|
212
239
|
# breaks the process, it'll always ensure it removes the temporary files regardless
|
|
213
240
|
# to avoid mass consumption of storage space on the machine
|
|
214
241
|
def perform!
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
package!
|
|
220
|
-
compressors.each { |c| c.perform! }
|
|
221
|
-
encryptors.each { |e| e.perform! }
|
|
222
|
-
storages.each { |s| s.perform! }
|
|
223
|
-
clean!
|
|
242
|
+
if databases.any? or archives.any?
|
|
243
|
+
procedures.each do |procedure|
|
|
244
|
+
(procedure.call; next) if procedure.is_a?(Proc)
|
|
245
|
+
procedure.each(&:perform!)
|
|
224
246
|
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
syncers.each(&:perform!)
|
|
250
|
+
notifiers.each { |n| n.perform!(self) }
|
|
251
|
+
|
|
252
|
+
rescue Exception => err
|
|
253
|
+
fatal = !err.is_a?(StandardError)
|
|
254
|
+
|
|
255
|
+
Logger.error Backup::Errors::ModelError.wrap(err, <<-EOS)
|
|
256
|
+
Backup for #{label} (#{trigger}) Failed!
|
|
257
|
+
An Error occured which has caused this Backup to abort before completion.
|
|
258
|
+
Please review the Log for this Backup to determine if steps need to be taken
|
|
259
|
+
to clean up, based on the point at which the failure occured.
|
|
260
|
+
EOS
|
|
261
|
+
Logger.error "\nBacktrace:\n" + err.backtrace.join("\n\s\s") + "\n\n"
|
|
262
|
+
|
|
263
|
+
if fatal
|
|
264
|
+
Logger.error Backup::Errors::ModelError.new(<<-EOS)
|
|
265
|
+
This Error was Fatal and Backup will now exit.
|
|
266
|
+
If you have other Backup jobs (triggers) configured to run,
|
|
267
|
+
they will not be processed.
|
|
268
|
+
EOS
|
|
269
|
+
else
|
|
270
|
+
Logger.message Backup::Errors::ModelError.new(<<-EOS)
|
|
271
|
+
If you have other Backup jobs (triggers) configured to run,
|
|
272
|
+
Backup will now attempt to continue...
|
|
273
|
+
EOS
|
|
274
|
+
end
|
|
225
275
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
notifiers.each { |n| n.perform!(self, exception) }
|
|
231
|
-
show_exception!(exception)
|
|
276
|
+
notifiers.each do |n|
|
|
277
|
+
begin
|
|
278
|
+
n.perform!(self, err)
|
|
279
|
+
rescue Exception; end
|
|
232
280
|
end
|
|
281
|
+
|
|
282
|
+
exit(1) if fatal
|
|
283
|
+
ensure
|
|
284
|
+
clean!
|
|
233
285
|
end
|
|
234
286
|
|
|
235
287
|
private
|
|
@@ -239,35 +291,42 @@ module Backup
|
|
|
239
291
|
# these files will be bundled in to a .tar archive (uncompressed) so it
|
|
240
292
|
# becomes a single (transferrable) packaged file.
|
|
241
293
|
def package!
|
|
242
|
-
|
|
243
|
-
|
|
294
|
+
Backup::Packager.new(self).package!
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
##
|
|
298
|
+
# Create a new instance of Backup::Splitter,
|
|
299
|
+
# passing it the current model instance and runs it.
|
|
300
|
+
def split!
|
|
301
|
+
Backup::Splitter.new(self).split!
|
|
244
302
|
end
|
|
245
303
|
|
|
246
304
|
##
|
|
247
305
|
# Cleans up the temporary files that were created after the backup process finishes
|
|
248
306
|
def clean!
|
|
249
|
-
|
|
250
|
-
run("#{ utility(:rm) } -rf '#{ File.join(TMP_PATH, TRIGGER) }' '#{ File.join(TMP_PATH, "#{TIME}.#{TRIGGER}.#{Backup::Model.extension}") }'")
|
|
307
|
+
Backup::Cleaner.new(self).clean!
|
|
251
308
|
end
|
|
252
309
|
|
|
253
310
|
##
|
|
254
|
-
# Returns
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
311
|
+
# Returns an array of procedures
|
|
312
|
+
def procedures
|
|
313
|
+
Array.new([
|
|
314
|
+
databases, archives, lambda { package! }, compressors,
|
|
315
|
+
encryptors, lambda { split! }, storages
|
|
316
|
+
])
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
##
|
|
320
|
+
# Returns an Array of the names (String) of the procedure instance variables
|
|
321
|
+
def procedure_instance_variables
|
|
322
|
+
[:@databases, :@archives, :@encryptors, :@compressors, :@storages, :@notifiers, :@syncers]
|
|
261
323
|
end
|
|
262
324
|
|
|
263
325
|
##
|
|
264
|
-
#
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
Logger.normal "If you've setup a \"Notification\" in your configuration file, the above error will have been sent."
|
|
269
|
-
#Notifies the shell an exception occured.
|
|
270
|
-
exit 1
|
|
326
|
+
# Returns the string representation of the last value of a nested constant
|
|
327
|
+
# example: last_constant(Backup::Model::MySQL) becomes and returns "MySQL"
|
|
328
|
+
def last_constant(constant)
|
|
329
|
+
constant.to_s.split("::").last
|
|
271
330
|
end
|
|
272
331
|
|
|
273
332
|
end
|
data/lib/backup/notifier/base.rb
CHANGED
|
@@ -5,18 +5,68 @@ module Backup
|
|
|
5
5
|
class Base
|
|
6
6
|
include Backup::Configuration::Helpers
|
|
7
7
|
|
|
8
|
+
##
|
|
9
|
+
# Container for the Model object
|
|
10
|
+
attr_accessor :model
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Contains the Backup::Template object
|
|
14
|
+
attr_accessor :template
|
|
15
|
+
|
|
8
16
|
##
|
|
9
17
|
# When set to true, the user will be notified by email
|
|
10
18
|
# when a backup process ends without raising any exceptions
|
|
11
19
|
attr_accessor :on_success
|
|
12
20
|
alias :notify_on_success? :on_success
|
|
13
21
|
|
|
22
|
+
##
|
|
23
|
+
# When set to true, the user will be notified by email
|
|
24
|
+
# when a backup process is successful, but has warnings
|
|
25
|
+
attr_accessor :on_warning
|
|
26
|
+
alias :notify_on_warning? :on_warning
|
|
27
|
+
|
|
14
28
|
##
|
|
15
29
|
# When set to true, the user will be notified by email
|
|
16
30
|
# when a backup process raises an exception before finishing
|
|
17
31
|
attr_accessor :on_failure
|
|
18
32
|
alias :notify_on_failure? :on_failure
|
|
19
33
|
|
|
34
|
+
##
|
|
35
|
+
# Super method #initialize for all child classes
|
|
36
|
+
def initialize(&block)
|
|
37
|
+
load_defaults!
|
|
38
|
+
|
|
39
|
+
instance_eval(&block) if block_given?
|
|
40
|
+
|
|
41
|
+
set_defaults!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# Performs the notification
|
|
46
|
+
# Takes an exception object that might've been created if an exception occurred.
|
|
47
|
+
# If this is the case it'll invoke notify_failure!(exception), otherwise, if no
|
|
48
|
+
# error was raised, it'll go ahead and notify_success!
|
|
49
|
+
#
|
|
50
|
+
# If'll only perform these if on_success is true or on_failure is true
|
|
51
|
+
def perform!(model, exception = false)
|
|
52
|
+
@model = model
|
|
53
|
+
@template = Backup::Template.new({:model => model, :exception => exception})
|
|
54
|
+
|
|
55
|
+
action = false
|
|
56
|
+
if exception.eql?(false)
|
|
57
|
+
if notify_on_success? || (notify_on_warning? && Logger.has_warnings?)
|
|
58
|
+
action = Logger.has_warnings? ? :warning : :success
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
action = :failure if notify_on_failure?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
if action
|
|
65
|
+
log!
|
|
66
|
+
notify!(action)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
20
70
|
##
|
|
21
71
|
# Logs a message to the console and log file to inform
|
|
22
72
|
# the client that Backup is notifying about the process
|
|
@@ -30,75 +30,55 @@ module Backup
|
|
|
30
30
|
# Campfire account's room id
|
|
31
31
|
attr_accessor :room_id
|
|
32
32
|
|
|
33
|
-
##
|
|
34
|
-
# Container for the Model object
|
|
35
|
-
attr_accessor :model
|
|
36
|
-
|
|
37
|
-
##
|
|
38
|
-
# Instantiates a new Backup::Notifier::Campfire object
|
|
39
|
-
def initialize(&block)
|
|
40
|
-
load_defaults!
|
|
41
|
-
|
|
42
|
-
instance_eval(&block) if block_given?
|
|
43
|
-
|
|
44
|
-
set_defaults!
|
|
45
|
-
end
|
|
46
|
-
|
|
47
33
|
##
|
|
48
34
|
# Performs the notification
|
|
49
|
-
#
|
|
50
|
-
# If
|
|
51
|
-
# error was raised, it'll go ahead and notify_success!
|
|
52
|
-
#
|
|
53
|
-
# If'll only perform these if on_success is true or on_failure is true
|
|
35
|
+
# Extends from super class. Must call super(model, exception).
|
|
36
|
+
# If any pre-configuration needs to be done, put it above the super(model, exception)
|
|
54
37
|
def perform!(model, exception = false)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if notify_on_success? and exception.eql?(false)
|
|
58
|
-
log!
|
|
59
|
-
notify_success!
|
|
60
|
-
elsif notify_on_failure? and not exception.eql?(false)
|
|
61
|
-
log!
|
|
62
|
-
notify_failure!(exception)
|
|
63
|
-
end
|
|
38
|
+
super(model, exception)
|
|
64
39
|
end
|
|
65
40
|
|
|
66
41
|
private
|
|
67
42
|
|
|
68
43
|
##
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
44
|
+
# Notify the user of the backup operation results.
|
|
45
|
+
# `status` indicates one of the following:
|
|
46
|
+
#
|
|
47
|
+
# `:success`
|
|
48
|
+
# : The backup completed successfully.
|
|
49
|
+
# : Notification will be sent if `on_success` was set to `true`
|
|
50
|
+
#
|
|
51
|
+
# `:warning`
|
|
52
|
+
# : The backup completed successfully, but warnings were logged
|
|
53
|
+
# : Notification will be sent, including a copy of the current
|
|
54
|
+
# : backup log, if `on_warning` was set to `true`
|
|
55
|
+
#
|
|
56
|
+
# `:failure`
|
|
57
|
+
# : The backup operation failed.
|
|
58
|
+
# : Notification will be sent, including the Exception which caused
|
|
59
|
+
# : the failure, the Exception's backtrace, a copy of the current
|
|
60
|
+
# : backup log and other information if `on_failure` was set to `true`
|
|
61
|
+
#
|
|
62
|
+
def notify!(status)
|
|
63
|
+
name = case status
|
|
64
|
+
when :success then 'Success'
|
|
65
|
+
when :warning then 'Warning'
|
|
66
|
+
when :failure then 'Failure'
|
|
67
|
+
end
|
|
68
|
+
message = "[Backup::%s] #{model.label} (#{model.trigger})" % name
|
|
69
|
+
send_message(message)
|
|
80
70
|
end
|
|
81
71
|
|
|
82
72
|
##
|
|
83
|
-
#
|
|
84
|
-
def set_defaults
|
|
85
|
-
@campfire_client = {
|
|
86
|
-
:api_token => @api_token,
|
|
87
|
-
:subdomain => @subdomain,
|
|
88
|
-
:room_id => @room_id
|
|
89
|
-
}
|
|
90
|
-
end
|
|
73
|
+
# nothing to do
|
|
74
|
+
def set_defaults!; end
|
|
91
75
|
|
|
92
76
|
##
|
|
93
77
|
# Creates a new Campfire::Interface object and passes in the
|
|
94
78
|
# campfire clients "room_id", "subdomain" and "api_token". Using this object
|
|
95
79
|
# the provided "message" will be sent to the desired Campfire chat room
|
|
96
80
|
def send_message(message)
|
|
97
|
-
room = Interface.room(
|
|
98
|
-
@campfire_client[:room_id],
|
|
99
|
-
@campfire_client[:subdomain],
|
|
100
|
-
@campfire_client[:api_token]
|
|
101
|
-
)
|
|
81
|
+
room = Interface.room(room_id, subdomain, api_token)
|
|
102
82
|
room.message(message)
|
|
103
83
|
end
|
|
104
84
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
if RUBY_VERSION < '1.9.0'
|
|
4
|
+
Backup::Dependency.load('json')
|
|
5
|
+
else
|
|
6
|
+
require 'json'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Load HTTParty
|
|
10
|
+
Backup::Dependency.load('hipchat')
|
|
11
|
+
|
|
12
|
+
module Backup
|
|
13
|
+
module Notifier
|
|
14
|
+
class Hipchat < Base
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# The Hipchat API token
|
|
18
|
+
attr_accessor :token
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Who the notification should appear from
|
|
22
|
+
attr_accessor :from
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# The rooms that should be notified
|
|
26
|
+
attr_accessor :rooms_notified
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# The background color of a success message. One of :yellow, :red, :green, :purple, or :random. (default: yellow)
|
|
30
|
+
attr_accessor :success_color
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# The background color of a warning message. One of :yellow, :red, :green, :purple, or :random. (default: yellow)
|
|
34
|
+
attr_accessor :warning_color
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# The background color of an error message. One of :yellow, :red, :green, :purple, or :random. (default: yellow)
|
|
38
|
+
attr_accessor :failure_color
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Notify users in the room
|
|
42
|
+
attr_accessor :notify_users
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# Performs the notification
|
|
46
|
+
# Extends from super class. Must call super(model, exception).
|
|
47
|
+
# If any pre-configuration needs to be done, put it above the super(model, exception)
|
|
48
|
+
def perform!(model, exception = false)
|
|
49
|
+
@rooms_notified = [rooms_notified].flatten
|
|
50
|
+
super(model, exception)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def send_message(msg, color, notify)
|
|
56
|
+
client = HipChat::Client.new(token)
|
|
57
|
+
rooms_notified.each do |room|
|
|
58
|
+
client[room].send(from, msg, :color => color, :notify => notify)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Notify the user of the backup operation results.
|
|
64
|
+
# `status` indicates one of the following:
|
|
65
|
+
#
|
|
66
|
+
# `:success`
|
|
67
|
+
# : The backup completed successfully.
|
|
68
|
+
# : Notification will be sent if `on_success` was set to `true`
|
|
69
|
+
#
|
|
70
|
+
# `:warning`
|
|
71
|
+
# : The backup completed successfully, but warnings were logged
|
|
72
|
+
# : Notification will be sent, including a copy of the current
|
|
73
|
+
# : backup log, if `on_warning` was set to `true`
|
|
74
|
+
#
|
|
75
|
+
# `:failure`
|
|
76
|
+
# : The backup operation failed.
|
|
77
|
+
# : Notification will be sent, including the Exception which caused
|
|
78
|
+
# : the failure, the Exception's backtrace, a copy of the current
|
|
79
|
+
# : backup log and other information if `on_failure` was set to `true`
|
|
80
|
+
#
|
|
81
|
+
def notify!(status)
|
|
82
|
+
name, color = case status
|
|
83
|
+
when :success then ['Success', success_color]
|
|
84
|
+
when :warning then ['Warning', warning_color]
|
|
85
|
+
when :failure then ['Failure', failure_color]
|
|
86
|
+
end
|
|
87
|
+
message = "[Backup::%s] #{model.label} (#{model.trigger})" % name
|
|
88
|
+
send_message(message, color, notify_users)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def set_defaults!
|
|
92
|
+
@success_color ||= 'yellow'
|
|
93
|
+
@warning_color ||= 'yellow'
|
|
94
|
+
@failure_color ||= 'yellow'
|
|
95
|
+
@notify_users ||= false
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|