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.
- data/.gitignore +7 -0
- data/.travis.yml +10 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +130 -0
- data/Guardfile +21 -0
- data/LICENSE.md +24 -0
- data/README.md +476 -0
- data/backup_checksum.gemspec +32 -0
- data/bin/backup +11 -0
- data/lib/backup.rb +217 -0
- data/lib/backup/archive.rb +117 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/checksum/base.rb +44 -0
- data/lib/backup/checksum/shasum.rb +16 -0
- data/lib/backup/cleaner.rb +121 -0
- data/lib/backup/cli/helpers.rb +88 -0
- data/lib/backup/cli/utility.rb +247 -0
- data/lib/backup/compressor/base.rb +29 -0
- data/lib/backup/compressor/bzip2.rb +50 -0
- data/lib/backup/compressor/gzip.rb +47 -0
- data/lib/backup/compressor/lzma.rb +50 -0
- data/lib/backup/compressor/pbzip2.rb +56 -0
- data/lib/backup/config.rb +173 -0
- data/lib/backup/configuration/base.rb +15 -0
- data/lib/backup/configuration/checksum/base.rb +9 -0
- data/lib/backup/configuration/checksum/shasum.rb +9 -0
- data/lib/backup/configuration/compressor/base.rb +9 -0
- data/lib/backup/configuration/compressor/bzip2.rb +23 -0
- data/lib/backup/configuration/compressor/gzip.rb +23 -0
- data/lib/backup/configuration/compressor/lzma.rb +23 -0
- data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
- data/lib/backup/configuration/database/base.rb +19 -0
- data/lib/backup/configuration/database/mongodb.rb +49 -0
- data/lib/backup/configuration/database/mysql.rb +42 -0
- data/lib/backup/configuration/database/postgresql.rb +41 -0
- data/lib/backup/configuration/database/redis.rb +39 -0
- data/lib/backup/configuration/database/riak.rb +29 -0
- data/lib/backup/configuration/encryptor/base.rb +9 -0
- data/lib/backup/configuration/encryptor/gpg.rb +17 -0
- data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
- data/lib/backup/configuration/helpers.rb +52 -0
- data/lib/backup/configuration/notifier/base.rb +28 -0
- data/lib/backup/configuration/notifier/campfire.rb +25 -0
- data/lib/backup/configuration/notifier/hipchat.rb +41 -0
- data/lib/backup/configuration/notifier/mail.rb +112 -0
- data/lib/backup/configuration/notifier/presently.rb +25 -0
- data/lib/backup/configuration/notifier/prowl.rb +23 -0
- data/lib/backup/configuration/notifier/twitter.rb +21 -0
- data/lib/backup/configuration/storage/base.rb +18 -0
- data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
- data/lib/backup/configuration/storage/dropbox.rb +58 -0
- data/lib/backup/configuration/storage/ftp.rb +29 -0
- data/lib/backup/configuration/storage/local.rb +17 -0
- data/lib/backup/configuration/storage/ninefold.rb +20 -0
- data/lib/backup/configuration/storage/rsync.rb +29 -0
- data/lib/backup/configuration/storage/s3.rb +25 -0
- data/lib/backup/configuration/storage/scp.rb +25 -0
- data/lib/backup/configuration/storage/sftp.rb +25 -0
- data/lib/backup/configuration/syncer/base.rb +10 -0
- data/lib/backup/configuration/syncer/cloud.rb +23 -0
- data/lib/backup/configuration/syncer/cloud_files.rb +30 -0
- data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
- data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
- data/lib/backup/configuration/syncer/s3.rb +23 -0
- data/lib/backup/database/base.rb +59 -0
- data/lib/backup/database/mongodb.rb +232 -0
- data/lib/backup/database/mysql.rb +163 -0
- data/lib/backup/database/postgresql.rb +146 -0
- data/lib/backup/database/redis.rb +139 -0
- data/lib/backup/database/riak.rb +69 -0
- data/lib/backup/dependency.rb +114 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +80 -0
- data/lib/backup/encryptor/open_ssl.rb +72 -0
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/logger.rb +152 -0
- data/lib/backup/model.rb +386 -0
- data/lib/backup/notifier/base.rb +81 -0
- data/lib/backup/notifier/campfire.rb +168 -0
- data/lib/backup/notifier/hipchat.rb +99 -0
- data/lib/backup/notifier/mail.rb +206 -0
- data/lib/backup/notifier/presently.rb +88 -0
- data/lib/backup/notifier/prowl.rb +65 -0
- data/lib/backup/notifier/twitter.rb +70 -0
- data/lib/backup/package.rb +51 -0
- data/lib/backup/packager.rb +108 -0
- data/lib/backup/pipeline.rb +107 -0
- data/lib/backup/splitter.rb +75 -0
- data/lib/backup/storage/base.rb +119 -0
- data/lib/backup/storage/cloudfiles.rb +87 -0
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +181 -0
- data/lib/backup/storage/ftp.rb +119 -0
- data/lib/backup/storage/local.rb +82 -0
- data/lib/backup/storage/ninefold.rb +116 -0
- data/lib/backup/storage/rsync.rb +149 -0
- data/lib/backup/storage/s3.rb +94 -0
- data/lib/backup/storage/scp.rb +99 -0
- data/lib/backup/storage/sftp.rb +108 -0
- data/lib/backup/syncer/base.rb +42 -0
- data/lib/backup/syncer/cloud.rb +190 -0
- data/lib/backup/syncer/cloud_files.rb +56 -0
- data/lib/backup/syncer/rsync/base.rb +52 -0
- data/lib/backup/syncer/rsync/local.rb +53 -0
- data/lib/backup/syncer/rsync/pull.rb +38 -0
- data/lib/backup/syncer/rsync/push.rb +113 -0
- data/lib/backup/syncer/s3.rb +47 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +43 -0
- data/spec/archive_spec.rb +335 -0
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +176 -0
- data/spec/cli/utility_spec.rb +363 -0
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +83 -0
- data/spec/compressor/gzip_spec.rb +83 -0
- data/spec/compressor/lzma_spec.rb +83 -0
- data/spec/compressor/pbzip2_spec.rb +124 -0
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +35 -0
- data/spec/configuration/compressor/bzip2_spec.rb +29 -0
- data/spec/configuration/compressor/gzip_spec.rb +29 -0
- data/spec/configuration/compressor/lzma_spec.rb +29 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +17 -0
- data/spec/configuration/database/mongodb_spec.rb +56 -0
- data/spec/configuration/database/mysql_spec.rb +53 -0
- data/spec/configuration/database/postgresql_spec.rb +53 -0
- data/spec/configuration/database/redis_spec.rb +50 -0
- data/spec/configuration/database/riak_spec.rb +35 -0
- data/spec/configuration/encryptor/gpg_spec.rb +26 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +32 -0
- data/spec/configuration/notifier/hipchat_spec.rb +44 -0
- data/spec/configuration/notifier/mail_spec.rb +71 -0
- data/spec/configuration/notifier/presently_spec.rb +35 -0
- data/spec/configuration/notifier/prowl_spec.rb +29 -0
- data/spec/configuration/notifier/twitter_spec.rb +35 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
- data/spec/configuration/storage/dropbox_spec.rb +38 -0
- data/spec/configuration/storage/ftp_spec.rb +44 -0
- data/spec/configuration/storage/local_spec.rb +29 -0
- data/spec/configuration/storage/ninefold_spec.rb +32 -0
- data/spec/configuration/storage/rsync_spec.rb +41 -0
- data/spec/configuration/storage/s3_spec.rb +38 -0
- data/spec/configuration/storage/scp_spec.rb +41 -0
- data/spec/configuration/storage/sftp_spec.rb +41 -0
- data/spec/configuration/syncer/cloud_files_spec.rb +44 -0
- data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
- data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
- data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
- data/spec/configuration/syncer/rsync/push_spec.rb +43 -0
- data/spec/configuration/syncer/s3_spec.rb +38 -0
- data/spec/database/base_spec.rb +54 -0
- data/spec/database/mongodb_spec.rb +428 -0
- data/spec/database/mysql_spec.rb +335 -0
- data/spec/database/postgresql_spec.rb +278 -0
- data/spec/database/redis_spec.rb +260 -0
- data/spec/database/riak_spec.rb +108 -0
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +134 -0
- data/spec/encryptor/open_ssl_spec.rb +129 -0
- data/spec/errors_spec.rb +306 -0
- data/spec/logger_spec.rb +363 -0
- data/spec/model_spec.rb +649 -0
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +199 -0
- data/spec/notifier/hipchat_spec.rb +188 -0
- data/spec/notifier/mail_spec.rb +280 -0
- data/spec/notifier/presently_spec.rb +181 -0
- data/spec/notifier/prowl_spec.rb +117 -0
- data/spec/notifier/twitter_spec.rb +132 -0
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +225 -0
- data/spec/pipeline_spec.rb +257 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/splitter_spec.rb +120 -0
- data/spec/storage/base_spec.rb +160 -0
- data/spec/storage/cloudfiles_spec.rb +230 -0
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +370 -0
- data/spec/storage/ftp_spec.rb +247 -0
- data/spec/storage/local_spec.rb +235 -0
- data/spec/storage/ninefold_spec.rb +319 -0
- data/spec/storage/rsync_spec.rb +345 -0
- data/spec/storage/s3_spec.rb +221 -0
- data/spec/storage/scp_spec.rb +209 -0
- data/spec/storage/sftp_spec.rb +220 -0
- data/spec/syncer/base_spec.rb +22 -0
- data/spec/syncer/cloud_files_spec.rb +192 -0
- data/spec/syncer/rsync/base_spec.rb +118 -0
- data/spec/syncer/rsync/local_spec.rb +121 -0
- data/spec/syncer/rsync/pull_spec.rb +90 -0
- data/spec/syncer/rsync/push_spec.rb +327 -0
- data/spec/syncer/s3_spec.rb +192 -0
- data/spec/version_spec.rb +21 -0
- data/templates/cli/utility/archive +25 -0
- data/templates/cli/utility/compressor/bzip2 +7 -0
- data/templates/cli/utility/compressor/gzip +7 -0
- data/templates/cli/utility/compressor/lzma +7 -0
- data/templates/cli/utility/compressor/pbzip2 +7 -0
- data/templates/cli/utility/config +31 -0
- data/templates/cli/utility/database/mongodb +18 -0
- data/templates/cli/utility/database/mysql +21 -0
- data/templates/cli/utility/database/postgresql +17 -0
- data/templates/cli/utility/database/redis +16 -0
- data/templates/cli/utility/database/riak +11 -0
- data/templates/cli/utility/encryptor/gpg +12 -0
- data/templates/cli/utility/encryptor/openssl +9 -0
- data/templates/cli/utility/model.erb +23 -0
- data/templates/cli/utility/notifier/campfire +12 -0
- data/templates/cli/utility/notifier/hipchat +15 -0
- data/templates/cli/utility/notifier/mail +22 -0
- data/templates/cli/utility/notifier/presently +13 -0
- data/templates/cli/utility/notifier/prowl +11 -0
- data/templates/cli/utility/notifier/twitter +13 -0
- data/templates/cli/utility/splitter +7 -0
- data/templates/cli/utility/storage/cloud_files +22 -0
- data/templates/cli/utility/storage/dropbox +20 -0
- data/templates/cli/utility/storage/ftp +12 -0
- data/templates/cli/utility/storage/local +7 -0
- data/templates/cli/utility/storage/ninefold +9 -0
- data/templates/cli/utility/storage/rsync +11 -0
- data/templates/cli/utility/storage/s3 +19 -0
- data/templates/cli/utility/storage/scp +11 -0
- data/templates/cli/utility/storage/sftp +11 -0
- data/templates/cli/utility/syncer/cloud_files +48 -0
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/rsync_pull +17 -0
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/cli/utility/syncer/s3 +45 -0
- 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 +311 -0
data/lib/backup/model.rb
ADDED
|
@@ -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
|