backup 4.4.1 → 5.0.0.beta.1
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.
- checksums.yaml +5 -5
- data/LICENSE +19 -0
- data/README.md +1 -1
- data/lib/backup.rb +74 -78
- data/lib/backup/archive.rb +31 -32
- data/lib/backup/binder.rb +2 -6
- data/lib/backup/cleaner.rb +14 -18
- data/lib/backup/cli.rb +104 -108
- data/lib/backup/cloud_io/base.rb +4 -7
- data/lib/backup/cloud_io/cloud_files.rb +60 -62
- data/lib/backup/cloud_io/s3.rb +69 -76
- data/lib/backup/compressor/base.rb +4 -7
- data/lib/backup/compressor/bzip2.rb +3 -7
- data/lib/backup/compressor/custom.rb +2 -6
- data/lib/backup/compressor/gzip.rb +16 -17
- data/lib/backup/config.rb +17 -18
- data/lib/backup/config/dsl.rb +16 -17
- data/lib/backup/config/helpers.rb +10 -16
- data/lib/backup/database/base.rb +22 -21
- data/lib/backup/database/mongodb.rb +36 -37
- data/lib/backup/database/mysql.rb +40 -41
- data/lib/backup/database/openldap.rb +8 -10
- data/lib/backup/database/postgresql.rb +29 -30
- data/lib/backup/database/redis.rb +27 -30
- data/lib/backup/database/riak.rb +15 -18
- data/lib/backup/database/sqlite.rb +4 -6
- data/lib/backup/encryptor/base.rb +2 -4
- data/lib/backup/encryptor/gpg.rb +49 -59
- data/lib/backup/encryptor/open_ssl.rb +11 -14
- data/lib/backup/errors.rb +7 -12
- data/lib/backup/logger.rb +16 -18
- data/lib/backup/logger/console.rb +5 -8
- data/lib/backup/logger/fog_adapter.rb +2 -6
- data/lib/backup/logger/logfile.rb +10 -12
- data/lib/backup/logger/syslog.rb +2 -4
- data/lib/backup/model.rb +75 -40
- data/lib/backup/notifier/base.rb +24 -26
- data/lib/backup/notifier/campfire.rb +9 -11
- data/lib/backup/notifier/command.rb +0 -3
- data/lib/backup/notifier/datadog.rb +9 -12
- data/lib/backup/notifier/flowdock.rb +13 -17
- data/lib/backup/notifier/hipchat.rb +11 -13
- data/lib/backup/notifier/http_post.rb +11 -14
- data/lib/backup/notifier/mail.rb +44 -47
- data/lib/backup/notifier/nagios.rb +5 -9
- data/lib/backup/notifier/pagerduty.rb +10 -12
- data/lib/backup/notifier/prowl.rb +15 -15
- data/lib/backup/notifier/pushover.rb +7 -10
- data/lib/backup/notifier/ses.rb +34 -16
- data/lib/backup/notifier/slack.rb +39 -40
- data/lib/backup/notifier/twitter.rb +2 -5
- data/lib/backup/notifier/zabbix.rb +11 -14
- data/lib/backup/package.rb +5 -9
- data/lib/backup/packager.rb +16 -17
- data/lib/backup/pipeline.rb +17 -21
- data/lib/backup/splitter.rb +8 -11
- data/lib/backup/storage/base.rb +5 -8
- data/lib/backup/storage/cloud_files.rb +21 -23
- data/lib/backup/storage/cycler.rb +10 -15
- data/lib/backup/storage/dropbox.rb +15 -21
- data/lib/backup/storage/ftp.rb +8 -10
- data/lib/backup/storage/local.rb +5 -8
- data/lib/backup/storage/qiniu.rb +8 -8
- data/lib/backup/storage/rsync.rb +24 -26
- data/lib/backup/storage/s3.rb +27 -28
- data/lib/backup/storage/scp.rb +10 -12
- data/lib/backup/storage/sftp.rb +10 -12
- data/lib/backup/syncer/base.rb +5 -8
- data/lib/backup/syncer/cloud/base.rb +27 -30
- data/lib/backup/syncer/cloud/cloud_files.rb +16 -18
- data/lib/backup/syncer/cloud/local_file.rb +5 -8
- data/lib/backup/syncer/cloud/s3.rb +23 -24
- data/lib/backup/syncer/rsync/base.rb +6 -10
- data/lib/backup/syncer/rsync/local.rb +1 -5
- data/lib/backup/syncer/rsync/pull.rb +6 -10
- data/lib/backup/syncer/rsync/push.rb +18 -22
- data/lib/backup/template.rb +9 -14
- data/lib/backup/utilities.rb +82 -69
- data/lib/backup/version.rb +1 -3
- metadata +100 -660
@@ -1,9 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
module Encryptor
|
5
3
|
class OpenSSL < Base
|
6
|
-
|
7
4
|
##
|
8
5
|
# The password that'll be used to encrypt the backup. This
|
9
6
|
# password will be required to decrypt the backup later on.
|
@@ -42,7 +39,7 @@ module Backup
|
|
42
39
|
# so that any clean-up may be performed after the yield.
|
43
40
|
def encrypt_with
|
44
41
|
log!
|
45
|
-
yield "#{
|
42
|
+
yield "#{utility(:openssl)} #{options}", ".enc"
|
46
43
|
end
|
47
44
|
|
48
45
|
private
|
@@ -59,19 +56,19 @@ module Backup
|
|
59
56
|
# Always sets a password option, if even no password is given,
|
60
57
|
# but will prefer the password_file option if both are given.
|
61
58
|
def options
|
62
|
-
opts = [
|
63
|
-
opts <<
|
64
|
-
opts <<
|
59
|
+
opts = ["aes-256-cbc"]
|
60
|
+
opts << "-base64" if @base64
|
61
|
+
opts << "-salt" if @salt
|
65
62
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
opts <<
|
64
|
+
if @password_file.to_s.empty?
|
65
|
+
"-k #{Shellwords.escape(@password)}"
|
66
|
+
else
|
67
|
+
"-pass file:#{@password_file}"
|
68
|
+
end
|
71
69
|
|
72
|
-
opts.join(
|
70
|
+
opts.join(" ")
|
73
71
|
end
|
74
|
-
|
75
72
|
end
|
76
73
|
end
|
77
74
|
end
|
data/lib/backup/errors.rb
CHANGED
@@ -1,29 +1,25 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
|
-
|
5
2
|
# Provides cascading errors with formatted messages.
|
6
3
|
# See the specs for details.
|
7
4
|
module NestedExceptions
|
8
|
-
|
9
5
|
def self.included(klass)
|
10
|
-
klass.extend
|
6
|
+
klass.extend(Module.new do
|
11
7
|
def wrap(wrapped_exception, msg = nil)
|
12
8
|
new(msg, wrapped_exception)
|
13
9
|
end
|
14
|
-
|
10
|
+
end)
|
15
11
|
end
|
16
12
|
|
17
13
|
def initialize(obj = nil, wrapped_exception = nil)
|
18
14
|
@wrapped_exception = wrapped_exception
|
19
|
-
msg = (obj.respond_to?(:to_str) ? obj.to_str : obj.to_s)
|
20
|
-
|
21
|
-
msg = clean_name(self.class.name) + (msg.empty? ?
|
15
|
+
msg = (obj.respond_to?(:to_str) ? obj.to_str : obj.to_s)
|
16
|
+
.gsub(/^ */, " ").strip
|
17
|
+
msg = clean_name(self.class.name) + (msg.empty? ? "" : ": #{msg}")
|
22
18
|
|
23
19
|
if wrapped_exception
|
24
20
|
msg << "\n--- Wrapped Exception ---\n"
|
25
21
|
class_name = clean_name(wrapped_exception.class.name)
|
26
|
-
msg << class_name +
|
22
|
+
msg << class_name + ": " unless
|
27
23
|
wrapped_exception.message.start_with? class_name
|
28
24
|
msg << wrapped_exception.message
|
29
25
|
end
|
@@ -43,9 +39,8 @@ module Backup
|
|
43
39
|
private
|
44
40
|
|
45
41
|
def clean_name(name)
|
46
|
-
name.sub(/^Backup::/,
|
42
|
+
name.sub(/^Backup::/, "")
|
47
43
|
end
|
48
|
-
|
49
44
|
end
|
50
45
|
|
51
46
|
class Error < StandardError
|
data/lib/backup/logger.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require 'backup/logger/syslog'
|
6
|
-
require 'backup/logger/fog_adapter'
|
1
|
+
require "backup/logger/console"
|
2
|
+
require "backup/logger/logfile"
|
3
|
+
require "backup/logger/syslog"
|
4
|
+
require "backup/logger/fog_adapter"
|
7
5
|
|
8
6
|
module Backup
|
9
7
|
class Logger
|
10
|
-
|
11
8
|
class Config
|
12
9
|
class Logger < Struct.new(:class, :options)
|
13
10
|
def enabled?
|
@@ -44,22 +41,22 @@ module Backup
|
|
44
41
|
# [YYYY/MM/DD HH:MM:SS][level] message line text
|
45
42
|
def formatted_lines
|
46
43
|
timestamp = time.strftime("%Y/%m/%d %H:%M:%S")
|
47
|
-
lines.map {|line| "[#{
|
44
|
+
lines.map { |line| "[#{timestamp}][#{level}] #{line}" }
|
48
45
|
end
|
49
46
|
|
50
47
|
def matches?(ignores)
|
51
48
|
text = lines.join("\n")
|
52
|
-
ignores.any?
|
49
|
+
ignores.any? do |obj|
|
53
50
|
obj.is_a?(Regexp) ? text.match(obj) : text.include?(obj)
|
54
|
-
|
51
|
+
end
|
55
52
|
end
|
56
53
|
end
|
57
54
|
|
58
55
|
class << self
|
59
56
|
extend Forwardable
|
60
57
|
def_delegators :logger,
|
61
|
-
|
62
|
-
|
58
|
+
:start!, :abort!, :info, :warn, :error,
|
59
|
+
:messages, :has_warnings?, :has_errors?
|
63
60
|
|
64
61
|
##
|
65
62
|
# Allows the Logger to be configured.
|
@@ -137,9 +134,9 @@ module Backup
|
|
137
134
|
# Sends a message to the Logger using the specified log level.
|
138
135
|
# +obj+ may be any Object that responds to #to_s (i.e. an Exception)
|
139
136
|
[:info, :warn, :error].each do |level|
|
140
|
-
define_method level
|
137
|
+
define_method level do |obj|
|
141
138
|
MUTEX.synchronize { log(obj, level) }
|
142
|
-
|
139
|
+
end
|
143
140
|
end
|
144
141
|
|
145
142
|
##
|
@@ -169,7 +166,7 @@ module Backup
|
|
169
166
|
@loggers << logger.class.new(logger.options) if logger.enabled?
|
170
167
|
end
|
171
168
|
messages.each do |message|
|
172
|
-
@loggers.each {|logger| logger.log(message) }
|
169
|
+
@loggers.each { |logger| logger.log(message) }
|
173
170
|
end
|
174
171
|
end
|
175
172
|
|
@@ -187,13 +184,14 @@ module Backup
|
|
187
184
|
def log(obj, level)
|
188
185
|
message = Message.new(Time.now.utc, level, obj.to_s.split("\n"))
|
189
186
|
|
190
|
-
|
191
|
-
|
187
|
+
if message.level == :warn && message.matches?(@config.ignores)
|
188
|
+
message.level = :info
|
189
|
+
end
|
192
190
|
@has_warnings ||= message.level == :warn
|
193
191
|
@has_errors ||= message.level == :error
|
194
192
|
|
195
193
|
messages << message
|
196
|
-
@loggers.each {|logger| logger.log(message) }
|
194
|
+
@loggers.each { |logger| logger.log(message) }
|
197
195
|
end
|
198
196
|
end
|
199
197
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
class Logger
|
5
3
|
class Console
|
@@ -30,22 +28,21 @@ module Backup
|
|
30
28
|
end
|
31
29
|
|
32
30
|
COLORS = {
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
31
|
+
info: "\e[32m%s\e[0m", # green
|
32
|
+
warn: "\e[33m%s\e[0m", # yellow
|
33
|
+
error: "\e[31m%s\e[0m" # red
|
36
34
|
}
|
37
35
|
|
38
|
-
def initialize(
|
36
|
+
def initialize(_options = nil)
|
39
37
|
$stdout.sync = $stderr.sync = true
|
40
38
|
end
|
41
39
|
|
42
40
|
def log(message)
|
43
41
|
io = message.level == :info ? $stdout : $stderr
|
44
42
|
lines = message.formatted_lines
|
45
|
-
lines.map! {|line| COLORS[message.level] % line } if io.tty?
|
43
|
+
lines.map! { |line| COLORS[message.level] % line } if io.tty?
|
46
44
|
io.puts lines
|
47
45
|
end
|
48
|
-
|
49
46
|
end
|
50
47
|
end
|
51
48
|
end
|
@@ -1,14 +1,11 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# require only the logger
|
4
|
-
require
|
5
|
-
require
|
2
|
+
require "formatador"
|
3
|
+
require "fog/core/logger"
|
6
4
|
|
7
5
|
module Backup
|
8
6
|
class Logger
|
9
7
|
module FogAdapter
|
10
8
|
class << self
|
11
|
-
|
12
9
|
# Logged as :info so these won't generate warnings.
|
13
10
|
# This is mostly to keep STDOUT clean and to provide
|
14
11
|
# supplemental messages for our own warnings.
|
@@ -20,7 +17,6 @@ module Backup
|
|
20
17
|
def tty?
|
21
18
|
false
|
22
19
|
end
|
23
|
-
|
24
20
|
end
|
25
21
|
end
|
26
22
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
class Logger
|
5
3
|
class Logfile
|
@@ -60,7 +58,7 @@ module Backup
|
|
60
58
|
|
61
59
|
def initialize
|
62
60
|
@enabled = true
|
63
|
-
@log_path =
|
61
|
+
@log_path = ""
|
64
62
|
@max_bytes = 500_000
|
65
63
|
end
|
66
64
|
|
@@ -84,7 +82,7 @@ module Backup
|
|
84
82
|
end
|
85
83
|
|
86
84
|
def log(message)
|
87
|
-
File.open(@logfile,
|
85
|
+
File.open(@logfile, "a") { |f| f.puts message.formatted_lines }
|
88
86
|
end
|
89
87
|
|
90
88
|
private
|
@@ -95,17 +93,17 @@ module Backup
|
|
95
93
|
def setup_logfile
|
96
94
|
# strip any trailing '/' in case the user supplied this as part of
|
97
95
|
# an absolute path, so we can match it against File.expand_path()
|
98
|
-
path = @options.log_path.chomp(
|
96
|
+
path = @options.log_path.chomp("/")
|
99
97
|
if path.empty?
|
100
|
-
path = File.join(Backup::Config.root_path,
|
98
|
+
path = File.join(Backup::Config.root_path, "log")
|
101
99
|
elsif path != File.expand_path(path)
|
102
100
|
path = File.join(Backup::Config.root_path, path)
|
103
101
|
end
|
104
102
|
FileUtils.mkdir_p(path)
|
105
|
-
log_file = @options.log_file ||
|
103
|
+
log_file = @options.log_file || "backup.log"
|
106
104
|
path = File.join(path, log_file)
|
107
105
|
if File.exist?(path) && !File.writable?(path)
|
108
|
-
raise Error, "Log File at '#{
|
106
|
+
raise Error, "Log File at '#{path}' is not writable"
|
109
107
|
end
|
110
108
|
path
|
111
109
|
end
|
@@ -116,16 +114,16 @@ module Backup
|
|
116
114
|
return unless File.exist?(@logfile)
|
117
115
|
|
118
116
|
if File.stat(@logfile).size > @options.max_bytes
|
119
|
-
FileUtils.cp(@logfile, @logfile +
|
120
|
-
File.open(@logfile +
|
121
|
-
File.open(@logfile,
|
117
|
+
FileUtils.cp(@logfile, @logfile + "~")
|
118
|
+
File.open(@logfile + "~", "r") do |io_in|
|
119
|
+
File.open(@logfile, "w") do |io_out|
|
122
120
|
io_in.seek(-@options.max_bytes, IO::SEEK_END) && io_in.gets
|
123
121
|
while line = io_in.gets
|
124
122
|
io_out.puts line
|
125
123
|
end
|
126
124
|
end
|
127
125
|
end
|
128
|
-
FileUtils.rm_f(@logfile +
|
126
|
+
FileUtils.rm_f(@logfile + "~")
|
129
127
|
end
|
130
128
|
end
|
131
129
|
end
|
data/lib/backup/logger/syslog.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
class Logger
|
5
3
|
class Syslog
|
@@ -81,7 +79,7 @@ module Backup
|
|
81
79
|
|
82
80
|
def initialize
|
83
81
|
@enabled = false
|
84
|
-
@ident =
|
82
|
+
@ident = "backup"
|
85
83
|
@options = ::Syslog::LOG_PID
|
86
84
|
@facility = ::Syslog::LOG_LOCAL0
|
87
85
|
@info = ::Syslog::LOG_INFO
|
@@ -108,7 +106,7 @@ module Backup
|
|
108
106
|
def log(message)
|
109
107
|
level = @options.send(message.level)
|
110
108
|
::Syslog.open(@options.ident, @options.options, @options.facility) do |s|
|
111
|
-
message.lines.each {|line| s.log(level,
|
109
|
+
message.lines.each { |line| s.log(level, "%s", line) }
|
112
110
|
end
|
113
111
|
end
|
114
112
|
end
|
data/lib/backup/model.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
class Model
|
5
3
|
class Error < Backup::Error; end
|
6
4
|
class FatalError < Backup::FatalError; end
|
7
5
|
|
6
|
+
DEPRECATED_MODULES = %w[
|
7
|
+
Campfire
|
8
|
+
CloudFiles
|
9
|
+
FTP
|
10
|
+
Nagios
|
11
|
+
OpenLDAP
|
12
|
+
Prowl
|
13
|
+
Riak
|
14
|
+
Twitter
|
15
|
+
Zabbix
|
16
|
+
].freeze
|
17
|
+
|
8
18
|
class << self
|
9
19
|
##
|
10
20
|
# The Backup::Model.all class method keeps track of all the models
|
@@ -18,11 +28,11 @@ module Backup
|
|
18
28
|
# Return an Array of Models matching the given +trigger+.
|
19
29
|
def find_by_trigger(trigger)
|
20
30
|
trigger = trigger.to_s
|
21
|
-
if trigger.include?(
|
31
|
+
if trigger.include?("*")
|
22
32
|
regex = /^#{ trigger.gsub('*', '(.*)') }$/
|
23
|
-
all.select {|model| regex =~ model.trigger }
|
33
|
+
all.select { |model| regex =~ model.trigger }
|
24
34
|
else
|
25
|
-
all.select {|model| trigger == model.trigger }
|
35
|
+
all.select { |model| trigger == model.trigger }
|
26
36
|
end
|
27
37
|
end
|
28
38
|
|
@@ -128,7 +138,7 @@ module Backup
|
|
128
138
|
|
129
139
|
# trigger all defined databases to generate their #dump_filename
|
130
140
|
# so warnings may be logged if `backup perform --check` is used
|
131
|
-
databases.each {|db| db.send(:dump_filename) }
|
141
|
+
databases.each { |db| db.send(:dump_filename) }
|
132
142
|
|
133
143
|
Model.all << self
|
134
144
|
end
|
@@ -142,26 +152,48 @@ module Backup
|
|
142
152
|
##
|
143
153
|
# Adds an Database. Multiple Databases may be added to the model.
|
144
154
|
def database(name, database_id = nil, &block)
|
145
|
-
|
146
|
-
|
155
|
+
dsl_name = dsl_const_name(name)
|
156
|
+
if deprecated_module? dsl_name
|
157
|
+
Logger.warn "The Backup database \"#{dsl_name}\" is " \
|
158
|
+
"scheduled to be deprecated. If you're using this feature, " \
|
159
|
+
"please see: https://github.com/backup/backup/issues/851"
|
160
|
+
end
|
161
|
+
@databases << get_class_from_scope(Database, name)
|
162
|
+
.new(self, database_id, &block)
|
147
163
|
end
|
148
164
|
|
149
165
|
##
|
150
166
|
# Adds an Storage. Multiple Storages may be added to the model.
|
151
167
|
def store_with(name, storage_id = nil, &block)
|
152
|
-
|
153
|
-
|
168
|
+
dsl_name = dsl_const_name(name)
|
169
|
+
if deprecated_module? dsl_name
|
170
|
+
Logger.warn "The Backup storage \"#{dsl_name}\" is " \
|
171
|
+
"scheduled to be deprecated. If you're using this feature, " \
|
172
|
+
"please see: https://github.com/backup/backup/issues/851"
|
173
|
+
end
|
174
|
+
@storages << get_class_from_scope(Storage, name)
|
175
|
+
.new(self, storage_id, &block)
|
154
176
|
end
|
155
177
|
|
156
178
|
##
|
157
179
|
# Adds an Syncer. Multiple Syncers may be added to the model.
|
158
180
|
def sync_with(name, syncer_id = nil, &block)
|
181
|
+
dsl_name = dsl_const_name(name)
|
182
|
+
Logger.warn "The Backup syncer \"#{dsl_name}\" is " \
|
183
|
+
"scheduled to be deprecated. If you're using this feature, " \
|
184
|
+
"please see: https://github.com/backup/backup/issues/851"
|
159
185
|
@syncers << get_class_from_scope(Syncer, name).new(syncer_id, &block)
|
160
186
|
end
|
161
187
|
|
162
188
|
##
|
163
189
|
# Adds an Notifier. Multiple Notifiers may be added to the model.
|
164
190
|
def notify_by(name, &block)
|
191
|
+
dsl_name = dsl_const_name(name)
|
192
|
+
if deprecated_module? dsl_name
|
193
|
+
Logger.warn "The Backup notifier \"#{dsl_name}\" is " \
|
194
|
+
"scheduled to be deprecated. If you're using this feature, " \
|
195
|
+
"please see: https://github.com/backup/backup/issues/851"
|
196
|
+
end
|
165
197
|
@notifiers << get_class_from_scope(Notifier, name).new(self, &block)
|
166
198
|
end
|
167
199
|
|
@@ -270,14 +302,11 @@ module Backup
|
|
270
302
|
end
|
271
303
|
|
272
304
|
syncers.each(&:perform!)
|
273
|
-
|
274
305
|
rescue Interrupt
|
275
306
|
@interrupted = true
|
276
307
|
raise
|
277
|
-
|
278
308
|
rescue Exception => err
|
279
309
|
@exception = err
|
280
|
-
|
281
310
|
ensure
|
282
311
|
unless @interrupted
|
283
312
|
set_exit_status
|
@@ -296,14 +325,22 @@ module Backup
|
|
296
325
|
|
297
326
|
private
|
298
327
|
|
328
|
+
def dsl_const_name(name)
|
329
|
+
name.to_s.sub "Backup::Config::DSL::", ""
|
330
|
+
end
|
331
|
+
|
332
|
+
def deprecated_module?(name)
|
333
|
+
DEPRECATED_MODULES.include? name
|
334
|
+
end
|
335
|
+
|
299
336
|
##
|
300
337
|
# Returns an array of procedures that will be performed if any
|
301
338
|
# Archives or Databases are configured for the model.
|
302
339
|
def procedures
|
303
340
|
return [] unless databases.any? || archives.any?
|
304
341
|
|
305
|
-
[
|
306
|
-
|
342
|
+
[-> { prepare! }, databases, archives,
|
343
|
+
-> { package! }, -> { store! }, -> { clean! }]
|
307
344
|
end
|
308
345
|
|
309
346
|
##
|
@@ -341,8 +378,8 @@ module Backup
|
|
341
378
|
|
342
379
|
if first_exception
|
343
380
|
other_exceptions.each do |exception|
|
344
|
-
|
345
|
-
|
381
|
+
Logger.error exception.to_s
|
382
|
+
Logger.error exception.backtrace.join('\n')
|
346
383
|
end
|
347
384
|
raise first_exception
|
348
385
|
else
|
@@ -375,8 +412,8 @@ module Backup
|
|
375
412
|
#
|
376
413
|
def get_class_from_scope(scope, name)
|
377
414
|
klass = scope
|
378
|
-
name = name.to_s.sub(/^Backup::Config::DSL::/,
|
379
|
-
name.split(
|
415
|
+
name = name.to_s.sub(/^Backup::Config::DSL::/, "")
|
416
|
+
name.split("::").each do |chunk|
|
380
417
|
klass = klass.const_get(chunk)
|
381
418
|
end
|
382
419
|
klass
|
@@ -385,11 +422,12 @@ module Backup
|
|
385
422
|
##
|
386
423
|
# Sets or updates the model's #exit_status.
|
387
424
|
def set_exit_status
|
388
|
-
@exit_status =
|
389
|
-
exception
|
390
|
-
|
391
|
-
|
392
|
-
|
425
|
+
@exit_status =
|
426
|
+
if exception
|
427
|
+
exception.is_a?(StandardError) ? 2 : 3
|
428
|
+
else
|
429
|
+
Logger.has_warnings? ? 1 : 0
|
430
|
+
end
|
393
431
|
end
|
394
432
|
|
395
433
|
##
|
@@ -401,14 +439,13 @@ module Backup
|
|
401
439
|
def before_hook
|
402
440
|
return unless before
|
403
441
|
|
404
|
-
Logger.info
|
442
|
+
Logger.info "Before Hook Starting..."
|
405
443
|
before.call
|
406
|
-
Logger.info
|
407
|
-
|
444
|
+
Logger.info "Before Hook Finished."
|
408
445
|
rescue Exception => err
|
409
446
|
@before_hook_failed = true
|
410
447
|
ex = err.is_a?(StandardError) ? Error : FatalError
|
411
|
-
raise ex.wrap(err,
|
448
|
+
raise ex.wrap(err, "Before Hook Failed!")
|
412
449
|
end
|
413
450
|
|
414
451
|
##
|
@@ -418,16 +455,15 @@ module Backup
|
|
418
455
|
def after_hook
|
419
456
|
return unless after && !@before_hook_failed
|
420
457
|
|
421
|
-
Logger.info
|
458
|
+
Logger.info "After Hook Starting..."
|
422
459
|
after.call(exit_status)
|
423
|
-
Logger.info
|
460
|
+
Logger.info "After Hook Finished."
|
424
461
|
|
425
462
|
set_exit_status # in case hook logged warnings
|
426
|
-
|
427
463
|
rescue Exception => err
|
428
464
|
fatal = !err.is_a?(StandardError)
|
429
465
|
ex = fatal ? FatalError : Error
|
430
|
-
Logger.error ex.wrap(err,
|
466
|
+
Logger.error ex.wrap(err, "After Hook Failed!")
|
431
467
|
# upgrade exit_status if needed
|
432
468
|
(@exit_status = fatal ? 3 : 2) unless exit_status == 3
|
433
469
|
end
|
@@ -440,24 +476,24 @@ module Backup
|
|
440
476
|
def log!(action)
|
441
477
|
case action
|
442
478
|
when :started
|
443
|
-
Logger.info "Performing Backup for '#{
|
444
|
-
"[ backup #{
|
479
|
+
Logger.info "Performing Backup for '#{label} (#{trigger})'!\n" \
|
480
|
+
"[ backup #{VERSION} : #{RUBY_DESCRIPTION} ]"
|
445
481
|
|
446
482
|
when :finished
|
447
483
|
if exit_status > 1
|
448
484
|
ex = exit_status == 2 ? Error : FatalError
|
449
|
-
err = ex.wrap(exception, "Backup for #{
|
485
|
+
err = ex.wrap(exception, "Backup for #{label} (#{trigger}) Failed!")
|
450
486
|
Logger.error err
|
451
487
|
Logger.error "\nBacktrace:\n\s\s" + err.backtrace.join("\n\s\s") + "\n\n"
|
452
488
|
|
453
489
|
Cleaner.warnings(self)
|
454
490
|
else
|
455
|
-
msg = "Backup for '#{
|
491
|
+
msg = "Backup for '#{label} (#{trigger})' "
|
456
492
|
if exit_status == 1
|
457
|
-
msg << "Completed Successfully (with Warnings) in #{
|
493
|
+
msg << "Completed Successfully (with Warnings) in #{duration}"
|
458
494
|
Logger.warn msg
|
459
495
|
else
|
460
|
-
msg << "Completed Successfully in #{
|
496
|
+
msg << "Completed Successfully in #{duration}"
|
461
497
|
Logger.info msg
|
462
498
|
end
|
463
499
|
end
|
@@ -472,8 +508,7 @@ module Backup
|
|
472
508
|
remainder = duration - (hours * 3600)
|
473
509
|
minutes = remainder / 60
|
474
510
|
seconds = remainder - (minutes * 60)
|
475
|
-
|
511
|
+
sprintf "%02d:%02d:%02d", hours, minutes, seconds
|
476
512
|
end
|
477
|
-
|
478
513
|
end
|
479
514
|
end
|