backup 3.0.19 → 3.0.20

Sign up to get free protection for your applications and to get access to all the features.
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