backup 3.5.1 → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/backup/cli.rb +29 -6
- data/lib/backup/errors.rb +46 -81
- data/lib/backup/model.rb +184 -143
- data/lib/backup/notifier/base.rb +60 -29
- data/lib/backup/notifier/campfire.rb +23 -105
- data/lib/backup/notifier/hipchat.rb +19 -17
- data/lib/backup/notifier/mail.rb +64 -59
- data/lib/backup/notifier/prowl.rb +27 -19
- data/lib/backup/notifier/pushover.rb +26 -36
- data/lib/backup/notifier/twitter.rb +13 -15
- data/lib/backup/pipeline.rb +1 -3
- data/lib/backup/storage/s3.rb +0 -3
- data/lib/backup/utilities.rb +9 -8
- data/lib/backup/version.rb +1 -1
- data/templates/notifier/mail/failure.erb +2 -0
- data/templates/notifier/mail/success.erb +4 -0
- data/templates/notifier/mail/warning.erb +2 -0
- metadata +16 -30
data/lib/backup/notifier/base.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
module Backup
|
4
4
|
module Notifier
|
5
5
|
class Base
|
6
|
+
include Backup::Utilities::Helpers
|
6
7
|
include Backup::Configuration::Helpers
|
7
8
|
|
8
9
|
##
|
@@ -24,7 +25,17 @@ module Backup
|
|
24
25
|
alias :notify_on_failure? :on_failure
|
25
26
|
|
26
27
|
##
|
27
|
-
#
|
28
|
+
# Number of times to retry failed attempts to send notification.
|
29
|
+
# Default: 10
|
30
|
+
attr_accessor :max_retries
|
31
|
+
|
32
|
+
##
|
33
|
+
# Time in seconds to pause before each retry.
|
34
|
+
# Default: 30
|
35
|
+
attr_accessor :retry_waitsec
|
36
|
+
|
37
|
+
attr_reader :model
|
38
|
+
|
28
39
|
def initialize(model)
|
29
40
|
@model = model
|
30
41
|
load_defaults!
|
@@ -32,48 +43,68 @@ module Backup
|
|
32
43
|
@on_success = true if on_success.nil?
|
33
44
|
@on_warning = true if on_warning.nil?
|
34
45
|
@on_failure = true if on_failure.nil?
|
46
|
+
@max_retries ||= 10
|
47
|
+
@retry_waitsec ||= 30
|
35
48
|
end
|
36
49
|
|
37
|
-
|
38
|
-
#
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
50
|
+
# This method is called from an ensure block in Model#perform! and must
|
51
|
+
# not raise any exceptions. However, each Notifier's #notify! method
|
52
|
+
# should raise an exception if the request fails so it may be retried.
|
53
|
+
def perform!
|
54
|
+
status = case model.exit_status
|
55
|
+
when 0
|
56
|
+
:success if notify_on_success?
|
57
|
+
when 1
|
58
|
+
:warning if notify_on_success? || notify_on_warning?
|
59
|
+
else
|
60
|
+
:failure if notify_on_failure?
|
61
|
+
end
|
57
62
|
|
58
|
-
if
|
59
|
-
|
60
|
-
notify!(
|
63
|
+
if status
|
64
|
+
Logger.info "Sending notification using #{ notifier_name }..."
|
65
|
+
with_retries { notify!(status) }
|
61
66
|
end
|
67
|
+
|
68
|
+
rescue Exception => err
|
69
|
+
Logger.error Errors::NotifierError.wrap(err, "#{ notifier_name } Failed!")
|
62
70
|
end
|
63
71
|
|
64
72
|
private
|
65
73
|
|
74
|
+
def with_retries
|
75
|
+
retries = 0
|
76
|
+
begin
|
77
|
+
yield
|
78
|
+
rescue StandardError, Timeout::Error => err
|
79
|
+
retries += 1
|
80
|
+
raise if retries > max_retries
|
81
|
+
|
82
|
+
Logger.info Errors::NotifierError.
|
83
|
+
wrap(err, "Retry ##{ retries } of #{ max_retries }.")
|
84
|
+
sleep(retry_waitsec)
|
85
|
+
retry
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
66
89
|
##
|
67
90
|
# Return the notifier name, with Backup namespace removed
|
68
91
|
def notifier_name
|
69
92
|
self.class.to_s.sub('Backup::', '')
|
70
93
|
end
|
71
94
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
95
|
+
# For ruby-1.8.7. Both sorted so specs will match.
|
96
|
+
def encode_www_form(enum)
|
97
|
+
if RUBY_VERSION < '1.9'
|
98
|
+
require 'cgi'
|
99
|
+
str = ''
|
100
|
+
enum.to_a.map {|k,v| [k.to_s, v] }.sort.each do |k,v|
|
101
|
+
str << '&' unless str.empty?
|
102
|
+
str << CGI.escape(k) << '=' << CGI.escape(v)
|
103
|
+
end
|
104
|
+
str
|
105
|
+
else
|
106
|
+
URI.encode_www_form(enum.sort)
|
107
|
+
end
|
77
108
|
end
|
78
109
|
|
79
110
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require '
|
2
|
+
require 'excon'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
module Backup
|
5
6
|
module Notifier
|
@@ -18,8 +19,7 @@ module Backup
|
|
18
19
|
attr_accessor :room_id
|
19
20
|
|
20
21
|
def initialize(model, &block)
|
21
|
-
super
|
22
|
-
|
22
|
+
super
|
23
23
|
instance_eval(&block) if block_given?
|
24
24
|
end
|
25
25
|
|
@@ -27,124 +27,42 @@ module Backup
|
|
27
27
|
|
28
28
|
##
|
29
29
|
# Notify the user of the backup operation results.
|
30
|
+
#
|
30
31
|
# `status` indicates one of the following:
|
31
32
|
#
|
32
33
|
# `:success`
|
33
34
|
# : The backup completed successfully.
|
34
|
-
# : Notification will be sent if `on_success`
|
35
|
+
# : Notification will be sent if `on_success` is `true`.
|
35
36
|
#
|
36
37
|
# `:warning`
|
37
|
-
# : The backup completed successfully, but warnings were logged
|
38
|
-
# : Notification will be sent
|
39
|
-
# : backup log, if `on_warning` was set to `true`
|
38
|
+
# : The backup completed successfully, but warnings were logged.
|
39
|
+
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
40
40
|
#
|
41
41
|
# `:failure`
|
42
42
|
# : The backup operation failed.
|
43
|
-
# : Notification will be sent
|
44
|
-
# : the failure, the Exception's backtrace, a copy of the current
|
45
|
-
# : backup log and other information if `on_failure` was set to `true`
|
43
|
+
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
46
44
|
#
|
47
45
|
def notify!(status)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
message = "
|
46
|
+
tag = case status
|
47
|
+
when :success then '[Backup::Success]'
|
48
|
+
when :warning then '[Backup::Warning]'
|
49
|
+
when :failure then '[Backup::Failure]'
|
50
|
+
end
|
51
|
+
message = "#{ tag } #{ model.label } (#{ model.trigger })"
|
54
52
|
send_message(message)
|
55
53
|
end
|
56
54
|
|
57
|
-
##
|
58
|
-
# Creates a new Campfire::Interface object and passes in the
|
59
|
-
# campfire clients "room_id", "subdomain" and "api_token". Using this object
|
60
|
-
# the provided "message" will be sent to the desired Campfire chat room
|
61
55
|
def send_message(message)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
# The Campfire::Interface acts as the Interface for the Campfire class.
|
68
|
-
# It uses the HTTParty library and the Campfire::Room class to communicate
|
69
|
-
# with the Campfire rooms. HTTParty provides the Campfire::Interface with the methods
|
70
|
-
# necessary to communicate (inside the HTTParty module) such as the class methods:
|
71
|
-
# * post
|
72
|
-
# * base_uri
|
73
|
-
# * basic_auth
|
74
|
-
class Interface
|
75
|
-
include HTTParty
|
76
|
-
|
77
|
-
##
|
78
|
-
# We communicate using the JSON data format
|
79
|
-
headers 'Content-Type' => 'application/json'
|
80
|
-
|
81
|
-
##
|
82
|
-
# Instantiates a new Campfire::Room object with
|
83
|
-
# the provided arguments and returns this object
|
84
|
-
def self.room(room_id, subdomain, api_token)
|
85
|
-
Room.new(room_id, subdomain, api_token)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
##
|
90
|
-
# The Campfire::Room acts as a model for an actual room on the Campfire service.
|
91
|
-
# And it uses the Campfire::Interface's (HTTParty) class methods to communicate based
|
92
|
-
# on the provided parameters (room_id, subdomain and api_token)
|
93
|
-
class Room
|
94
|
-
|
95
|
-
##
|
96
|
-
# Campfire api authentication api_token
|
97
|
-
attr_accessor :api_token
|
98
|
-
|
99
|
-
##
|
100
|
-
# Campfire account's subdomain
|
101
|
-
attr_accessor :subdomain
|
102
|
-
|
103
|
-
##
|
104
|
-
# Campfire account's room id
|
105
|
-
attr_accessor :room_id
|
106
|
-
|
107
|
-
##
|
108
|
-
# Instantiates a new Campfire::Room object and sets all the
|
109
|
-
# necessary arguments (@room_id, @subdomain, @api_token)
|
110
|
-
def initialize(room_id, subdomain, api_token)
|
111
|
-
@room_id = room_id
|
112
|
-
@subdomain = subdomain
|
113
|
-
@api_token = api_token
|
114
|
-
end
|
115
|
-
|
116
|
-
##
|
117
|
-
# Wrapper method for the #send_message (private) method
|
118
|
-
def message(message)
|
119
|
-
send_message(message)
|
120
|
-
end
|
121
|
-
|
122
|
-
private
|
123
|
-
|
124
|
-
##
|
125
|
-
# Takes a "message" as argument, the "type" defaults to "Textmessage".
|
126
|
-
# This method builds up a POST request with the necessary params (serialized to JSON format)
|
127
|
-
# and sends it to the Campfire service in order to submit the message
|
128
|
-
def send_message(message, type = 'Textmessage')
|
129
|
-
post 'speak', :body => MultiJson.encode(
|
130
|
-
{ :message => { :body => message, :type => type } }
|
56
|
+
uri = "https://#{ subdomain }.campfirenow.com/room/#{ room_id }/speak.json"
|
57
|
+
options = {
|
58
|
+
:headers => { 'Content-Type' => 'application/json' },
|
59
|
+
:body => JSON.dump(
|
60
|
+
{ :message => { :body => message, :type => 'Textmessage' } }
|
131
61
|
)
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
# the POST request that was built in the #send_message (private) method
|
137
|
-
def post(action, options = {})
|
138
|
-
Interface.base_uri("https://#{subdomain}.campfirenow.com")
|
139
|
-
Interface.basic_auth(api_token, 'x')
|
140
|
-
Interface.post(room_url_for(action), options)
|
141
|
-
end
|
142
|
-
|
143
|
-
##
|
144
|
-
# Returns the url for the specified room (in JSON format)
|
145
|
-
def room_url_for(action)
|
146
|
-
"/room/#{room_id}/#{action}.json"
|
147
|
-
end
|
62
|
+
}
|
63
|
+
options.merge!(:user => api_token, :password => 'x') # Basic Auth
|
64
|
+
options.merge!(:expects => 201) # raise error if unsuccessful
|
65
|
+
Excon.post(uri, options)
|
148
66
|
end
|
149
67
|
|
150
68
|
end
|
@@ -37,55 +37,57 @@ module Backup
|
|
37
37
|
attr_accessor :failure_color
|
38
38
|
|
39
39
|
def initialize(model, &block)
|
40
|
-
super
|
40
|
+
super
|
41
|
+
instance_eval(&block) if block_given?
|
41
42
|
|
42
43
|
@notify_users ||= false
|
43
44
|
@rooms_notified ||= []
|
44
45
|
@success_color ||= 'yellow'
|
45
46
|
@warning_color ||= 'yellow'
|
46
47
|
@failure_color ||= 'yellow'
|
47
|
-
|
48
|
-
instance_eval(&block) if block_given?
|
49
48
|
end
|
50
49
|
|
51
50
|
private
|
52
51
|
|
53
52
|
##
|
54
53
|
# Notify the user of the backup operation results.
|
54
|
+
#
|
55
55
|
# `status` indicates one of the following:
|
56
56
|
#
|
57
57
|
# `:success`
|
58
58
|
# : The backup completed successfully.
|
59
|
-
# : Notification will be sent if `on_success`
|
59
|
+
# : Notification will be sent if `on_success` is `true`.
|
60
60
|
#
|
61
61
|
# `:warning`
|
62
|
-
# : The backup completed successfully, but warnings were logged
|
63
|
-
# : Notification will be sent
|
64
|
-
# : backup log, if `on_warning` was set to `true`
|
62
|
+
# : The backup completed successfully, but warnings were logged.
|
63
|
+
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
65
64
|
#
|
66
65
|
# `:failure`
|
67
66
|
# : The backup operation failed.
|
68
|
-
# : Notification will be sent
|
69
|
-
# : the failure, the Exception's backtrace, a copy of the current
|
70
|
-
# : backup log and other information if `on_failure` was set to `true`
|
67
|
+
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
71
68
|
#
|
72
69
|
def notify!(status)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
message = "
|
70
|
+
tag, color = case status
|
71
|
+
when :success then ['[Backup::Success]', success_color]
|
72
|
+
when :warning then ['[Backup::Warning]', warning_color]
|
73
|
+
when :failure then ['[Backup::Failure]', failure_color]
|
74
|
+
end
|
75
|
+
message = "#{ tag } #{ model.label } (#{ model.trigger })"
|
79
76
|
send_message(message, color)
|
80
77
|
end
|
81
78
|
|
79
|
+
# Hipchat::Client will raise an error if unsuccessful.
|
82
80
|
def send_message(msg, color)
|
83
81
|
client = HipChat::Client.new(token)
|
84
|
-
|
82
|
+
rooms_to_notify.each do |room|
|
85
83
|
client[room].send(from, msg, :color => color, :notify => notify_users)
|
86
84
|
end
|
87
85
|
end
|
88
86
|
|
87
|
+
def rooms_to_notify
|
88
|
+
Array(rooms_notified).map {|r| r.split(',').map(&:strip) }.flatten
|
89
|
+
end
|
90
|
+
|
89
91
|
end
|
90
92
|
end
|
91
93
|
end
|
data/lib/backup/notifier/mail.rb
CHANGED
@@ -17,11 +17,11 @@ module Backup
|
|
17
17
|
#
|
18
18
|
# [:sendmail - ::Mail::Sendmail]
|
19
19
|
# Settings used by this method:
|
20
|
-
# {#
|
20
|
+
# {#sendmail_args}
|
21
21
|
#
|
22
22
|
# [:exim - ::Mail::Exim]
|
23
23
|
# Settings used by this method:
|
24
|
-
# {#
|
24
|
+
# {#exim_args}
|
25
25
|
#
|
26
26
|
# [:file - ::Mail::FileDelivery]
|
27
27
|
# Settings used by this method:
|
@@ -76,13 +76,6 @@ module Backup
|
|
76
76
|
# Use a +SSL/TLS+ connection.
|
77
77
|
attr_accessor :encryption
|
78
78
|
|
79
|
-
attr_deprecate :enable_starttls_auto, :version => '3.2.0',
|
80
|
-
:message => "Use #encryption instead.\n" +
|
81
|
-
'e.g. mail.encryption = :starttls',
|
82
|
-
:action => lambda {|klass, val|
|
83
|
-
klass.encryption = val ? :starttls : :none
|
84
|
-
}
|
85
|
-
|
86
79
|
##
|
87
80
|
# OpenSSL Verify Mode
|
88
81
|
#
|
@@ -92,52 +85,44 @@ module Backup
|
|
92
85
|
# Use +:none+ for a self-signed and/or wildcard certificate
|
93
86
|
attr_accessor :openssl_verify_mode
|
94
87
|
|
95
|
-
##
|
96
|
-
# Path to `sendmail` (if needed)
|
97
|
-
#
|
98
|
-
# When using the `:sendmail` `delivery_method` option,
|
99
|
-
# this may be used to specify the absolute path to `sendmail`
|
100
|
-
#
|
101
|
-
# Example: '/usr/sbin/sendmail'
|
102
|
-
attr_accessor :sendmail
|
103
|
-
|
104
88
|
##
|
105
89
|
# Optional arguments to pass to `sendmail`
|
106
90
|
#
|
107
|
-
# Note that this will override the defaults set by the Mail gem
|
108
|
-
# So, if set here, be sure to set all the arguments
|
91
|
+
# Note that this will override the defaults set by the Mail gem
|
92
|
+
# (currently: '-i'). So, if set here, be sure to set all the arguments
|
93
|
+
# you require.
|
109
94
|
#
|
110
|
-
# Example: '-i -
|
95
|
+
# Example: '-i -X/tmp/traffic.log'
|
111
96
|
attr_accessor :sendmail_args
|
112
97
|
|
113
|
-
##
|
114
|
-
# Path to `exim` (if needed)
|
115
|
-
#
|
116
|
-
# When using the `:exim` `delivery_method` option,
|
117
|
-
# this may be used to specify the absolute path to `exim`
|
118
|
-
#
|
119
|
-
# Example: '/usr/sbin/exim'
|
120
|
-
attr_accessor :exim
|
121
|
-
|
122
98
|
##
|
123
99
|
# Optional arguments to pass to `exim`
|
124
100
|
#
|
125
|
-
# Note that this will override the defaults set by the Mail gem
|
126
|
-
# So, if set here, be sure to set all the arguments
|
101
|
+
# Note that this will override the defaults set by the Mail gem
|
102
|
+
# (currently: '-i -t') So, if set here, be sure to set all the arguments
|
103
|
+
# you require.
|
127
104
|
#
|
128
105
|
# Example: '-i -t -X/tmp/traffic.log'
|
129
106
|
attr_accessor :exim_args
|
130
107
|
|
131
108
|
##
|
132
|
-
# Folder where mail will be kept when using the `:file` `delivery_method
|
109
|
+
# Folder where mail will be kept when using the `:file` `delivery_method`.
|
133
110
|
#
|
134
111
|
# Default location is '$HOME/Backup/emails'
|
135
112
|
attr_accessor :mail_folder
|
136
113
|
|
137
|
-
|
138
|
-
|
114
|
+
##
|
115
|
+
# Array of statuses for which the log file should be attached.
|
116
|
+
#
|
117
|
+
# Available statuses are: `:success`, `:warning` and `:failure`.
|
118
|
+
# Default: [:warning, :failure]
|
119
|
+
attr_accessor :send_log_on
|
139
120
|
|
121
|
+
def initialize(model, &block)
|
122
|
+
super
|
140
123
|
instance_eval(&block) if block_given?
|
124
|
+
|
125
|
+
@send_log_on ||= [:warning, :failure]
|
141
126
|
end
|
142
127
|
|
143
128
|
private
|
@@ -147,42 +132,43 @@ module Backup
|
|
147
132
|
#
|
148
133
|
# `status` indicates one of the following:
|
149
134
|
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
135
|
+
# `:success`
|
136
|
+
# : The backup completed successfully.
|
137
|
+
# : Notification will be sent if `on_success` is `true`.
|
153
138
|
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
139
|
+
# `:warning`
|
140
|
+
# : The backup completed successfully, but warnings were logged.
|
141
|
+
# : Notification will be sent, including a copy of the current
|
142
|
+
# : backup log, if `on_warning` or `on_success` is `true`.
|
158
143
|
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
# backup log and other information if `on_failure` was set to `true`
|
144
|
+
# `:failure`
|
145
|
+
# : The backup operation failed.
|
146
|
+
# : Notification will be sent, including a copy of the current
|
147
|
+
# : backup log, if `on_failure` is `true`.
|
164
148
|
#
|
165
149
|
def notify!(status)
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
end
|
150
|
+
tag = case status
|
151
|
+
when :success then '[Backup::Success]'
|
152
|
+
when :warning then '[Backup::Warning]'
|
153
|
+
when :failure then '[Backup::Failure]'
|
154
|
+
end
|
172
155
|
|
173
156
|
email = new_email
|
174
|
-
email.subject = "
|
175
|
-
|
157
|
+
email.subject = "#{ tag } #{ model.label } (#{ model.trigger })"
|
158
|
+
|
159
|
+
send_log = send_log_on.include?(status)
|
160
|
+
template = Backup::Template.new({ :model => model, :send_log => send_log })
|
161
|
+
email.body = template.result('notifier/mail/%s.erb' % status.to_s)
|
176
162
|
|
177
163
|
if send_log
|
178
164
|
email.convert_to_multipart
|
179
|
-
email.attachments["#{
|
165
|
+
email.attachments["#{ model.time }.#{ model.trigger }.log"] = {
|
180
166
|
:mime_type => 'text/plain;',
|
181
167
|
:content => Logger.messages.map(&:formatted_lines).flatten.join("\n")
|
182
168
|
}
|
183
169
|
end
|
184
170
|
|
185
|
-
email.deliver!
|
171
|
+
email.deliver! # raise error if unsuccessful
|
186
172
|
end
|
187
173
|
|
188
174
|
##
|
@@ -208,12 +194,12 @@ module Backup
|
|
208
194
|
}
|
209
195
|
when 'sendmail'
|
210
196
|
opts = {}
|
211
|
-
opts.merge!(:location =>
|
197
|
+
opts.merge!(:location => utility(:sendmail))
|
212
198
|
opts.merge!(:arguments => @sendmail_args) if @sendmail_args
|
213
199
|
opts
|
214
200
|
when 'exim'
|
215
201
|
opts = {}
|
216
|
-
opts.merge!(:location =>
|
202
|
+
opts.merge!(:location => utility(:exim))
|
217
203
|
opts.merge!(:arguments => @exim_args) if @exim_args
|
218
204
|
opts
|
219
205
|
when 'file'
|
@@ -232,6 +218,25 @@ module Backup
|
|
232
218
|
email
|
233
219
|
end
|
234
220
|
|
221
|
+
attr_deprecate :enable_starttls_auto, :version => '3.2.0',
|
222
|
+
:message => "Use #encryption instead.\n" +
|
223
|
+
'e.g. mail.encryption = :starttls',
|
224
|
+
:action => lambda {|klass, val|
|
225
|
+
klass.encryption = val ? :starttls : :none
|
226
|
+
}
|
227
|
+
|
228
|
+
attr_deprecate :sendmail, :version => '3.6.0',
|
229
|
+
:message => 'Use Backup::Utilities.configure instead.',
|
230
|
+
:action => lambda {|klass, val|
|
231
|
+
Utilities.configure { sendmail val }
|
232
|
+
}
|
233
|
+
|
234
|
+
attr_deprecate :exim, :version => '3.6.0',
|
235
|
+
:message => 'Use Backup::Utilities.configure instead.',
|
236
|
+
:action => lambda {|klass, val|
|
237
|
+
Utilities.configure { exim val }
|
238
|
+
}
|
239
|
+
|
235
240
|
end
|
236
241
|
end
|
237
242
|
end
|