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.
Files changed (188) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +9 -8
  3. data/Gemfile.lock +19 -1
  4. data/Guardfile +13 -9
  5. data/README.md +93 -31
  6. data/backup.gemspec +3 -3
  7. data/bin/backup +6 -283
  8. data/lib/backup.rb +101 -72
  9. data/lib/backup/archive.rb +21 -9
  10. data/lib/backup/binder.rb +22 -0
  11. data/lib/backup/cleaner.rb +36 -0
  12. data/lib/backup/cli/helpers.rb +103 -0
  13. data/lib/backup/cli/utility.rb +308 -0
  14. data/lib/backup/compressor/base.rb +2 -2
  15. data/lib/backup/compressor/pbzip2.rb +76 -0
  16. data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
  17. data/lib/backup/configuration/database/riak.rb +25 -0
  18. data/lib/backup/configuration/encryptor/open_ssl.rb +6 -0
  19. data/lib/backup/configuration/helpers.rb +5 -18
  20. data/lib/backup/configuration/notifier/base.rb +13 -0
  21. data/lib/backup/configuration/notifier/hipchat.rb +41 -0
  22. data/lib/backup/configuration/notifier/mail.rb +38 -0
  23. data/lib/backup/configuration/notifier/prowl.rb +23 -0
  24. data/lib/backup/configuration/storage/cloudfiles.rb +4 -0
  25. data/lib/backup/configuration/storage/dropbox.rb +8 -4
  26. data/lib/backup/database/base.rb +10 -2
  27. data/lib/backup/database/mongodb.rb +16 -19
  28. data/lib/backup/database/mysql.rb +2 -2
  29. data/lib/backup/database/postgresql.rb +2 -2
  30. data/lib/backup/database/redis.rb +15 -7
  31. data/lib/backup/database/riak.rb +45 -0
  32. data/lib/backup/dependency.rb +21 -7
  33. data/lib/backup/encryptor/base.rb +1 -1
  34. data/lib/backup/encryptor/open_ssl.rb +20 -5
  35. data/lib/backup/errors.rb +124 -0
  36. data/lib/backup/finder.rb +11 -3
  37. data/lib/backup/logger.rb +121 -82
  38. data/lib/backup/model.rb +103 -44
  39. data/lib/backup/notifier/base.rb +50 -0
  40. data/lib/backup/notifier/campfire.rb +32 -52
  41. data/lib/backup/notifier/hipchat.rb +99 -0
  42. data/lib/backup/notifier/mail.rb +100 -61
  43. data/lib/backup/notifier/presently.rb +31 -40
  44. data/lib/backup/notifier/prowl.rb +73 -0
  45. data/lib/backup/notifier/twitter.rb +29 -39
  46. data/lib/backup/packager.rb +25 -0
  47. data/lib/backup/splitter.rb +62 -0
  48. data/lib/backup/storage/base.rb +178 -18
  49. data/lib/backup/storage/cloudfiles.rb +34 -28
  50. data/lib/backup/storage/dropbox.rb +64 -67
  51. data/lib/backup/storage/ftp.rb +48 -40
  52. data/lib/backup/storage/local.rb +33 -28
  53. data/lib/backup/storage/ninefold.rb +40 -26
  54. data/lib/backup/storage/object.rb +8 -6
  55. data/lib/backup/storage/rsync.rb +61 -51
  56. data/lib/backup/storage/s3.rb +29 -27
  57. data/lib/backup/storage/scp.rb +56 -36
  58. data/lib/backup/storage/sftp.rb +49 -33
  59. data/lib/backup/syncer/base.rb +1 -1
  60. data/lib/backup/syncer/rsync.rb +1 -1
  61. data/lib/backup/template.rb +46 -0
  62. data/lib/backup/version.rb +1 -1
  63. data/spec/archive_spec.rb +34 -9
  64. data/spec/backup_spec.rb +1 -1
  65. data/spec/cli/helpers_spec.rb +35 -0
  66. data/spec/cli/utility_spec.rb +38 -0
  67. data/spec/compressor/bzip2_spec.rb +1 -1
  68. data/spec/compressor/gzip_spec.rb +1 -1
  69. data/spec/compressor/lzma_spec.rb +1 -1
  70. data/spec/compressor/pbzip2_spec.rb +63 -0
  71. data/spec/configuration/base_spec.rb +1 -1
  72. data/spec/configuration/compressor/bzip2_spec.rb +1 -1
  73. data/spec/configuration/compressor/gzip_spec.rb +1 -1
  74. data/spec/configuration/compressor/lzma_spec.rb +1 -1
  75. data/spec/configuration/database/base_spec.rb +1 -1
  76. data/spec/configuration/database/mongodb_spec.rb +1 -1
  77. data/spec/configuration/database/mysql_spec.rb +1 -1
  78. data/spec/configuration/database/postgresql_spec.rb +1 -1
  79. data/spec/configuration/database/redis_spec.rb +1 -1
  80. data/spec/configuration/database/riak_spec.rb +31 -0
  81. data/spec/configuration/encryptor/gpg_spec.rb +1 -1
  82. data/spec/configuration/encryptor/open_ssl_spec.rb +4 -1
  83. data/spec/configuration/notifier/campfire_spec.rb +1 -1
  84. data/spec/configuration/notifier/hipchat_spec.rb +43 -0
  85. data/spec/configuration/notifier/mail_spec.rb +34 -22
  86. data/spec/configuration/notifier/presently_spec.rb +1 -1
  87. data/spec/configuration/notifier/prowl_spec.rb +28 -0
  88. data/spec/configuration/notifier/twitter_spec.rb +1 -1
  89. data/spec/configuration/storage/cloudfiles_spec.rb +19 -16
  90. data/spec/configuration/storage/dropbox_spec.rb +1 -1
  91. data/spec/configuration/storage/ftp_spec.rb +1 -1
  92. data/spec/configuration/storage/local_spec.rb +1 -1
  93. data/spec/configuration/storage/ninefold_spec.rb +1 -1
  94. data/spec/configuration/storage/rsync_spec.rb +1 -1
  95. data/spec/configuration/storage/s3_spec.rb +1 -1
  96. data/spec/configuration/storage/scp_spec.rb +1 -1
  97. data/spec/configuration/storage/sftp_spec.rb +1 -1
  98. data/spec/configuration/syncer/rsync_spec.rb +1 -1
  99. data/spec/configuration/syncer/s3_spec.rb +1 -1
  100. data/spec/database/base_spec.rb +10 -1
  101. data/spec/database/mongodb_spec.rb +34 -7
  102. data/spec/database/mysql_spec.rb +8 -7
  103. data/spec/database/postgresql_spec.rb +8 -7
  104. data/spec/database/redis_spec.rb +39 -9
  105. data/spec/database/riak_spec.rb +50 -0
  106. data/spec/encryptor/gpg_spec.rb +1 -1
  107. data/spec/encryptor/open_ssl_spec.rb +77 -20
  108. data/spec/errors_spec.rb +306 -0
  109. data/spec/finder_spec.rb +91 -0
  110. data/spec/logger_spec.rb +254 -33
  111. data/spec/model_spec.rb +120 -15
  112. data/spec/notifier/campfire_spec.rb +127 -52
  113. data/spec/notifier/hipchat_spec.rb +193 -0
  114. data/spec/notifier/mail_spec.rb +290 -74
  115. data/spec/notifier/presently_spec.rb +290 -73
  116. data/spec/notifier/prowl_spec.rb +149 -0
  117. data/spec/notifier/twitter_spec.rb +106 -41
  118. data/spec/spec_helper.rb +8 -2
  119. data/spec/splitter_spec.rb +71 -0
  120. data/spec/storage/base_spec.rb +280 -19
  121. data/spec/storage/cloudfiles_spec.rb +38 -22
  122. data/spec/storage/dropbox_spec.rb +17 -13
  123. data/spec/storage/ftp_spec.rb +145 -55
  124. data/spec/storage/local_spec.rb +6 -6
  125. data/spec/storage/ninefold_spec.rb +70 -29
  126. data/spec/storage/object_spec.rb +44 -44
  127. data/spec/storage/rsync_spec.rb +186 -63
  128. data/spec/storage/s3_spec.rb +23 -24
  129. data/spec/storage/scp_spec.rb +116 -41
  130. data/spec/storage/sftp_spec.rb +124 -46
  131. data/spec/syncer/rsync_spec.rb +3 -3
  132. data/spec/syncer/s3_spec.rb +1 -1
  133. data/spec/version_spec.rb +1 -1
  134. data/templates/cli/utility/archive +13 -0
  135. data/{lib/templates → templates/cli/utility}/compressor/bzip2 +1 -1
  136. data/{lib/templates → templates/cli/utility}/compressor/gzip +1 -1
  137. data/{lib/templates → templates/cli/utility}/compressor/lzma +0 -0
  138. data/templates/cli/utility/compressor/pbzip2 +7 -0
  139. data/templates/cli/utility/config +31 -0
  140. data/{lib/templates → templates/cli/utility}/database/mongodb +1 -1
  141. data/{lib/templates → templates/cli/utility}/database/mysql +1 -1
  142. data/{lib/templates → templates/cli/utility}/database/postgresql +1 -1
  143. data/{lib/templates → templates/cli/utility}/database/redis +1 -1
  144. data/templates/cli/utility/database/riak +8 -0
  145. data/{lib/templates → templates/cli/utility}/encryptor/gpg +1 -1
  146. data/templates/cli/utility/encryptor/openssl +9 -0
  147. data/templates/cli/utility/model.erb +23 -0
  148. data/{lib/templates → templates/cli/utility}/notifier/campfire +2 -1
  149. data/templates/cli/utility/notifier/hipchat +15 -0
  150. data/{lib/templates → templates/cli/utility}/notifier/mail +6 -1
  151. data/{lib/templates → templates/cli/utility}/notifier/presently +1 -0
  152. data/templates/cli/utility/notifier/prowl +11 -0
  153. data/{lib/templates → templates/cli/utility}/notifier/twitter +2 -1
  154. data/templates/cli/utility/splitter +7 -0
  155. data/templates/cli/utility/storage/cloudfiles +12 -0
  156. data/{lib/templates → templates/cli/utility}/storage/dropbox +1 -1
  157. data/{lib/templates → templates/cli/utility}/storage/ftp +0 -0
  158. data/templates/cli/utility/storage/local +7 -0
  159. data/{lib/templates → templates/cli/utility}/storage/ninefold +1 -1
  160. data/templates/cli/utility/storage/rsync +11 -0
  161. data/{lib/templates → templates/cli/utility}/storage/s3 +0 -2
  162. data/templates/cli/utility/storage/scp +11 -0
  163. data/templates/cli/utility/storage/sftp +11 -0
  164. data/{lib/templates → templates/cli/utility}/syncer/rsync +1 -1
  165. data/{lib/templates → templates/cli/utility}/syncer/s3 +1 -1
  166. data/templates/general/links +11 -0
  167. data/templates/general/version.erb +2 -0
  168. data/templates/notifier/mail/failure.erb +9 -0
  169. data/templates/notifier/mail/success.erb +7 -0
  170. data/templates/notifier/mail/warning.erb +9 -0
  171. data/templates/storage/dropbox/authorization_url.erb +6 -0
  172. data/templates/storage/dropbox/authorized.erb +4 -0
  173. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  174. metadata +81 -45
  175. data/lib/backup/cli.rb +0 -110
  176. data/lib/backup/exception/command_failed.rb +0 -8
  177. data/lib/backup/exception/command_not_found.rb +0 -8
  178. data/lib/backup/notifier/binder.rb +0 -32
  179. data/lib/backup/notifier/templates/notify_failure.erb +0 -33
  180. data/lib/backup/notifier/templates/notify_success.erb +0 -16
  181. data/lib/templates/archive +0 -7
  182. data/lib/templates/encryptor/openssl +0 -8
  183. data/lib/templates/readme +0 -15
  184. data/lib/templates/storage/cloudfiles +0 -11
  185. data/lib/templates/storage/local +0 -7
  186. data/lib/templates/storage/rsync +0 -11
  187. data/lib/templates/storage/scp +0 -11
  188. 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
- @databases = Array.new
103
- @archives = Array.new
104
- @encryptors = Array.new
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
- # [Package]
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
- begin
216
- if databases.any? or archives.any?
217
- databases.each { |d| d.perform! }
218
- archives.each { |a| a.perform! }
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
- syncers.each { |s| s.perform! }
227
- notifiers.each { |n| n.perform!(self) }
228
- rescue => exception
229
- clean!
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
- Logger.message "Backup started packaging everything to a single archive file."
243
- run(%|#{ utility(:tar) } -c -f '#{ File.join(TMP_PATH, "#{TIME}.#{TRIGGER}.tar") }' -C '#{ TMP_PATH }' '#{ TRIGGER }'|)
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
- Logger.message "Backup started cleaning up the temporary files."
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 the string representation of the last value of a nested constant
255
- # example:
256
- # Backup::Model::MySQL
257
- # becomes and returns:
258
- # "MySQL"
259
- def last_constant(constant)
260
- constant.to_s.split("::").last
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
- # Formats an exception
265
- def show_exception!(exception)
266
- Logger.normal "=" * 75 + "\nException that got raised:\n#{exception.class} - #{exception} \n" + "=" * 75 + "\n" + exception.backtrace.join("\n")
267
- Logger.normal "=" * 75 + "\n\nYou are running Backup version \"#{Backup::Version.current}\" and Ruby version \"#{RUBY_VERSION} (patchlevel #{RUBY_PATCHLEVEL})\" on platform \"#{RUBY_PLATFORM}\".\n"
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
@@ -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
- # Takes an exception object that might've been created if an exception occurred.
50
- # If this is the case it'll invoke notify_failure!(exception), otherwise, if no
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
- @model = model
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
- # Sends a message informing the user that the backup operation
70
- # proceeded without any errors
71
- def notify_success!
72
- send_message("[Backup::Succeeded] #{model.label} (#{ File.basename(Backup::Model.file) })")
73
- end
74
-
75
- ##
76
- # Sends a message informing the user that the backup operation
77
- # raised an exception
78
- def notify_failure!(exception)
79
- send_message("[Backup::Failed] #{model.label} (#{ File.basename(Backup::Model.file) })")
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
- # Setting up credentials
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