backup_checksum 3.0.23

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 (244) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +10 -0
  3. data/Gemfile +28 -0
  4. data/Gemfile.lock +130 -0
  5. data/Guardfile +21 -0
  6. data/LICENSE.md +24 -0
  7. data/README.md +476 -0
  8. data/backup_checksum.gemspec +32 -0
  9. data/bin/backup +11 -0
  10. data/lib/backup.rb +217 -0
  11. data/lib/backup/archive.rb +117 -0
  12. data/lib/backup/binder.rb +22 -0
  13. data/lib/backup/checksum/base.rb +44 -0
  14. data/lib/backup/checksum/shasum.rb +16 -0
  15. data/lib/backup/cleaner.rb +121 -0
  16. data/lib/backup/cli/helpers.rb +88 -0
  17. data/lib/backup/cli/utility.rb +247 -0
  18. data/lib/backup/compressor/base.rb +29 -0
  19. data/lib/backup/compressor/bzip2.rb +50 -0
  20. data/lib/backup/compressor/gzip.rb +47 -0
  21. data/lib/backup/compressor/lzma.rb +50 -0
  22. data/lib/backup/compressor/pbzip2.rb +56 -0
  23. data/lib/backup/config.rb +173 -0
  24. data/lib/backup/configuration/base.rb +15 -0
  25. data/lib/backup/configuration/checksum/base.rb +9 -0
  26. data/lib/backup/configuration/checksum/shasum.rb +9 -0
  27. data/lib/backup/configuration/compressor/base.rb +9 -0
  28. data/lib/backup/configuration/compressor/bzip2.rb +23 -0
  29. data/lib/backup/configuration/compressor/gzip.rb +23 -0
  30. data/lib/backup/configuration/compressor/lzma.rb +23 -0
  31. data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
  32. data/lib/backup/configuration/database/base.rb +19 -0
  33. data/lib/backup/configuration/database/mongodb.rb +49 -0
  34. data/lib/backup/configuration/database/mysql.rb +42 -0
  35. data/lib/backup/configuration/database/postgresql.rb +41 -0
  36. data/lib/backup/configuration/database/redis.rb +39 -0
  37. data/lib/backup/configuration/database/riak.rb +29 -0
  38. data/lib/backup/configuration/encryptor/base.rb +9 -0
  39. data/lib/backup/configuration/encryptor/gpg.rb +17 -0
  40. data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
  41. data/lib/backup/configuration/helpers.rb +52 -0
  42. data/lib/backup/configuration/notifier/base.rb +28 -0
  43. data/lib/backup/configuration/notifier/campfire.rb +25 -0
  44. data/lib/backup/configuration/notifier/hipchat.rb +41 -0
  45. data/lib/backup/configuration/notifier/mail.rb +112 -0
  46. data/lib/backup/configuration/notifier/presently.rb +25 -0
  47. data/lib/backup/configuration/notifier/prowl.rb +23 -0
  48. data/lib/backup/configuration/notifier/twitter.rb +21 -0
  49. data/lib/backup/configuration/storage/base.rb +18 -0
  50. data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
  51. data/lib/backup/configuration/storage/dropbox.rb +58 -0
  52. data/lib/backup/configuration/storage/ftp.rb +29 -0
  53. data/lib/backup/configuration/storage/local.rb +17 -0
  54. data/lib/backup/configuration/storage/ninefold.rb +20 -0
  55. data/lib/backup/configuration/storage/rsync.rb +29 -0
  56. data/lib/backup/configuration/storage/s3.rb +25 -0
  57. data/lib/backup/configuration/storage/scp.rb +25 -0
  58. data/lib/backup/configuration/storage/sftp.rb +25 -0
  59. data/lib/backup/configuration/syncer/base.rb +10 -0
  60. data/lib/backup/configuration/syncer/cloud.rb +23 -0
  61. data/lib/backup/configuration/syncer/cloud_files.rb +30 -0
  62. data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
  63. data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
  64. data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
  65. data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
  66. data/lib/backup/configuration/syncer/s3.rb +23 -0
  67. data/lib/backup/database/base.rb +59 -0
  68. data/lib/backup/database/mongodb.rb +232 -0
  69. data/lib/backup/database/mysql.rb +163 -0
  70. data/lib/backup/database/postgresql.rb +146 -0
  71. data/lib/backup/database/redis.rb +139 -0
  72. data/lib/backup/database/riak.rb +69 -0
  73. data/lib/backup/dependency.rb +114 -0
  74. data/lib/backup/encryptor/base.rb +29 -0
  75. data/lib/backup/encryptor/gpg.rb +80 -0
  76. data/lib/backup/encryptor/open_ssl.rb +72 -0
  77. data/lib/backup/errors.rb +124 -0
  78. data/lib/backup/logger.rb +152 -0
  79. data/lib/backup/model.rb +386 -0
  80. data/lib/backup/notifier/base.rb +81 -0
  81. data/lib/backup/notifier/campfire.rb +168 -0
  82. data/lib/backup/notifier/hipchat.rb +99 -0
  83. data/lib/backup/notifier/mail.rb +206 -0
  84. data/lib/backup/notifier/presently.rb +88 -0
  85. data/lib/backup/notifier/prowl.rb +65 -0
  86. data/lib/backup/notifier/twitter.rb +70 -0
  87. data/lib/backup/package.rb +51 -0
  88. data/lib/backup/packager.rb +108 -0
  89. data/lib/backup/pipeline.rb +107 -0
  90. data/lib/backup/splitter.rb +75 -0
  91. data/lib/backup/storage/base.rb +119 -0
  92. data/lib/backup/storage/cloudfiles.rb +87 -0
  93. data/lib/backup/storage/cycler.rb +117 -0
  94. data/lib/backup/storage/dropbox.rb +181 -0
  95. data/lib/backup/storage/ftp.rb +119 -0
  96. data/lib/backup/storage/local.rb +82 -0
  97. data/lib/backup/storage/ninefold.rb +116 -0
  98. data/lib/backup/storage/rsync.rb +149 -0
  99. data/lib/backup/storage/s3.rb +94 -0
  100. data/lib/backup/storage/scp.rb +99 -0
  101. data/lib/backup/storage/sftp.rb +108 -0
  102. data/lib/backup/syncer/base.rb +42 -0
  103. data/lib/backup/syncer/cloud.rb +190 -0
  104. data/lib/backup/syncer/cloud_files.rb +56 -0
  105. data/lib/backup/syncer/rsync/base.rb +52 -0
  106. data/lib/backup/syncer/rsync/local.rb +53 -0
  107. data/lib/backup/syncer/rsync/pull.rb +38 -0
  108. data/lib/backup/syncer/rsync/push.rb +113 -0
  109. data/lib/backup/syncer/s3.rb +47 -0
  110. data/lib/backup/template.rb +46 -0
  111. data/lib/backup/version.rb +43 -0
  112. data/spec/archive_spec.rb +335 -0
  113. data/spec/cleaner_spec.rb +304 -0
  114. data/spec/cli/helpers_spec.rb +176 -0
  115. data/spec/cli/utility_spec.rb +363 -0
  116. data/spec/compressor/base_spec.rb +31 -0
  117. data/spec/compressor/bzip2_spec.rb +83 -0
  118. data/spec/compressor/gzip_spec.rb +83 -0
  119. data/spec/compressor/lzma_spec.rb +83 -0
  120. data/spec/compressor/pbzip2_spec.rb +124 -0
  121. data/spec/config_spec.rb +321 -0
  122. data/spec/configuration/base_spec.rb +35 -0
  123. data/spec/configuration/compressor/bzip2_spec.rb +29 -0
  124. data/spec/configuration/compressor/gzip_spec.rb +29 -0
  125. data/spec/configuration/compressor/lzma_spec.rb +29 -0
  126. data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
  127. data/spec/configuration/database/base_spec.rb +17 -0
  128. data/spec/configuration/database/mongodb_spec.rb +56 -0
  129. data/spec/configuration/database/mysql_spec.rb +53 -0
  130. data/spec/configuration/database/postgresql_spec.rb +53 -0
  131. data/spec/configuration/database/redis_spec.rb +50 -0
  132. data/spec/configuration/database/riak_spec.rb +35 -0
  133. data/spec/configuration/encryptor/gpg_spec.rb +26 -0
  134. data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
  135. data/spec/configuration/notifier/base_spec.rb +32 -0
  136. data/spec/configuration/notifier/campfire_spec.rb +32 -0
  137. data/spec/configuration/notifier/hipchat_spec.rb +44 -0
  138. data/spec/configuration/notifier/mail_spec.rb +71 -0
  139. data/spec/configuration/notifier/presently_spec.rb +35 -0
  140. data/spec/configuration/notifier/prowl_spec.rb +29 -0
  141. data/spec/configuration/notifier/twitter_spec.rb +35 -0
  142. data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
  143. data/spec/configuration/storage/dropbox_spec.rb +38 -0
  144. data/spec/configuration/storage/ftp_spec.rb +44 -0
  145. data/spec/configuration/storage/local_spec.rb +29 -0
  146. data/spec/configuration/storage/ninefold_spec.rb +32 -0
  147. data/spec/configuration/storage/rsync_spec.rb +41 -0
  148. data/spec/configuration/storage/s3_spec.rb +38 -0
  149. data/spec/configuration/storage/scp_spec.rb +41 -0
  150. data/spec/configuration/storage/sftp_spec.rb +41 -0
  151. data/spec/configuration/syncer/cloud_files_spec.rb +44 -0
  152. data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
  153. data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
  154. data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
  155. data/spec/configuration/syncer/rsync/push_spec.rb +43 -0
  156. data/spec/configuration/syncer/s3_spec.rb +38 -0
  157. data/spec/database/base_spec.rb +54 -0
  158. data/spec/database/mongodb_spec.rb +428 -0
  159. data/spec/database/mysql_spec.rb +335 -0
  160. data/spec/database/postgresql_spec.rb +278 -0
  161. data/spec/database/redis_spec.rb +260 -0
  162. data/spec/database/riak_spec.rb +108 -0
  163. data/spec/dependency_spec.rb +49 -0
  164. data/spec/encryptor/base_spec.rb +30 -0
  165. data/spec/encryptor/gpg_spec.rb +134 -0
  166. data/spec/encryptor/open_ssl_spec.rb +129 -0
  167. data/spec/errors_spec.rb +306 -0
  168. data/spec/logger_spec.rb +363 -0
  169. data/spec/model_spec.rb +649 -0
  170. data/spec/notifier/base_spec.rb +89 -0
  171. data/spec/notifier/campfire_spec.rb +199 -0
  172. data/spec/notifier/hipchat_spec.rb +188 -0
  173. data/spec/notifier/mail_spec.rb +280 -0
  174. data/spec/notifier/presently_spec.rb +181 -0
  175. data/spec/notifier/prowl_spec.rb +117 -0
  176. data/spec/notifier/twitter_spec.rb +132 -0
  177. data/spec/package_spec.rb +61 -0
  178. data/spec/packager_spec.rb +225 -0
  179. data/spec/pipeline_spec.rb +257 -0
  180. data/spec/spec_helper.rb +59 -0
  181. data/spec/splitter_spec.rb +120 -0
  182. data/spec/storage/base_spec.rb +160 -0
  183. data/spec/storage/cloudfiles_spec.rb +230 -0
  184. data/spec/storage/cycler_spec.rb +239 -0
  185. data/spec/storage/dropbox_spec.rb +370 -0
  186. data/spec/storage/ftp_spec.rb +247 -0
  187. data/spec/storage/local_spec.rb +235 -0
  188. data/spec/storage/ninefold_spec.rb +319 -0
  189. data/spec/storage/rsync_spec.rb +345 -0
  190. data/spec/storage/s3_spec.rb +221 -0
  191. data/spec/storage/scp_spec.rb +209 -0
  192. data/spec/storage/sftp_spec.rb +220 -0
  193. data/spec/syncer/base_spec.rb +22 -0
  194. data/spec/syncer/cloud_files_spec.rb +192 -0
  195. data/spec/syncer/rsync/base_spec.rb +118 -0
  196. data/spec/syncer/rsync/local_spec.rb +121 -0
  197. data/spec/syncer/rsync/pull_spec.rb +90 -0
  198. data/spec/syncer/rsync/push_spec.rb +327 -0
  199. data/spec/syncer/s3_spec.rb +192 -0
  200. data/spec/version_spec.rb +21 -0
  201. data/templates/cli/utility/archive +25 -0
  202. data/templates/cli/utility/compressor/bzip2 +7 -0
  203. data/templates/cli/utility/compressor/gzip +7 -0
  204. data/templates/cli/utility/compressor/lzma +7 -0
  205. data/templates/cli/utility/compressor/pbzip2 +7 -0
  206. data/templates/cli/utility/config +31 -0
  207. data/templates/cli/utility/database/mongodb +18 -0
  208. data/templates/cli/utility/database/mysql +21 -0
  209. data/templates/cli/utility/database/postgresql +17 -0
  210. data/templates/cli/utility/database/redis +16 -0
  211. data/templates/cli/utility/database/riak +11 -0
  212. data/templates/cli/utility/encryptor/gpg +12 -0
  213. data/templates/cli/utility/encryptor/openssl +9 -0
  214. data/templates/cli/utility/model.erb +23 -0
  215. data/templates/cli/utility/notifier/campfire +12 -0
  216. data/templates/cli/utility/notifier/hipchat +15 -0
  217. data/templates/cli/utility/notifier/mail +22 -0
  218. data/templates/cli/utility/notifier/presently +13 -0
  219. data/templates/cli/utility/notifier/prowl +11 -0
  220. data/templates/cli/utility/notifier/twitter +13 -0
  221. data/templates/cli/utility/splitter +7 -0
  222. data/templates/cli/utility/storage/cloud_files +22 -0
  223. data/templates/cli/utility/storage/dropbox +20 -0
  224. data/templates/cli/utility/storage/ftp +12 -0
  225. data/templates/cli/utility/storage/local +7 -0
  226. data/templates/cli/utility/storage/ninefold +9 -0
  227. data/templates/cli/utility/storage/rsync +11 -0
  228. data/templates/cli/utility/storage/s3 +19 -0
  229. data/templates/cli/utility/storage/scp +11 -0
  230. data/templates/cli/utility/storage/sftp +11 -0
  231. data/templates/cli/utility/syncer/cloud_files +48 -0
  232. data/templates/cli/utility/syncer/rsync_local +12 -0
  233. data/templates/cli/utility/syncer/rsync_pull +17 -0
  234. data/templates/cli/utility/syncer/rsync_push +17 -0
  235. data/templates/cli/utility/syncer/s3 +45 -0
  236. data/templates/general/links +11 -0
  237. data/templates/general/version.erb +2 -0
  238. data/templates/notifier/mail/failure.erb +9 -0
  239. data/templates/notifier/mail/success.erb +7 -0
  240. data/templates/notifier/mail/warning.erb +9 -0
  241. data/templates/storage/dropbox/authorization_url.erb +6 -0
  242. data/templates/storage/dropbox/authorized.erb +4 -0
  243. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  244. metadata +311 -0
@@ -0,0 +1,386 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ class Model
5
+ include Backup::CLI::Helpers
6
+
7
+ class << self
8
+ ##
9
+ # The Backup::Model.all class method keeps track of all the models
10
+ # that have been instantiated. It returns the @all class variable,
11
+ # which contains an array of all the models
12
+ def all
13
+ @all ||= []
14
+ end
15
+
16
+ ##
17
+ # Return the first model matching +trigger+.
18
+ # Raises Errors::MissingTriggerError if no matches are found.
19
+ def find(trigger)
20
+ trigger = trigger.to_s
21
+ all.each do |model|
22
+ return model if model.trigger == trigger
23
+ end
24
+ raise Errors::Model::MissingTriggerError,
25
+ "Could not find trigger '#{trigger}'."
26
+ end
27
+
28
+ ##
29
+ # Find and return an Array of all models matching +trigger+
30
+ # Used to match triggers using a wildcard (*)
31
+ def find_matching(trigger)
32
+ regex = /^#{ trigger.to_s.gsub('*', '(.*)') }$/
33
+ all.select {|model| regex =~ model.trigger }
34
+ end
35
+ end
36
+
37
+ ##
38
+ # The trigger (stored as a String) is used as an identifier
39
+ # for initializing the backup process
40
+ attr_reader :trigger
41
+
42
+ ##
43
+ # The label (stored as a String) is used for a more friendly user output
44
+ attr_reader :label
45
+
46
+ ##
47
+ # The databases attribute holds an array of database objects
48
+ attr_reader :databases
49
+
50
+ ##
51
+ # The archives attr_accessor holds an array of archive objects
52
+ attr_reader :archives
53
+
54
+ ##
55
+ # The notifiers attr_accessor holds an array of notifier objects
56
+ attr_reader :notifiers
57
+
58
+ ##
59
+ # The storages attribute holds an array of storage objects
60
+ attr_reader :storages
61
+
62
+ ##
63
+ # The syncers attribute holds an array of syncer objects
64
+ attr_reader :syncers
65
+
66
+ ##
67
+ # Holds the configured Compressor
68
+ attr_reader :compressor
69
+
70
+ ##
71
+ # Holds the configured ChecksumCreator
72
+ attr_reader :checksum_creator
73
+
74
+ ##
75
+ # Holds the configured Encryptor
76
+ attr_reader :encryptor
77
+
78
+ ##
79
+ # Holds the configured Splitter
80
+ attr_reader :splitter
81
+
82
+ ##
83
+ # The final backup Package this model will create.
84
+ attr_reader :package
85
+
86
+ ##
87
+ # The time when the backup initiated (in format: 2011.02.20.03.29.59)
88
+ attr_reader :time
89
+
90
+ ##
91
+ # Takes a trigger, label and the configuration block.
92
+ # After the instance has evaluated the configuration block
93
+ # to configure the model, it will be appended to Model.all
94
+ def initialize(trigger, label, &block)
95
+ @trigger = trigger.to_s
96
+ @label = label.to_s
97
+
98
+ procedure_instance_variables.each do |variable|
99
+ instance_variable_set(variable, Array.new)
100
+ end
101
+
102
+ instance_eval(&block) if block_given?
103
+ Model.all << self
104
+ end
105
+
106
+ ##
107
+ # Adds an archive to the array of archives
108
+ # to store during the backup process
109
+ def archive(name, &block)
110
+ @archives << Archive.new(self, name, &block)
111
+ end
112
+
113
+ ##
114
+ # Adds a database to the array of databases
115
+ # to dump during the backup process
116
+ def database(name, &block)
117
+ @databases << get_class_from_scope(Database, name).new(self, &block)
118
+ end
119
+
120
+ ##
121
+ # Adds a storage method to the array of storage
122
+ # methods to use during the backup process
123
+ def store_with(name, storage_id = nil, &block)
124
+ @storages << get_class_from_scope(Storage, name).new(self, storage_id, &block)
125
+ end
126
+
127
+ ##
128
+ # Adds a syncer method to the array of syncer
129
+ # methods to use during the backup process
130
+ def sync_with(name, &block)
131
+ ##
132
+ # Warn user of DSL change from 'RSync' to 'RSync::Local'
133
+ if name.to_s == 'Backup::Config::RSync'
134
+ Logger.warn Errors::ConfigError.new(<<-EOS)
135
+ Configuration Update Needed for Syncer::RSync
136
+ The RSync Syncer has been split into three separate modules:
137
+ RSync::Local, RSync::Push and RSync::Pull
138
+ Please update your configuration for your local RSync Syncer
139
+ from 'sync_with RSync do ...' to 'sync_with RSync::Local do ...'
140
+ EOS
141
+ name = Backup::Config::RSync::Local
142
+ end
143
+ @syncers << get_class_from_scope(Syncer, name).new(&block)
144
+ end
145
+
146
+ ##
147
+ # Adds a notifier to the array of notifiers
148
+ # to use during the backup process
149
+ def notify_by(name, &block)
150
+ @notifiers << get_class_from_scope(Notifier, name).new(self, &block)
151
+ end
152
+
153
+ ##
154
+ # Adds an encryptor to use during the backup process
155
+ def encrypt_with(name, &block)
156
+ @encryptor = get_class_from_scope(Encryptor, name).new(&block)
157
+ end
158
+
159
+ ##
160
+ # Adds a compressor to use during the backup process
161
+ def compress_with(name, &block)
162
+ @compressor = get_class_from_scope(Compressor, name).new(&block)
163
+ end
164
+
165
+ ##
166
+ # Adds a checksum to use during the backup process
167
+ def checksum_with(name, &block)
168
+ @checksum_creator = get_class_from_scope(Checksum, name).new(&block)
169
+ end
170
+
171
+ ##
172
+ # Adds a method that allows the user to configure this backup model
173
+ # to use a Splitter, with the given +chunk_size+
174
+ # The +chunk_size+ (in megabytes) will later determine
175
+ # in how many chunks the backup needs to be split into
176
+ def split_into_chunks_of(chunk_size)
177
+ if chunk_size.is_a?(Integer)
178
+ @splitter = Splitter.new(self, chunk_size)
179
+ else
180
+ raise Errors::Model::ConfigurationError, <<-EOS
181
+ Invalid Chunk Size for Splitter
182
+ Argument to #split_into_chunks_of() must be an Integer
183
+ EOS
184
+ end
185
+ end
186
+
187
+ ##
188
+ # Ensure DATA_PATH and DATA_PATH/TRIGGER are created
189
+ # if they do not yet exist
190
+ #
191
+ # Clean any temporary files and/or package files left over
192
+ # from the last time this model/trigger was performed.
193
+ # Logs warnings if files exist and are cleaned.
194
+ def prepare!
195
+ FileUtils.mkdir_p(File.join(Config.data_path, trigger))
196
+ Cleaner.prepare(self)
197
+ end
198
+
199
+ ##
200
+ # Performs the backup process
201
+ ##
202
+ # [Databases]
203
+ # Runs all (if any) database objects to dump the databases
204
+ ##
205
+ # [Archives]
206
+ # Runs all (if any) archive objects to package all their
207
+ # paths in to a single tar file and places it in the backup folder
208
+ ##
209
+ # [Packaging]
210
+ # After all the database dumps and archives are placed inside
211
+ # the folder, it'll make a single .tar package (archive) out of it
212
+ ##
213
+ # [Encryption]
214
+ # Optionally encrypts the packaged file with the configured encryptor
215
+ ##
216
+ # [Compression]
217
+ # Optionally compresses the each Archive and Database dump with the configured compressor
218
+ ##
219
+ # [Splitting]
220
+ # Optionally splits the backup file in to multiple smaller chunks before transferring them
221
+ ##
222
+ # [Storages]
223
+ # Runs all (if any) storage objects to store the backups to remote locations
224
+ # and (if configured) it'll cycle the files on the remote location to limit the
225
+ # amount of backups stored on each individual location
226
+ ##
227
+ # [Syncers]
228
+ # Runs all (if any) sync objects to store the backups to remote locations.
229
+ # A Syncer does not go through the process of packaging, compressing, encrypting backups.
230
+ # A Syncer directly transfers data from the filesystem to the remote location
231
+ ##
232
+ # [Notifiers]
233
+ # Runs all (if any) notifier objects when a backup proces finished with or without
234
+ # any errors.
235
+ ##
236
+ # [Cleaning]
237
+ # Once the final Packaging is complete, the temporary folder used will be removed.
238
+ # Then, once all Storages have run, the final packaged files will be removed.
239
+ # If any errors occur during the backup process, all temporary files will be left in place.
240
+ # If the error occurs before Packaging, then the temporary folder (tmp_path/trigger)
241
+ # will remain and may contain all or some of the configured Archives and/or Database dumps.
242
+ # If the error occurs after Packaging, but before the Storages complete, then the final
243
+ # packaged files (located in the root of tmp_path) will remain.
244
+ # *** Important *** If an error occurs and any of the above mentioned temporary files remain,
245
+ # those files *** will be removed *** before the next scheduled backup for the same trigger.
246
+ #
247
+ def perform!
248
+ @started_at = Time.now
249
+ @time = @started_at.strftime("%Y.%m.%d.%H.%M.%S")
250
+ log!(:started)
251
+
252
+ if databases.any? or archives.any?
253
+ procedures.each do |procedure|
254
+ (procedure.call; next) if procedure.is_a?(Proc)
255
+ procedure.each(&:perform!)
256
+ end
257
+ end
258
+
259
+ syncers.each(&:perform!)
260
+ notifiers.each(&:perform!)
261
+ log!(:finished)
262
+
263
+ rescue Exception => err
264
+ fatal = !err.is_a?(StandardError)
265
+
266
+ err = Errors::ModelError.wrap(err, <<-EOS)
267
+ Backup for #{label} (#{trigger}) Failed!
268
+ An Error occured which has caused this Backup to abort before completion.
269
+ EOS
270
+ Logger.error err
271
+ Logger.error "\nBacktrace:\n\s\s" + err.backtrace.join("\n\s\s") + "\n\n"
272
+
273
+ Cleaner.warnings(self)
274
+
275
+ if fatal
276
+ Logger.error Errors::ModelError.new(<<-EOS)
277
+ This Error was Fatal and Backup will now exit.
278
+ If you have other Backup jobs (triggers) configured to run,
279
+ they will not be processed.
280
+ EOS
281
+ else
282
+ Logger.message Errors::ModelError.new(<<-EOS)
283
+ If you have other Backup jobs (triggers) configured to run,
284
+ Backup will now attempt to continue...
285
+ EOS
286
+ end
287
+
288
+ notifiers.each do |n|
289
+ begin
290
+ n.perform!(true)
291
+ rescue Exception; end
292
+ end
293
+
294
+ exit(1) if fatal
295
+ end
296
+
297
+ private
298
+
299
+ ##
300
+ # After all the databases and archives have been dumped and sorted,
301
+ # these files will be bundled in to a .tar archive (uncompressed),
302
+ # which may be optionally Encrypted and/or Split into multiple "chunks".
303
+ # All information about this final archive is stored in the @package.
304
+ # Once complete, the temporary folder used during packaging is removed.
305
+ def package!
306
+ @package = Package.new(self)
307
+ Packager.package!(self)
308
+ Cleaner.remove_packaging(self)
309
+ end
310
+
311
+ ##
312
+ # Removes the final package file(s) once all configured Storages have run.
313
+ def clean!
314
+ Cleaner.remove_package(@package)
315
+ end
316
+
317
+ ##
318
+ # Returns an array of procedures
319
+ def procedures
320
+ [databases, archives, lambda { package! }, storages, lambda { clean! }]
321
+ end
322
+
323
+ ##
324
+ # Returns an Array of the names (String) of the procedure instance variables
325
+ def procedure_instance_variables
326
+ [:@databases, :@archives, :@storages, :@notifiers, :@syncers]
327
+ end
328
+
329
+ ##
330
+ # Returns the class/model specified by +name+ inside of +scope+.
331
+ # +scope+ should be a Class/Module.
332
+ # +name+ may be Class/Module or String representation
333
+ # of any namespace which exists under +scope+.
334
+ #
335
+ # The 'Backup::Config::' namespace is stripped from +name+,
336
+ # since this is the namespace where we define module namespaces
337
+ # for use with Model's DSL methods.
338
+ #
339
+ # Examples:
340
+ # get_class_from_scope(Backup::Database, 'MySQL')
341
+ # returns the class Backup::Database::MySQL
342
+ #
343
+ # get_class_from_scope(Backup::Syncer, Backup::Config::RSync::Local)
344
+ # returns the class Backup::Syncer::RSync::Local
345
+ #
346
+ def get_class_from_scope(scope, name)
347
+ klass = scope
348
+ name = name.to_s.sub(/^Backup::Config::/, '')
349
+ name.split('::').each do |chunk|
350
+ klass = klass.const_get(chunk)
351
+ end
352
+ klass
353
+ end
354
+
355
+ ##
356
+ # Logs messages when the backup starts and finishes
357
+ def log!(action)
358
+ case action
359
+ when :started
360
+ Logger.message "Performing Backup for '#{label} (#{trigger})'!\n" +
361
+ "[ backup #{ Version.current } : #{ RUBY_DESCRIPTION } ]"
362
+
363
+ when :finished
364
+ msg = "Backup for '#{ label } (#{ trigger })' " +
365
+ "Completed %s in #{ elapsed_time }"
366
+ if Logger.has_warnings?
367
+ Logger.warn msg % 'Successfully (with Warnings)'
368
+ else
369
+ Logger.message msg % 'Successfully'
370
+ end
371
+ end
372
+ end
373
+
374
+ ##
375
+ # Returns a string representing the elapsed time since the backup started.
376
+ def elapsed_time
377
+ duration = Time.now.to_i - @started_at.to_i
378
+ hours = duration / 3600
379
+ remainder = duration - (hours * 3600)
380
+ minutes = remainder / 60
381
+ seconds = remainder - (minutes * 60)
382
+ '%02d:%02d:%02d' % [hours, minutes, seconds]
383
+ end
384
+
385
+ end
386
+ end
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Notifier
5
+ class Base
6
+ include Backup::Configuration::Helpers
7
+
8
+ ##
9
+ # When set to true, the user will be notified by email
10
+ # when a backup process ends without raising any exceptions
11
+ attr_accessor :on_success
12
+ alias :notify_on_success? :on_success
13
+
14
+ ##
15
+ # When set to true, the user will be notified by email
16
+ # when a backup process is successful, but has warnings
17
+ attr_accessor :on_warning
18
+ alias :notify_on_warning? :on_warning
19
+
20
+ ##
21
+ # When set to true, the user will be notified by email
22
+ # when a backup process raises an exception before finishing
23
+ attr_accessor :on_failure
24
+ alias :notify_on_failure? :on_failure
25
+
26
+ ##
27
+ # Called with super(model) from subclasses
28
+ def initialize(model)
29
+ @model = model
30
+ load_defaults!
31
+
32
+ @on_success = true if on_success.nil?
33
+ @on_warning = true if on_warning.nil?
34
+ @on_failure = true if on_failure.nil?
35
+ end
36
+
37
+ ##
38
+ # Performs the notification
39
+ # Takes a flag to indicate that a failure has occured.
40
+ # (this is only set from Model#perform! in the event of an error)
41
+ # If this is the case it will set the 'action' to :failure.
42
+ # Otherwise, it will set the 'action' to either :success or :warning,
43
+ # depending on whether or not any warnings were sent to the Logger.
44
+ # It will then invoke the notify! method with the 'action',
45
+ # but only if the proper on_success, on_warning or on_failure flag is true.
46
+ def perform!(failure = false)
47
+ @template = Backup::Template.new({:model => @model})
48
+
49
+ action = false
50
+ if failure
51
+ action = :failure if notify_on_failure?
52
+ else
53
+ if notify_on_success? || (notify_on_warning? && Logger.has_warnings?)
54
+ action = Logger.has_warnings? ? :warning : :success
55
+ end
56
+ end
57
+
58
+ if action
59
+ log!
60
+ notify!(action)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ ##
67
+ # Return the notifier name, with Backup namespace removed
68
+ def notifier_name
69
+ self.class.to_s.sub('Backup::', '')
70
+ end
71
+
72
+ ##
73
+ # Logs a message to the console and log file to inform
74
+ # the client that Backup is notifying about the process
75
+ def log!
76
+ Logger.message "#{ notifier_name } started notifying about the process."
77
+ end
78
+
79
+ end
80
+ end
81
+ end