backup_zh 4.0.3.1 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -7
- data/lib/backup.rb +6 -0
- data/lib/backup/cli.rb +10 -0
- data/lib/backup/config/dsl.rb +3 -3
- data/lib/backup/database/mysql.rb +17 -6
- data/lib/backup/database/postgresql.rb +2 -2
- data/lib/backup/database/sqlite.rb +57 -0
- data/lib/backup/encryptor/open_ssl.rb +7 -2
- data/lib/backup/model.rb +26 -1
- data/lib/backup/notifier/base.rb +30 -0
- data/lib/backup/notifier/campfire.rb +1 -7
- data/lib/backup/notifier/command.rb +99 -0
- data/lib/backup/notifier/datadog.rb +107 -0
- data/lib/backup/notifier/flowdock.rb +6 -5
- data/lib/backup/notifier/hipchat.rb +27 -8
- data/lib/backup/notifier/http_post.rb +2 -7
- data/lib/backup/notifier/mail.rb +19 -10
- data/lib/backup/notifier/nagios.rb +3 -8
- data/lib/backup/notifier/pagerduty.rb +81 -0
- data/lib/backup/notifier/prowl.rb +8 -9
- data/lib/backup/notifier/pushover.rb +1 -7
- data/lib/backup/notifier/ses.rb +88 -0
- data/lib/backup/notifier/slack.rb +7 -17
- data/lib/backup/notifier/twitter.rb +1 -7
- data/lib/backup/notifier/zabbix.rb +1 -6
- data/lib/backup/package.rb +4 -0
- data/lib/backup/packager.rb +8 -2
- data/lib/backup/storage/base.rb +15 -3
- data/lib/backup/storage/cycler.rb +24 -14
- data/lib/backup/storage/ftp.rb +15 -1
- data/lib/backup/storage/s3.rb +2 -1
- data/lib/backup/syncer/base.rb +2 -2
- data/lib/backup/version.rb +1 -1
- data/templates/cli/config +2 -2
- data/templates/cli/databases/sqlite +11 -0
- data/templates/cli/model +1 -1
- data/templates/cli/notifiers/command +32 -0
- data/templates/cli/notifiers/datadog +57 -0
- data/templates/cli/notifiers/hipchat +1 -0
- data/templates/cli/notifiers/mail +3 -0
- data/templates/cli/notifiers/pagerduty +12 -0
- data/templates/cli/notifiers/ses +15 -0
- data/templates/cli/notifiers/slack +3 -4
- data/templates/cli/storages/dropbox +1 -0
- data/templates/cli/storages/ftp +1 -0
- data/templates/cli/storages/local +1 -0
- data/templates/cli/storages/ninefold +1 -0
- data/templates/cli/storages/s3 +2 -0
- data/templates/cli/storages/scp +1 -0
- data/templates/cli/storages/sftp +1 -0
- data/templates/general/links +3 -3
- metadata +53 -136
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fc3367bd1a9cebd38de0ac0c15c1b81dfaa3d2f
|
4
|
+
data.tar.gz: 986424c3cce771ff3e7dad33d6fa72437381387f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94aed25187160ef0525c37f22f8ddef4c0afbe54e60103d21e54446a60a1c1277837045ece5ffbf6d7270aba4149a7a040588512957ac50b5fa62f807e37850f
|
7
|
+
data.tar.gz: 34a46c8e8ad9d11611af22671ac1979f11a9c005baca98cfc56358c5a815b5ccf4d964afb5ecebc360f3f7ffa6ada951762564b6599b7e46256a12336e435585
|
data/README.md
CHANGED
@@ -1,21 +1,29 @@
|
|
1
1
|
Backup v4.x
|
2
2
|
===========
|
3
|
-
|
4
|
-
[![
|
3
|
+
|
4
|
+
[![Code Climate](https://codeclimate.com/github/backup/backup.png)](https://codeclimate.com/github/backup/backup)
|
5
|
+
[![Build Status](https://travis-ci.org/backup/backup.svg?branch=master)](https://travis-ci.org/backup/backup)
|
6
|
+
[![Join the chat at https://gitter.im/backup/backup](https://badges.gitter.im/Join%20Chat.svg)][Gitter]
|
5
7
|
|
6
8
|
Backup is a system utility for Linux and Mac OS X, distributed as a RubyGem, that allows you to easily perform backup
|
7
9
|
operations. It provides an elegant DSL in Ruby for _modeling_ your backups. Backup has built-in support for various
|
8
10
|
databases, storage protocols/services, syncers, compressors, encryptors and notifiers which you can mix and match. It
|
9
11
|
was built with modularity, extensibility and simplicity in mind.
|
10
12
|
|
11
|
-
[Installation][] · [Release Notes][] · [Documentation][]
|
13
|
+
[Installation][] · [Release Notes][] · [Documentation][] · [Issues][] · [Features][] · [Chat][Gitter]
|
12
14
|
|
15
|
+
Please use the Backup features [issue tracker][Features] to suggest new features.
|
16
|
+
Only use the Backup gem [issue tracker][Issues] for bugs and other issues.
|
17
|
+
We're also available on [Gitter][] for questions and problems.
|
13
18
|
|
14
|
-
**Copyright (c) 2009-
|
19
|
+
**Copyright (c) 2009-2015 [Michael van Rooijen][] ( [@meskyanichi][] )**
|
15
20
|
Released under the **MIT** [License](LICENSE.md).
|
16
21
|
|
17
|
-
[Installation]: http://
|
18
|
-
[Release Notes]: http://
|
19
|
-
[Documentation]: http://
|
22
|
+
[Installation]: http://backup.github.io/backup/v4/installation
|
23
|
+
[Release Notes]: http://backup.github.io/backup/v4/release-notes
|
24
|
+
[Documentation]: http://backup.github.io/backup/v4
|
25
|
+
[Issues]: https://github.com/backup/backup/issues
|
26
|
+
[Features]: https://github.com/backup/backup-features/issues
|
27
|
+
[Gitter]: https://gitter.im/backup/backup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
20
28
|
[Michael van Rooijen]: http://michaelvanrooijen.com
|
21
29
|
[@meskyanichi]: http://twitter.com/#!/meskyanichi
|
data/lib/backup.rb
CHANGED
@@ -11,6 +11,7 @@ require 'thread'
|
|
11
11
|
|
12
12
|
require 'open4'
|
13
13
|
require 'thor'
|
14
|
+
require 'shellwords'
|
14
15
|
|
15
16
|
require 'excon'
|
16
17
|
# Include response.inspect in error messages.
|
@@ -78,6 +79,7 @@ module Backup
|
|
78
79
|
autoload :Redis, File.join(DATABASE_PATH, 'redis')
|
79
80
|
autoload :Riak, File.join(DATABASE_PATH, 'riak')
|
80
81
|
autoload :OpenLDAP, File.join(DATABASE_PATH, 'openldap')
|
82
|
+
autoload :SQLite, File.join(DATABASE_PATH, 'sqlite')
|
81
83
|
end
|
82
84
|
|
83
85
|
##
|
@@ -106,12 +108,16 @@ module Backup
|
|
106
108
|
autoload :Campfire, File.join(NOTIFIER_PATH, 'campfire')
|
107
109
|
autoload :Prowl, File.join(NOTIFIER_PATH, 'prowl')
|
108
110
|
autoload :Hipchat, File.join(NOTIFIER_PATH, 'hipchat')
|
111
|
+
autoload :PagerDuty, File.join(NOTIFIER_PATH, 'pagerduty')
|
109
112
|
autoload :Pushover, File.join(NOTIFIER_PATH, 'pushover')
|
110
113
|
autoload :Slack, File.join(NOTIFIER_PATH, 'slack')
|
111
114
|
autoload :HttpPost, File.join(NOTIFIER_PATH, 'http_post')
|
112
115
|
autoload :Nagios, File.join(NOTIFIER_PATH, 'nagios')
|
113
116
|
autoload :FlowDock, File.join(NOTIFIER_PATH, 'flowdock')
|
114
117
|
autoload :Zabbix, File.join(NOTIFIER_PATH, 'zabbix')
|
118
|
+
autoload :DataDog, File.join(NOTIFIER_PATH, 'datadog')
|
119
|
+
autoload :Ses, File.join(NOTIFIER_PATH, 'ses')
|
120
|
+
autoload :Command, File.join(NOTIFIER_PATH, 'command')
|
115
121
|
end
|
116
122
|
|
117
123
|
##
|
data/lib/backup/cli.rb
CHANGED
@@ -142,6 +142,9 @@ module Backup
|
|
142
142
|
|
143
143
|
rescue Exception => err
|
144
144
|
Logger.error Error.wrap(err)
|
145
|
+
unless Helpers.is_backup_error? err
|
146
|
+
Logger.error err.backtrace.join("\n")
|
147
|
+
end
|
145
148
|
# Logger configuration will be ignored
|
146
149
|
# and messages will be output to the console only.
|
147
150
|
Logger.abort!
|
@@ -219,6 +222,9 @@ module Backup
|
|
219
222
|
Config.load(options)
|
220
223
|
rescue Exception => err
|
221
224
|
Logger.error Error.wrap(err)
|
225
|
+
unless Helpers.is_backup_error? err
|
226
|
+
Logger.error err.backtrace.join("\n")
|
227
|
+
end
|
222
228
|
end
|
223
229
|
|
224
230
|
if Logger.has_warnings? || Logger.has_errors?
|
@@ -357,6 +363,10 @@ module Backup
|
|
357
363
|
exec(cmd)
|
358
364
|
end
|
359
365
|
|
366
|
+
def is_backup_error?(error)
|
367
|
+
error.class.ancestors.include? Backup::Error
|
368
|
+
end
|
369
|
+
|
360
370
|
end
|
361
371
|
end
|
362
372
|
|
data/lib/backup/config/dsl.rb
CHANGED
@@ -27,7 +27,7 @@ module Backup
|
|
27
27
|
create_modules(
|
28
28
|
DSL,
|
29
29
|
[ # Databases
|
30
|
-
['MySQL', 'PostgreSQL', 'MongoDB', 'Redis', 'Riak', 'OpenLDAP'],
|
30
|
+
['MySQL', 'PostgreSQL', 'MongoDB', 'Redis', 'Riak', 'OpenLDAP', 'SQLite'],
|
31
31
|
# Storages
|
32
32
|
['S3', 'CloudFiles', 'Ninefold', 'Dropbox', 'FTP',
|
33
33
|
'SFTP', 'SCP', 'RSync', 'Local', 'QiNiu'],
|
@@ -42,8 +42,8 @@ module Backup
|
|
42
42
|
],
|
43
43
|
# Notifiers
|
44
44
|
['Mail', 'Twitter', 'Campfire', 'Prowl',
|
45
|
-
'Hipchat', 'Pushover', 'HttpPost', 'Nagios',
|
46
|
-
'Slack', 'FlowDock', 'Zabbix']
|
45
|
+
'Hipchat', 'PagerDuty', 'Pushover', 'HttpPost', 'Nagios',
|
46
|
+
'Slack', 'FlowDock', 'Zabbix', 'Ses', 'DataDog', 'Command']
|
47
47
|
]
|
48
48
|
)
|
49
49
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'shellwords'
|
3
2
|
|
4
3
|
module Backup
|
5
4
|
module Database
|
@@ -47,6 +46,12 @@ module Backup
|
|
47
46
|
# See: http://www.percona.com/doc/percona-xtrabackup/
|
48
47
|
attr_accessor :backup_engine
|
49
48
|
|
49
|
+
##
|
50
|
+
# If true (which is the default behaviour), the backup will be prepared
|
51
|
+
# after it has been successfuly created. This option is only valid if
|
52
|
+
# :backup_engine is set to :innobackupex.
|
53
|
+
attr_accessor :prepare_backup
|
54
|
+
|
50
55
|
##
|
51
56
|
# If set the backup engine command block is executed as the given user
|
52
57
|
attr_accessor :sudo_user
|
@@ -61,6 +66,7 @@ module Backup
|
|
61
66
|
|
62
67
|
@name ||= :all
|
63
68
|
@backup_engine ||= :mysqldump
|
69
|
+
@prepare_backup = true if @prepare_backup.nil?
|
64
70
|
end
|
65
71
|
|
66
72
|
##
|
@@ -95,8 +101,8 @@ module Backup
|
|
95
101
|
private
|
96
102
|
|
97
103
|
def mysqldump
|
98
|
-
"#{ utility(:mysqldump) } #{ credential_options } " +
|
99
|
-
"#{ connectivity_options } #{
|
104
|
+
"#{ utility(:mysqldump) } #{ user_options } #{ credential_options } " +
|
105
|
+
"#{ connectivity_options } #{ name_option } " +
|
100
106
|
"#{ tables_to_dump } #{ tables_to_skip }"
|
101
107
|
end
|
102
108
|
|
@@ -152,14 +158,19 @@ module Backup
|
|
152
158
|
"#{ utility(:innobackupex) } #{ credential_options } " +
|
153
159
|
"#{ connectivity_options } #{ user_options } " +
|
154
160
|
"--no-timestamp #{ temp_dir } #{ quiet_option } && " +
|
155
|
-
|
156
|
-
"#{ utility(:innobackupex) } --apply-log #{ temp_dir } " +
|
157
|
-
"#{ user_prepare_options } #{ quiet_option } && " +
|
161
|
+
innobackupex_prepare +
|
158
162
|
# Move files to tar-ed stream on stdout
|
159
163
|
"#{ utility(:tar) } --remove-files -cf - " +
|
160
164
|
"-C #{ File.dirname(temp_dir) } #{ File.basename(temp_dir) }"
|
161
165
|
end
|
162
166
|
|
167
|
+
def innobackupex_prepare
|
168
|
+
return "" unless @prepare_backup
|
169
|
+
# Log applying phase (prepare for restore)
|
170
|
+
"#{ utility(:innobackupex) } --apply-log #{ temp_dir } " +
|
171
|
+
"#{ user_prepare_options } #{ quiet_option } && "
|
172
|
+
end
|
173
|
+
|
163
174
|
def sudo_option(command_block)
|
164
175
|
return command_block unless sudo_user
|
165
176
|
|
@@ -88,7 +88,7 @@ module Backup
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def password_option
|
91
|
-
"PGPASSWORD
|
91
|
+
"PGPASSWORD=#{ Shellwords.escape(password) } " if password
|
92
92
|
end
|
93
93
|
|
94
94
|
def sudo_option
|
@@ -96,7 +96,7 @@ module Backup
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def username_option
|
99
|
-
"--username
|
99
|
+
"--username=#{ Shellwords.escape(username) }" if username
|
100
100
|
end
|
101
101
|
|
102
102
|
def connectivity_options
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Backup
|
4
|
+
module Database
|
5
|
+
class SQLite < Base
|
6
|
+
class Error < Backup::Error; end
|
7
|
+
|
8
|
+
##
|
9
|
+
# Path to the sqlite3 file
|
10
|
+
attr_accessor :path
|
11
|
+
|
12
|
+
##
|
13
|
+
# Path to sqlite utility (optional)
|
14
|
+
attr_accessor :sqlitedump_utility
|
15
|
+
|
16
|
+
##
|
17
|
+
# Creates a new instance of the SQLite adapter object
|
18
|
+
def initialize(model, database_id = nil, &block)
|
19
|
+
super
|
20
|
+
instance_eval(&block) if block_given?
|
21
|
+
|
22
|
+
@sqlitedump_utility ||= utility(:sqlitedump)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Performs the sqlitedump command and outputs the
|
27
|
+
# data to the specified path based on the 'trigger'
|
28
|
+
def perform!
|
29
|
+
super
|
30
|
+
|
31
|
+
dump = "echo '.dump' | #{ sqlitedump_utility } #{ path }"
|
32
|
+
|
33
|
+
pipeline = Pipeline.new
|
34
|
+
dump_ext = 'sql'
|
35
|
+
|
36
|
+
pipeline << dump
|
37
|
+
if model.compressor
|
38
|
+
model.compressor.compress_with do |command, ext|
|
39
|
+
pipeline << command
|
40
|
+
dump_ext << ext
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
pipeline << "cat > '#{ File.join( dump_path , dump_filename) }.#{ dump_ext }'"
|
45
|
+
|
46
|
+
pipeline.run
|
47
|
+
|
48
|
+
if pipeline.success?
|
49
|
+
log!(:finished)
|
50
|
+
else
|
51
|
+
raise Error,
|
52
|
+
"#{ database_name } Dump Failed!\n" + pipeline.error_messages
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -62,8 +62,13 @@ module Backup
|
|
62
62
|
opts = ['aes-256-cbc']
|
63
63
|
opts << '-base64' if @base64
|
64
64
|
opts << '-salt' if @salt
|
65
|
-
|
66
|
-
|
65
|
+
|
66
|
+
if @password_file.to_s.empty?
|
67
|
+
opts << "-k #{Shellwords.escape(@password)}"
|
68
|
+
else
|
69
|
+
opts << "-pass file:#{@password_file}"
|
70
|
+
end
|
71
|
+
|
67
72
|
opts.join(' ')
|
68
73
|
end
|
69
74
|
|
data/lib/backup/model.rb
CHANGED
@@ -303,7 +303,7 @@ module Backup
|
|
303
303
|
return [] unless databases.any? || archives.any?
|
304
304
|
|
305
305
|
[lambda { prepare! }, databases, archives,
|
306
|
-
lambda { package! },
|
306
|
+
lambda { package! }, lambda { store! }, lambda { clean! }]
|
307
307
|
end
|
308
308
|
|
309
309
|
##
|
@@ -325,6 +325,31 @@ module Backup
|
|
325
325
|
Cleaner.remove_packaging(self)
|
326
326
|
end
|
327
327
|
|
328
|
+
##
|
329
|
+
# Attempts to use all configured Storages, even if some of them result in exceptions.
|
330
|
+
# Returns true or raises first encountered exception.
|
331
|
+
def store!
|
332
|
+
storage_results = storages.map do |storage|
|
333
|
+
begin
|
334
|
+
storage.perform!
|
335
|
+
rescue => ex
|
336
|
+
ex
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
first_exception, *other_exceptions = storage_results.select { |result| result.is_a? Exception }
|
341
|
+
|
342
|
+
if first_exception
|
343
|
+
other_exceptions.each do |exception|
|
344
|
+
Logger.error exception.to_s
|
345
|
+
Logger.error exception.backtrace.join('\n')
|
346
|
+
end
|
347
|
+
raise first_exception
|
348
|
+
else
|
349
|
+
true
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
328
353
|
##
|
329
354
|
# Removes the final package file(s) once all configured Storages have run.
|
330
355
|
def clean!
|
data/lib/backup/notifier/base.rb
CHANGED
@@ -36,6 +36,15 @@ module Backup
|
|
36
36
|
# Default: 30
|
37
37
|
attr_accessor :retry_waitsec
|
38
38
|
|
39
|
+
##
|
40
|
+
# Message to send. Depends on notifier implementation if this is used.
|
41
|
+
# Default: lambda returning:
|
42
|
+
# "#{ message } #{ model.label } (#{ model.trigger })"
|
43
|
+
#
|
44
|
+
# @yieldparam [model] Backup::Model
|
45
|
+
# @yieldparam [data] Hash containing `message` and `key` values.
|
46
|
+
attr_accessor :message
|
47
|
+
|
39
48
|
attr_reader :model
|
40
49
|
|
41
50
|
def initialize(model)
|
@@ -47,6 +56,9 @@ module Backup
|
|
47
56
|
@on_failure = true if on_failure.nil?
|
48
57
|
@max_retries ||= 10
|
49
58
|
@retry_waitsec ||= 30
|
59
|
+
@message ||= lambda do |model, data|
|
60
|
+
"[#{ data[:status][:message] }] #{ model.label } (#{ model.trigger })"
|
61
|
+
end
|
50
62
|
end
|
51
63
|
|
52
64
|
# This method is called from an ensure block in Model#perform! and must
|
@@ -93,6 +105,24 @@ module Backup
|
|
93
105
|
self.class.to_s.sub('Backup::', '')
|
94
106
|
end
|
95
107
|
|
108
|
+
##
|
109
|
+
# Return status data for message creation
|
110
|
+
def status_data_for(status)
|
111
|
+
{
|
112
|
+
:success => {
|
113
|
+
:message => 'Backup::Success',
|
114
|
+
:key => :success
|
115
|
+
},
|
116
|
+
:warning => {
|
117
|
+
:message => 'Backup::Warning',
|
118
|
+
:key => :warning
|
119
|
+
},
|
120
|
+
:failure => {
|
121
|
+
:message => 'Backup::Failure',
|
122
|
+
:key => :failure
|
123
|
+
}
|
124
|
+
}[status]
|
125
|
+
end
|
96
126
|
end
|
97
127
|
end
|
98
128
|
end
|
@@ -42,13 +42,7 @@ module Backup
|
|
42
42
|
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
43
43
|
#
|
44
44
|
def notify!(status)
|
45
|
-
|
46
|
-
when :success then '[Backup::Success]'
|
47
|
-
when :warning then '[Backup::Warning]'
|
48
|
-
when :failure then '[Backup::Failure]'
|
49
|
-
end
|
50
|
-
message = "#{ tag } #{ model.label } (#{ model.trigger })"
|
51
|
-
send_message(message)
|
45
|
+
send_message(message.call(model, :status => status_data_for(status)))
|
52
46
|
end
|
53
47
|
|
54
48
|
def send_message(message)
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Backup
|
4
|
+
module Notifier
|
5
|
+
class Command < Base
|
6
|
+
|
7
|
+
##
|
8
|
+
# Command to execute.
|
9
|
+
#
|
10
|
+
# Make sure it is accessible from your $PATH, or provide
|
11
|
+
# the absolute path to the command.
|
12
|
+
attr_accessor :command
|
13
|
+
|
14
|
+
##
|
15
|
+
# Arguments to pass to the command.
|
16
|
+
#
|
17
|
+
# Must be an array of strings or callable objects.
|
18
|
+
#
|
19
|
+
# Callables will be invoked with #call(model, status),
|
20
|
+
# and the return value used as the argument.
|
21
|
+
#
|
22
|
+
# In strings you can use the following placeholders:
|
23
|
+
#
|
24
|
+
# %l - Model label
|
25
|
+
# %t - Model trigger
|
26
|
+
# %s - Status (success/failure/warning)
|
27
|
+
# %v - Status verb (succeeded/failed/succeeded with warnings)
|
28
|
+
#
|
29
|
+
# All placeholders can be used with uppercase letters to capitalize
|
30
|
+
# the value.
|
31
|
+
#
|
32
|
+
# Defaults to ["%L %v"]
|
33
|
+
attr_accessor :args
|
34
|
+
|
35
|
+
def initialize(model, &block)
|
36
|
+
super
|
37
|
+
instance_eval(&block) if block_given?
|
38
|
+
|
39
|
+
@args ||= ["%L %v"]
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
##
|
45
|
+
# Notify the user of the backup operation results.
|
46
|
+
#
|
47
|
+
# `status` indicates one of the following:
|
48
|
+
#
|
49
|
+
# `:success`
|
50
|
+
# : The backup completed successfully.
|
51
|
+
# : Notification will be sent if `on_success` is `true`.
|
52
|
+
#
|
53
|
+
# `:warning`
|
54
|
+
# : The backup completed successfully, but warnings were logged.
|
55
|
+
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
56
|
+
#
|
57
|
+
# `:failure`
|
58
|
+
# : The backup operation failed.
|
59
|
+
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
60
|
+
#
|
61
|
+
def notify!(status)
|
62
|
+
IO.popen([@command] + args.map { |arg| format_arg(arg, status) })
|
63
|
+
end
|
64
|
+
|
65
|
+
def format_arg(arg, status)
|
66
|
+
if arg.respond_to?(:call)
|
67
|
+
arg.call(model, status)
|
68
|
+
else
|
69
|
+
arg.gsub(/%(\w)/) do |match|
|
70
|
+
ph = match[1]
|
71
|
+
val = case ph.downcase
|
72
|
+
when "l"
|
73
|
+
model.label
|
74
|
+
when "t"
|
75
|
+
model.trigger.to_s
|
76
|
+
when "v"
|
77
|
+
status_verb(status)
|
78
|
+
when "s"
|
79
|
+
status.to_s
|
80
|
+
end
|
81
|
+
val.capitalize! if ph == ph.upcase
|
82
|
+
val
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def status_verb(status)
|
88
|
+
case status
|
89
|
+
when :success
|
90
|
+
"succeeded"
|
91
|
+
when :failure
|
92
|
+
"failed"
|
93
|
+
when :warning
|
94
|
+
"succeeded with warnings"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|