backup_zh 4.0.3.1 → 4.2.0
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 +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
@@ -7,12 +7,8 @@ module Backup
|
|
7
7
|
class Slack < Base
|
8
8
|
|
9
9
|
##
|
10
|
-
# The
|
11
|
-
attr_accessor :
|
12
|
-
|
13
|
-
##
|
14
|
-
# The Integration Token
|
15
|
-
attr_accessor :token
|
10
|
+
# The incoming webhook url
|
11
|
+
attr_accessor :webhook_url
|
16
12
|
|
17
13
|
##
|
18
14
|
# The channel to send messages to
|
@@ -65,21 +61,15 @@ module Backup
|
|
65
61
|
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
66
62
|
#
|
67
63
|
def notify!(status)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
message = "#{ tag } #{ model.label } (#{ model.trigger })"
|
74
|
-
|
75
|
-
data = { :text => message }
|
64
|
+
data = {
|
65
|
+
:text => message.call(model, :status => status_data_for(status)),
|
66
|
+
:attachments => [attachment(status)]
|
67
|
+
}
|
76
68
|
[:channel, :username, :icon_emoji].each do |param|
|
77
69
|
val = send(param)
|
78
70
|
data.merge!(param => val) if val
|
79
71
|
end
|
80
72
|
|
81
|
-
data.merge!(:attachments => [attachment(status)])
|
82
|
-
|
83
73
|
options = {
|
84
74
|
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
|
85
75
|
:body => URI.encode_www_form(:payload => JSON.dump(data))
|
@@ -151,7 +141,7 @@ module Backup
|
|
151
141
|
end
|
152
142
|
|
153
143
|
def uri
|
154
|
-
@uri ||=
|
144
|
+
@uri ||= webhook_url
|
155
145
|
end
|
156
146
|
end
|
157
147
|
end
|
@@ -38,13 +38,7 @@ module Backup
|
|
38
38
|
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
39
39
|
#
|
40
40
|
def notify!(status)
|
41
|
-
|
42
|
-
when :success then '[Backup::Success]'
|
43
|
-
when :warning then '[Backup::Warning]'
|
44
|
-
when :failure then '[Backup::Failure]'
|
45
|
-
end
|
46
|
-
message = "#{ tag } #{ model.label } (#{ model.trigger }) (@ #{ model.time })"
|
47
|
-
send_message(message)
|
41
|
+
send_message(message.call(model, :status => status_data_for(status)))
|
48
42
|
end
|
49
43
|
|
50
44
|
# Twitter::Client will raise an error if unsuccessful.
|
@@ -45,12 +45,7 @@ module Backup
|
|
45
45
|
# : Notification will be sent if `on_warning` or `on_success` is `true`.
|
46
46
|
#
|
47
47
|
def notify!(status)
|
48
|
-
message
|
49
|
-
when :success then 'Completed Successfully'
|
50
|
-
when :warning then 'Completed Successfully (with Warnings)'
|
51
|
-
when :failure then 'Failed'
|
52
|
-
end
|
53
|
-
send_message("#{ message } in #{ model.duration }")
|
48
|
+
send_message(message.call(model, :status => status_data_for(status)))
|
54
49
|
end
|
55
50
|
|
56
51
|
def send_message(message)
|
data/lib/backup/package.rb
CHANGED
data/lib/backup/packager.rb
CHANGED
@@ -42,8 +42,11 @@ module Backup
|
|
42
42
|
# The command's output will then be either piped to the Encryptor
|
43
43
|
# or the Splitter (if no Encryptor), or through `cat` into the final
|
44
44
|
# output file if neither are configured.
|
45
|
-
@pipeline
|
46
|
-
|
45
|
+
@pipeline.add(
|
46
|
+
"#{ utility(:tar) } -cf - " +
|
47
|
+
"-C '#{ Config.tmp_path }' '#{ @package.trigger }'",
|
48
|
+
tar_success_codes
|
49
|
+
)
|
47
50
|
|
48
51
|
##
|
49
52
|
# If an Encryptor was configured, it will be called first
|
@@ -96,6 +99,9 @@ module Backup
|
|
96
99
|
stack.shift
|
97
100
|
end
|
98
101
|
|
102
|
+
def tar_success_codes
|
103
|
+
gnu_tar? ? [0, 1] : [0]
|
104
|
+
end
|
99
105
|
end
|
100
106
|
end
|
101
107
|
end
|
data/lib/backup/storage/base.rb
CHANGED
@@ -10,8 +10,18 @@ module Backup
|
|
10
10
|
attr_accessor :path
|
11
11
|
|
12
12
|
##
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# Number of backups to keep or time until which to keep.
|
14
|
+
#
|
15
|
+
# If an Integer is given it sets the limit to how many backups to keep in
|
16
|
+
# the remote location. If exceeded, the oldest will be removed to make
|
17
|
+
# room for the newest.
|
18
|
+
#
|
19
|
+
# If a Time object is given it will remove backups _older_ than the given
|
20
|
+
# date.
|
21
|
+
#
|
22
|
+
# @!attribute [rw] keep
|
23
|
+
# @param [Integer|Time]
|
24
|
+
# @return [Integer|Time]
|
15
25
|
attr_accessor :keep
|
16
26
|
|
17
27
|
attr_reader :model, :package, :storage_id
|
@@ -33,7 +43,9 @@ module Backup
|
|
33
43
|
def perform!
|
34
44
|
Logger.info "#{ storage_name } Started..."
|
35
45
|
transfer!
|
36
|
-
|
46
|
+
if respond_to?(:cycle!, true) && (keep.to_i > 0 || keep.is_a?(Time))
|
47
|
+
cycle!
|
48
|
+
end
|
37
49
|
Logger.info "#{ storage_name } Finished!"
|
38
50
|
end
|
39
51
|
|
@@ -14,24 +14,34 @@ module Backup
|
|
14
14
|
Logger.info 'Cycling Started...'
|
15
15
|
|
16
16
|
packages = yaml_load.unshift(package)
|
17
|
-
|
17
|
+
cycled_packages = []
|
18
18
|
|
19
|
-
if
|
20
|
-
packages.
|
21
|
-
|
22
|
-
remove!(pkg) unless pkg.no_cycle
|
23
|
-
rescue => err
|
24
|
-
Logger.warn Error.wrap(err, <<-EOS)
|
25
|
-
There was a problem removing the following package:
|
26
|
-
Trigger: #{pkg.trigger} :: Dated: #{pkg.time}
|
27
|
-
Package included the following #{ pkg.filenames.count } file(s):
|
28
|
-
#{ pkg.filenames.join("\n") }
|
29
|
-
EOS
|
30
|
-
end
|
19
|
+
if keep.is_a?(Date) || keep.is_a?(Time)
|
20
|
+
cycled_packages = packages.select do |p|
|
21
|
+
p.time_as_object < keep.to_time
|
31
22
|
end
|
23
|
+
else
|
24
|
+
excess = packages.count - keep.to_i
|
25
|
+
cycled_packages = packages.last(excess)
|
32
26
|
end
|
33
27
|
|
34
|
-
|
28
|
+
saved_packages = packages - cycled_packages
|
29
|
+
cycled_packages.each { |package| delete_package package }
|
30
|
+
|
31
|
+
yaml_save(saved_packages)
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete_package(package)
|
35
|
+
begin
|
36
|
+
remove!(package) unless package.no_cycle
|
37
|
+
rescue => err
|
38
|
+
Logger.warn Error.wrap(err, <<-EOS)
|
39
|
+
There was a problem removing the following package:
|
40
|
+
Trigger: #{package.trigger} :: Dated: #{package.time}
|
41
|
+
Package included the following #{ package.filenames.count } file(s):
|
42
|
+
#{ package.filenames.join("\n") }
|
43
|
+
EOS
|
44
|
+
end
|
35
45
|
end
|
36
46
|
|
37
47
|
# Returns path to the YAML data file.
|
data/lib/backup/storage/ftp.rb
CHANGED
@@ -15,15 +15,25 @@ module Backup
|
|
15
15
|
attr_accessor :ip, :port
|
16
16
|
|
17
17
|
##
|
18
|
-
#
|
18
|
+
# Use passive mode?
|
19
19
|
attr_accessor :passive_mode
|
20
20
|
|
21
|
+
##
|
22
|
+
# Configure connection open and read timeouts.
|
23
|
+
# Net::FTP's open_timeout and read_timeout will both be configured using
|
24
|
+
# this setting.
|
25
|
+
# @!attribute [rw] timeout
|
26
|
+
# @param [Integer|Float]
|
27
|
+
# @return [Integer|Float]
|
28
|
+
attr_accessor :timeout
|
29
|
+
|
21
30
|
def initialize(model, storage_id = nil)
|
22
31
|
super
|
23
32
|
|
24
33
|
@port ||= 21
|
25
34
|
@path ||= 'backups'
|
26
35
|
@passive_mode ||= false
|
36
|
+
@timeout ||= nil
|
27
37
|
path.sub!(/^~\//, '')
|
28
38
|
end
|
29
39
|
|
@@ -42,6 +52,10 @@ module Backup
|
|
42
52
|
end; Net::FTP.send(:const_set, :FTP_PORT, port)
|
43
53
|
|
44
54
|
Net::FTP.open(ip, username, password) do |ftp|
|
55
|
+
if timeout
|
56
|
+
ftp.open_timeout = timeout
|
57
|
+
ftp.read_timeout = timeout
|
58
|
+
end
|
45
59
|
ftp.passive = true if passive_mode
|
46
60
|
yield ftp
|
47
61
|
end
|
data/lib/backup/storage/s3.rb
CHANGED
data/lib/backup/syncer/base.rb
CHANGED
data/lib/backup/version.rb
CHANGED
data/templates/cli/config
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
##
|
4
4
|
# Backup v<%= Backup::VERSION.split('.').first %>.x Configuration
|
5
5
|
#
|
6
|
-
# Documentation: http://
|
7
|
-
# Issue Tracker: https://github.com/
|
6
|
+
# Documentation: http://backup.github.io/backup
|
7
|
+
# Issue Tracker: https://github.com/backup/backup/issues
|
8
8
|
|
9
9
|
##
|
10
10
|
# Config Options
|
@@ -0,0 +1,11 @@
|
|
1
|
+
##
|
2
|
+
# SQLite [Database]
|
3
|
+
#
|
4
|
+
database SQLite do |db|
|
5
|
+
# Path to database file
|
6
|
+
db.path = "/path/to/my/sqlite/db.sqlite"
|
7
|
+
|
8
|
+
# Optional: Use to set the location of this utility
|
9
|
+
# if it cannot be found by name in your $PATH
|
10
|
+
db.sqlitedump_utility = "/opt/local/bin/sqlite3"
|
11
|
+
end
|
data/templates/cli/model
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
# $ backup perform -t <%= @options[:trigger] %> [-c <path_to_configuration_file>]
|
8
8
|
#
|
9
9
|
# For more information about Backup's components, see the documentation at:
|
10
|
-
# http://
|
10
|
+
# http://backup.github.io/backup
|
11
11
|
#
|
12
12
|
Model.new(:<%= @options[:trigger] %>, 'Description for <%= @options[:trigger] %>') do
|
13
13
|
<% if @options[:splitter] %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
##
|
2
|
+
# Command [Notifier]
|
3
|
+
#
|
4
|
+
notify_by Command do |cmd|
|
5
|
+
cmd.on_success = true
|
6
|
+
cmd.on_warning = true
|
7
|
+
cmd.on_failure = true
|
8
|
+
|
9
|
+
# Command to execute
|
10
|
+
cmd.command = 'notify-send'
|
11
|
+
|
12
|
+
# Arguments to pass to the command.
|
13
|
+
#
|
14
|
+
# Must be an array of strings or callable objects.
|
15
|
+
#
|
16
|
+
# Callables will be invoked with #call(model, status),
|
17
|
+
# and the return value used as the argument.
|
18
|
+
#
|
19
|
+
# In strings you can use the following placeholders:
|
20
|
+
#
|
21
|
+
# %l - Model label
|
22
|
+
# %t - Model trigger
|
23
|
+
# %s - Status (success/failure/warning)
|
24
|
+
# %v - Status verb (succeeded/failed/succeeded with warnings)
|
25
|
+
#
|
26
|
+
# All placeholders can be used with uppercase letters to capitalize
|
27
|
+
# the value.
|
28
|
+
#
|
29
|
+
# Defaults to ["%L %v"]
|
30
|
+
#
|
31
|
+
# cmd.args = ["Backup %L", "%V"]
|
32
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
##
|
2
|
+
# DataDog [Notifier]
|
3
|
+
#
|
4
|
+
notify_by DataDog do |datadog|
|
5
|
+
datadog.on_success = true
|
6
|
+
datadog.on_warning = true
|
7
|
+
datadog.on_failure = true
|
8
|
+
|
9
|
+
datadog.api_key = 'my_api_key'
|
10
|
+
|
11
|
+
##
|
12
|
+
# Optional
|
13
|
+
#
|
14
|
+
# Override Default Title
|
15
|
+
# Default is: "Backup #{:label}"
|
16
|
+
# datadog.title = "Backup #{:status}"
|
17
|
+
#
|
18
|
+
# Override Default Text
|
19
|
+
# Default is "Backup Notification for #{:label}"
|
20
|
+
# datadog.text = "Backup #{:status} - #{:message}"
|
21
|
+
#
|
22
|
+
# Provide a hostname to associate this backup to
|
23
|
+
# Default is nil
|
24
|
+
# datadog.host = 'db.example.com'
|
25
|
+
#
|
26
|
+
# Add Tags to the Event
|
27
|
+
# Default is nil
|
28
|
+
# valid option is an Array
|
29
|
+
# datadog.tags = ['backup', 'env:production']
|
30
|
+
#
|
31
|
+
# Override the Alert Type
|
32
|
+
# Default is based on the :status of the backup:
|
33
|
+
# :success => 'success'
|
34
|
+
# :warning => 'warning'
|
35
|
+
# :failure => 'error'
|
36
|
+
# valid options are: 'info', 'success', 'warning', 'error'
|
37
|
+
# datadog.alert_type = 'info'
|
38
|
+
#
|
39
|
+
# Add a Source Type
|
40
|
+
# Default is nil
|
41
|
+
# see api docs for valid source_type_names
|
42
|
+
# datadog.source_type_name = 'my apps'
|
43
|
+
#
|
44
|
+
# Override the Priority Level
|
45
|
+
# Default is 'normal'
|
46
|
+
# valid options are: 'normal' or 'low'
|
47
|
+
# datadog.priority = 'low'
|
48
|
+
#
|
49
|
+
# Override the Event Time (must be a unix Timestamp)
|
50
|
+
# Default is Time.now.to_i
|
51
|
+
# datadog.date_happened = Time.now.to_i
|
52
|
+
#
|
53
|
+
# Add an Aggregation Key
|
54
|
+
# Default is nil
|
55
|
+
# max length allowed is 100 characters
|
56
|
+
# datadog.aggregation_key = 'my_aggregation'
|
57
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
##
|
2
|
+
# PagerDuty [Notifier]
|
3
|
+
#
|
4
|
+
|
5
|
+
notify_by PagerDuty do |pagerduty|
|
6
|
+
pagerduty.on_success = true
|
7
|
+
pagerduty.on_warning = true
|
8
|
+
pagerduty.on_failure = true
|
9
|
+
|
10
|
+
pagerduty.service_key = '0123456789abcdef01234567890abcde'
|
11
|
+
pagerduty.resolve_on_warning = true
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
##
|
2
|
+
# SES [Notifier]
|
3
|
+
#
|
4
|
+
notify_by Ses do |ses|
|
5
|
+
ses.on_success = true
|
6
|
+
ses.on_warning = true
|
7
|
+
ses.on_failure = true
|
8
|
+
|
9
|
+
ses.access_key_id = ''
|
10
|
+
ses.secret_access_key = ''
|
11
|
+
ses.region = 'eu-west-1'
|
12
|
+
|
13
|
+
ses.from = "sender@email.com"
|
14
|
+
ses.to = "receiver@email.com"
|
15
|
+
end
|
@@ -6,11 +6,10 @@
|
|
6
6
|
slack.on_warning = true
|
7
7
|
slack.on_failure = true
|
8
8
|
|
9
|
-
# The
|
10
|
-
slack.
|
9
|
+
# The incoming webhook url
|
10
|
+
# https://hooks.slack.com/services/xxxxxxxx/xxxxxxxxx/xxxxxxxxxx
|
11
|
+
slack.webhook_url = 'xxxxxxxxxxxxxxxxxxxxxxxx'
|
11
12
|
|
12
|
-
# The integration token
|
13
|
-
slack.token = 'xxxxxxxxxxxxxxxxxxxxxxxx'
|
14
13
|
|
15
14
|
##
|
16
15
|
# Optional
|