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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -7
  3. data/lib/backup.rb +6 -0
  4. data/lib/backup/cli.rb +10 -0
  5. data/lib/backup/config/dsl.rb +3 -3
  6. data/lib/backup/database/mysql.rb +17 -6
  7. data/lib/backup/database/postgresql.rb +2 -2
  8. data/lib/backup/database/sqlite.rb +57 -0
  9. data/lib/backup/encryptor/open_ssl.rb +7 -2
  10. data/lib/backup/model.rb +26 -1
  11. data/lib/backup/notifier/base.rb +30 -0
  12. data/lib/backup/notifier/campfire.rb +1 -7
  13. data/lib/backup/notifier/command.rb +99 -0
  14. data/lib/backup/notifier/datadog.rb +107 -0
  15. data/lib/backup/notifier/flowdock.rb +6 -5
  16. data/lib/backup/notifier/hipchat.rb +27 -8
  17. data/lib/backup/notifier/http_post.rb +2 -7
  18. data/lib/backup/notifier/mail.rb +19 -10
  19. data/lib/backup/notifier/nagios.rb +3 -8
  20. data/lib/backup/notifier/pagerduty.rb +81 -0
  21. data/lib/backup/notifier/prowl.rb +8 -9
  22. data/lib/backup/notifier/pushover.rb +1 -7
  23. data/lib/backup/notifier/ses.rb +88 -0
  24. data/lib/backup/notifier/slack.rb +7 -17
  25. data/lib/backup/notifier/twitter.rb +1 -7
  26. data/lib/backup/notifier/zabbix.rb +1 -6
  27. data/lib/backup/package.rb +4 -0
  28. data/lib/backup/packager.rb +8 -2
  29. data/lib/backup/storage/base.rb +15 -3
  30. data/lib/backup/storage/cycler.rb +24 -14
  31. data/lib/backup/storage/ftp.rb +15 -1
  32. data/lib/backup/storage/s3.rb +2 -1
  33. data/lib/backup/syncer/base.rb +2 -2
  34. data/lib/backup/version.rb +1 -1
  35. data/templates/cli/config +2 -2
  36. data/templates/cli/databases/sqlite +11 -0
  37. data/templates/cli/model +1 -1
  38. data/templates/cli/notifiers/command +32 -0
  39. data/templates/cli/notifiers/datadog +57 -0
  40. data/templates/cli/notifiers/hipchat +1 -0
  41. data/templates/cli/notifiers/mail +3 -0
  42. data/templates/cli/notifiers/pagerduty +12 -0
  43. data/templates/cli/notifiers/ses +15 -0
  44. data/templates/cli/notifiers/slack +3 -4
  45. data/templates/cli/storages/dropbox +1 -0
  46. data/templates/cli/storages/ftp +1 -0
  47. data/templates/cli/storages/local +1 -0
  48. data/templates/cli/storages/ninefold +1 -0
  49. data/templates/cli/storages/s3 +2 -0
  50. data/templates/cli/storages/scp +1 -0
  51. data/templates/cli/storages/sftp +1 -0
  52. data/templates/general/links +3 -3
  53. metadata +53 -136
@@ -7,12 +7,8 @@ module Backup
7
7
  class Slack < Base
8
8
 
9
9
  ##
10
- # The Team name
11
- attr_accessor :team
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
- tag = case status
69
- when :success then '[Backup::Success]'
70
- when :failure then '[Backup::Failure]'
71
- when :warning then '[Backup::Warning]'
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 ||= "https://#{team}.slack.com/services/hooks/incoming-webhook?token=#{token}"
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
- tag = case status
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 = case status
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)
@@ -47,5 +47,9 @@ module Backup
47
47
  "#{ trigger }.#{ extension }"
48
48
  end
49
49
 
50
+ def time_as_object
51
+ Time.strptime(time, '%Y.%m.%d.%H.%M.%S')
52
+ end
53
+
50
54
  end
51
55
  end
@@ -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 << "#{ utility(:tar) } -cf - " +
46
- "-C '#{ Config.tmp_path }' '#{ @package.trigger }'"
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
@@ -10,8 +10,18 @@ module Backup
10
10
  attr_accessor :path
11
11
 
12
12
  ##
13
- # Sets the limit to how many backups to keep in the remote location.
14
- # If exceeded, the oldest will be removed to make room for the newest
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
- cycle! if respond_to?(:cycle!, true) && keep.to_i > 0
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
- excess = packages.count - keep.to_i
17
+ cycled_packages = []
18
18
 
19
- if excess > 0
20
- packages.pop(excess).each do |pkg|
21
- begin
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
- yaml_save(packages)
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.
@@ -15,15 +15,25 @@ module Backup
15
15
  attr_accessor :ip, :port
16
16
 
17
17
  ##
18
- # use passive mode?
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
@@ -76,7 +76,8 @@ module Backup
76
76
  @retry_waitsec ||= 30
77
77
  @path ||= 'backups'
78
78
  @storage_class ||= :standard
79
- path.sub!(/^\//, '')
79
+
80
+ @path = @path.sub(/^\//, '')
80
81
 
81
82
  check_configuration
82
83
  end
@@ -28,8 +28,8 @@ module Backup
28
28
  load_defaults!
29
29
 
30
30
  @mirror ||= false
31
- @directories = []
32
- @excludes = []
31
+ @directories ||= []
32
+ @excludes ||= []
33
33
  end
34
34
 
35
35
  ##
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Backup
4
- VERSION = '4.0.3.1'
4
+ VERSION = '4.2.0'
5
5
  end
@@ -3,8 +3,8 @@
3
3
  ##
4
4
  # Backup v<%= Backup::VERSION.split('.').first %>.x Configuration
5
5
  #
6
- # Documentation: http://meskyanichi.github.io/backup
7
- # Issue Tracker: https://github.com/meskyanichi/backup/issues
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
@@ -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://meskyanichi.github.io/backup
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
@@ -12,4 +12,5 @@
12
12
  hipchat.success_color = "green"
13
13
  hipchat.warning_color = "yellow"
14
14
  hipchat.failure_color = "red"
15
+ hipchat.api_version = "v1"
15
16
  end
@@ -11,6 +11,9 @@
11
11
 
12
12
  mail.from = "sender@email.com"
13
13
  mail.to = "receiver@email.com"
14
+ mail.cc = "cc@email.com"
15
+ mail.bcc = "bcc@email.com"
16
+ mail.reply_to = "reply_to@email.com"
14
17
  mail.address = "smtp.gmail.com"
15
18
  mail.port = 587
16
19
  mail.domain = "your.host.name"
@@ -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 team name
10
- slack.team = 'my_team'
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