backup 4.0.2 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0598ab928bc914fc5be6f4e473a2dba3f3b80c41
4
- data.tar.gz: d8c34be3b2896bb9a1cc024c67df93783ae1853c
3
+ metadata.gz: b7e83c99df63edb4998a75a49d81a06b0d1039ca
4
+ data.tar.gz: 5080aa4b34f9fc9104a1f312ad7418398b041148
5
5
  SHA512:
6
- metadata.gz: eed55c0c9b7e63ba902db61e8148413a430d21755175c34926ae5348318aefde89876a5dd8231dccef11adaad44ec08575f3e244e7b3ab235e2100e764b9b079
7
- data.tar.gz: 20d0efa09f22cf70b9bdaf94ac49d43f1fbe0d499b44bfe31ac93c0b867559c3db83c87a70953d5def9cfe53caff2308f36dc40cc0b1406cf284d310749c80b2
6
+ metadata.gz: 2e80a87dbf0a0d93cdb5ce0fb9a3f10c9b68b7d2ab2d49b5f30e8a77e3bf5763669ee7f0b853800283f3097c3c18fe0fc53f186dd0fbdb2bb5bacaf58b423c61
7
+ data.tar.gz: 2dacfb012d43a5e19434427d76ddd0ddb3b03913eba7dce02ce3947397be1b7b3f663fb74bcd04e93ee5006c27c7487c2c5cdb61cff1e2200562e5e0bbe0a413
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  Backup v4.x
2
2
  ===========
3
+ [![Code Climate](https://codeclimate.com/github/meskyanichi/backup.png)](https://codeclimate.com/github/meskyanichi/backup)
4
+ [![Build Status](https://travis-ci.org/meskyanichi/backup.svg?branch=master)](https://travis-ci.org/meskyanichi/backup)
3
5
 
4
6
  Backup is a system utility for Linux and Mac OS X, distributed as a RubyGem, that allows you to easily perform backup
5
7
  operations. It provides an elegant DSL in Ruby for _modeling_ your backups. Backup has built-in support for various
@@ -108,6 +108,8 @@ module Backup
108
108
  autoload :Slack, File.join(NOTIFIER_PATH, 'slack')
109
109
  autoload :HttpPost, File.join(NOTIFIER_PATH, 'http_post')
110
110
  autoload :Nagios, File.join(NOTIFIER_PATH, 'nagios')
111
+ autoload :FlowDock, File.join(NOTIFIER_PATH, 'flowdock')
112
+ autoload :Zabbix, File.join(NOTIFIER_PATH, 'zabbix')
111
113
  end
112
114
 
113
115
  ##
@@ -42,7 +42,8 @@ module Backup
42
42
  ],
43
43
  # Notifiers
44
44
  ['Mail', 'Twitter', 'Campfire', 'Prowl',
45
- 'Hipchat', 'Pushover', 'HttpPost', 'Nagios', 'Slack']
45
+ 'Hipchat', 'Pushover', 'HttpPost', 'Nagios',
46
+ 'Slack', 'FlowDock', 'Zabbix']
46
47
  ]
47
48
  )
48
49
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ require 'shellwords'
2
3
 
3
4
  module Backup
4
5
  module Database
@@ -32,28 +33,48 @@ module Backup
32
33
  attr_accessor :only_tables
33
34
 
34
35
  ##
35
- # Additional "mysqldump" options
36
+ # Additional "mysqldump" or "innobackupex (backup creation)" options
36
37
  attr_accessor :additional_options
37
38
 
39
+ ##
40
+ # Additional innobackupex log preparation phase ("apply-logs") options
41
+ attr_accessor :prepare_options
42
+
43
+ ##
44
+ # Default is :mysqldump (which is built in MySQL and generates
45
+ # a textual SQL file), but can be changed to :innobackupex, which
46
+ # has more feasible restore times for large databases.
47
+ # See: http://www.percona.com/doc/percona-xtrabackup/
48
+ attr_accessor :backup_engine
49
+
50
+ ##
51
+ # If set the backup engine command block is executed as the given user
52
+ attr_accessor :sudo_user
53
+
54
+ ##
55
+ # If set, do not suppress innobackupdb output (useful for debugging)
56
+ attr_accessor :verbose
57
+
38
58
  def initialize(model, database_id = nil, &block)
39
59
  super
40
60
  instance_eval(&block) if block_given?
41
61
 
42
62
  @name ||= :all
63
+ @backup_engine ||= :mysqldump
43
64
  end
44
65
 
45
66
  ##
46
- # Performs the mysqldump command and outputs the dump file
47
- # in the +dump_path+ using +dump_filename+.
67
+ # Performs the mysqldump or innobackupex command and outputs
68
+ # the dump file in the +dump_path+ using +dump_filename+.
48
69
  #
49
- # <trigger>/databases/MySQL[-<database_id>].sql[.gz]
70
+ # <trigger>/databases/MySQL[-<database_id>].[sql|tar][.gz]
50
71
  def perform!
51
72
  super
52
73
 
53
74
  pipeline = Pipeline.new
54
- dump_ext = 'sql'
75
+ dump_ext = sql_backup? ? 'sql' : 'tar'
55
76
 
56
- pipeline << mysqldump
77
+ pipeline << sudo_option(sql_backup? ? mysqldump : innobackupex)
57
78
 
58
79
  model.compressor.compress_with do |command, ext|
59
80
  pipeline << command
@@ -81,8 +102,8 @@ module Backup
81
102
 
82
103
  def credential_options
83
104
  opts = []
84
- opts << "--user='#{ username }'" if username
85
- opts << "--password='#{ password }'" if password
105
+ opts << "--user=#{ Shellwords.escape(username) }" if username
106
+ opts << "--password=#{ Shellwords.escape(password) }" if password
86
107
  opts.join(' ')
87
108
  end
88
109
 
@@ -99,6 +120,10 @@ module Backup
99
120
  Array(additional_options).join(' ')
100
121
  end
101
122
 
123
+ def user_prepare_options
124
+ Array(prepare_options).join(' ')
125
+ end
126
+
102
127
  def name_option
103
128
  dump_all? ? '--all-databases' : name
104
129
  end
@@ -118,6 +143,39 @@ module Backup
118
143
  name == :all
119
144
  end
120
145
 
146
+ def sql_backup?
147
+ backup_engine.to_sym == :mysqldump
148
+ end
149
+
150
+ def innobackupex
151
+ # Creation phase
152
+ "#{ utility(:innobackupex) } #{ credential_options } " +
153
+ "#{ connectivity_options } #{ user_options } " +
154
+ "--no-timestamp #{ temp_dir } #{ quiet_option } && " +
155
+ # Log applying phase (prepare for restore)
156
+ "#{ utility(:innobackupex) } --apply-log #{ temp_dir } " +
157
+ "#{ user_prepare_options } #{ quiet_option } && " +
158
+ # Move files to tar-ed stream on stdout
159
+ "#{ utility(:tar) } --remove-files -cf - " +
160
+ "-C #{ File.dirname(temp_dir) } #{ File.basename(temp_dir) }"
161
+ end
162
+
163
+ def sudo_option(command_block)
164
+ return command_block unless sudo_user
165
+
166
+ "sudo -s -u #{ sudo_user } -- <<END_OF_SUDO\n" +
167
+ "#{command_block}\n" +
168
+ "END_OF_SUDO\n"
169
+ end
170
+
171
+ def quiet_option
172
+ verbose ? "" : " 2> /dev/null "
173
+ end
174
+
175
+ def temp_dir
176
+ File.join(dump_path, dump_filename + ".bkpdir")
177
+ end
178
+
121
179
  end
122
180
  end
123
181
  end
@@ -45,7 +45,7 @@ module Backup
45
45
  end
46
46
 
47
47
  ##
48
- # Performs the mysqldump command and outputs the dump file
48
+ # Performs the pgdump command and outputs the dump file
49
49
  # in the +dump_path+ using +dump_filename+.
50
50
  #
51
51
  # <trigger>/databases/PostgreSQL[-<database_id>].sql[.gz]
@@ -35,6 +35,19 @@ module Backup
35
35
  # @return [String] Default: 'log'
36
36
  attr_reader :log_path
37
37
 
38
+ ##
39
+ # Backup's logfile in which backup logs can be written
40
+ #
41
+ # As there is already a log_path, this can simply be just a file name
42
+ # that will be created (If not exists) on log_path directory
43
+ #
44
+ # This may also be set on the command line using +--log-file+.
45
+ # If set on the command line, any setting here will be ignored.
46
+ #
47
+ # @param [String]
48
+ # @return [String] Default: 'backup.log'
49
+ attr_reader :log_file
50
+
38
51
  ##
39
52
  # Size in bytes to truncate logfile to before backup jobs are run.
40
53
  #
@@ -89,7 +102,8 @@ module Backup
89
102
  path = File.join(Backup::Config.root_path, path)
90
103
  end
91
104
  FileUtils.mkdir_p(path)
92
- path = File.join(path, 'backup.log')
105
+ log_file = @options.log_file || 'backup.log'
106
+ path = File.join(path, log_file)
93
107
  if File.exist?(path) && !File.writable?(path)
94
108
  raise Error, "Log File at '#{ path }' is not writable"
95
109
  end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+ require 'flowdock'
3
+
4
+ module Backup
5
+ module Notifier
6
+ class FlowDock < Base
7
+
8
+ ##
9
+ # The Flowdock API token
10
+ attr_accessor :token
11
+
12
+ ##
13
+ # Who the notification should appear from
14
+ attr_accessor :from_name
15
+
16
+ # Which email the notification should appear from
17
+ attr_accessor :from_email
18
+
19
+ ##
20
+ # source for message
21
+ attr_accessor :source
22
+
23
+ ##
24
+ # Subject for message
25
+ attr_accessor :subject
26
+
27
+ ##
28
+ # tag message in inbox
29
+ attr_accessor :tags
30
+
31
+ ##
32
+ # link for message
33
+ attr_accessor :link
34
+
35
+ def initialize(model, &block)
36
+ super
37
+ instance_eval(&block) if block_given?
38
+
39
+ @subject ||= default_subject
40
+ @source ||= default_source
41
+ @tags ||= []
42
+ end
43
+
44
+ private
45
+
46
+ ##
47
+ # Notify the user of the backup operation results.
48
+ #
49
+ # `status` indicates one of the following:
50
+ #
51
+ # `:success`
52
+ # : The backup completed successfully.
53
+ # : Notification will be sent if `on_success` is `true`.
54
+ #
55
+ # `:warning`
56
+ # : The backup completed successfully, but warnings were logged.
57
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
58
+ #
59
+ # `:failure`
60
+ # : The backup operation failed.
61
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
62
+ #
63
+ def notify!(status)
64
+ @tags += default_tags(status)
65
+ message = "#{ model.label } (#{ model.trigger })"
66
+ send_message(message)
67
+ end
68
+
69
+ # Flowdock::Client will raise an error if unsuccessful.
70
+ def send_message(msg)
71
+ client = Flowdock::Flow.new(:api_token => token, :source => source,
72
+ :from => {:name => from_name, :address => from_email })
73
+
74
+ client.push_to_team_inbox(:subject => subject,
75
+ :content => msg,
76
+ :tags => tags,
77
+ :link => link )
78
+ end
79
+
80
+ # set related tags
81
+ def default_tags(status)
82
+ case status
83
+ when :success then ['#BackupSuccess']
84
+ when :warning then ['#BackupWarning']
85
+ when :failure then ['#BackupFailure']
86
+ end
87
+ end
88
+
89
+
90
+ #set default source
91
+ def default_source
92
+ "Backup #{ model.label }"
93
+ end
94
+
95
+ # set default subject
96
+ def default_subject
97
+ 'Backup Notification'
98
+ end
99
+
100
+ end
101
+ end
102
+ end
@@ -12,6 +12,10 @@ module Backup
12
12
  # Port of Nagios server to notify on backup completion.
13
13
  attr_accessor :nagios_port
14
14
 
15
+ ##
16
+ # Nagios nrpe configuration file.
17
+ attr_accessor :send_nsca_cfg
18
+
15
19
  ##
16
20
  # Name of the Nagios service for the backup check.
17
21
  attr_accessor :service_name
@@ -26,6 +30,7 @@ module Backup
26
30
 
27
31
  @nagios_host ||= Config.hostname
28
32
  @nagios_port ||= 5667
33
+ @send_nsca_cfg||= "/etc/nagios/send_nsca.cfg"
29
34
  @service_name ||= "Backup #{ model.trigger }"
30
35
  @service_host ||= Config.hostname
31
36
  end
@@ -59,7 +64,7 @@ module Backup
59
64
  end
60
65
 
61
66
  def send_message(message)
62
- cmd = "#{ utility(:send_nsca) } -H '#{ nagios_host }' -p '#{ nagios_port }'"
67
+ cmd = "#{ utility(:send_nsca) } -H '#{ nagios_host }' -p '#{ nagios_port }' -c '#{ send_nsca_cfg }'"
63
68
  msg = [service_host, service_name, model.exit_status, message].join("\t")
64
69
  run("echo '#{ msg }' | #{ cmd }")
65
70
  end
@@ -49,14 +49,13 @@ module Backup
49
49
 
50
50
  # Twitter::Client will raise an error if unsuccessful.
51
51
  def send_message(message)
52
- ::Twitter.configure do |config|
53
- config.consumer_key = @consumer_key
54
- config.consumer_secret = @consumer_secret
55
- config.oauth_token = @oauth_token
56
- config.oauth_token_secret = @oauth_token_secret
52
+ client = ::Twitter::REST::Client.new do |config|
53
+ config.consumer_key = @consumer_key
54
+ config.consumer_secret = @consumer_secret
55
+ config.access_token = @oauth_token
56
+ config.access_token_secret = @oauth_token_secret
57
57
  end
58
58
 
59
- client = ::Twitter::Client.new
60
59
  client.update(message)
61
60
  end
62
61
 
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Notifier
5
+ class Zabbix < Base
6
+
7
+ attr_accessor :zabbix_host
8
+
9
+ attr_accessor :zabbix_port
10
+
11
+ attr_accessor :service_name
12
+
13
+ attr_accessor :service_host
14
+
15
+ attr_accessor :item_key
16
+
17
+ def initialize(model, &block)
18
+ super
19
+ instance_eval(&block) if block_given?
20
+
21
+ @zabbix_host ||= Config.hostname
22
+ @zabbix_port ||= 10051
23
+ @service_name ||= "Backup #{ model.trigger }"
24
+ @service_host ||= Config.hostname
25
+ @item_key ||= 'backup_status'
26
+ end
27
+
28
+ private
29
+
30
+ ##
31
+ # Notify the user of the backup operation results.
32
+ #
33
+ # `status` indicates one of the following:
34
+ #
35
+ # `:success`
36
+ # : The backup completed successfully.
37
+ # : Notification will be sent if `on_success` is `true`.
38
+ #
39
+ # `:warning`
40
+ # : The backup completed successfully, but warnings were logged.
41
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
42
+ #
43
+ # `:failure`
44
+ # : The backup operation failed.
45
+ # : Notification will be sent if `on_warning` or `on_success` is `true`.
46
+ #
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 }")
54
+ end
55
+
56
+ def send_message(message)
57
+ msg = [service_host, service_name, model.exit_status, message].join("\t")
58
+ cmd = "#{ utility(:zabbix_sender) }" +
59
+ " -z '#{ zabbix_host }'" +
60
+ " -p '#{ zabbix_port }'" +
61
+ " -s #{ service_host }" +
62
+ " -k #{ item_key }" +
63
+ " -o '#{ msg }'"
64
+ run("echo '#{ msg }' | #{ cmd }")
65
+ end
66
+ end
67
+ end
68
+ end
@@ -8,11 +8,13 @@ module Backup
8
8
  NAMES = %w{
9
9
  tar cat split sudo chown hostname
10
10
  gzip bzip2
11
- mongo mongodump mysqldump pg_dump pg_dumpall redis-cli riak-admin
11
+ mongo mongodump mysqldump innobackupex
12
+ pg_dump pg_dumpall redis-cli riak-admin
12
13
  gpg openssl
13
14
  rsync ssh
14
15
  sendmail exim
15
16
  send_nsca
17
+ zabbix_sender
16
18
  }
17
19
 
18
20
  module DSL
@@ -94,6 +96,7 @@ module Backup
94
96
  # sendmail '/path/to/sendmail'
95
97
  # exim '/path/to/exim'
96
98
  # send_nsca '/path/to/send_nsca'
99
+ # zabbix_sender '/path/to/zabbix_sender'
97
100
  # end
98
101
  #
99
102
  # These paths may be set using absolute paths, or relative to the
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Backup
4
- VERSION = '4.0.2'
4
+ VERSION = '4.0.3'
5
5
  end
@@ -0,0 +1,15 @@
1
+ ##
2
+ # Zabbix [Notifier]
3
+ #
4
+ notify_by Zabbix do |zabbix|
5
+ zabbix.on_success = true
6
+ zabbix.on_warning = true
7
+ zabbix.on_failure = true
8
+
9
+ zabbix.zabbix_host = "zabbix_server_hostname"
10
+ zabbix.zabbix_port = 10051
11
+ zabbix.service_name = "Backup trigger"
12
+ zabbix.service_host = "zabbix_host"
13
+ zabbix.item_key = "backup_status"
14
+ end
15
+
@@ -0,0 +1,16 @@
1
+ ##
2
+ # Flowdock [Notifier]
3
+ #
4
+ notify_by FlowDock do |flowdock|
5
+ flowdock.on_success = true
6
+ flowdock.on_warning = true
7
+ flowdock.on_failure = true
8
+
9
+ flowdock.token = "token"
10
+ flowdock.from_name = 'my_name'
11
+ flowdock.from_email = 'email@example.com'
12
+ flowdock.subject = 'My Daily Backup'
13
+ flowdock.source = 'Backup'
14
+ flowdock.tags = ['prod', 'backup']
15
+ flowdock.link = 'www.example.com'
16
+ end
@@ -0,0 +1,23 @@
1
+ ##
2
+ # Slack [Notifier]
3
+ #
4
+ notify_by Slack do |slack|
5
+ slack.on_success = true
6
+ slack.on_warning = true
7
+ slack.on_failure = true
8
+
9
+ # The team name
10
+ slack.team = 'my_team'
11
+
12
+ # The integration token
13
+ slack.token = 'xxxxxxxxxxxxxxxxxxxxxxxx'
14
+
15
+ ##
16
+ # Optional
17
+ #
18
+ # The channel to which messages will be sent
19
+ # slack.channel = 'my_channel'
20
+ #
21
+ # The username to display along with the notification
22
+ # slack.username = 'my_username'
23
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.2
4
+ version: 4.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael van Rooijen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-16 00:00:00.000000000 Z
11
+ date: 2014-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
138
  version: 0.8.8
139
+ - !ruby/object:Gem::Dependency
140
+ name: flowdock
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: 0.4.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 0.4.0
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: fog
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -576,6 +590,7 @@ files:
576
590
  - lib/backup/model.rb
577
591
  - lib/backup/notifier/base.rb
578
592
  - lib/backup/notifier/campfire.rb
593
+ - lib/backup/notifier/flowdock.rb
579
594
  - lib/backup/notifier/hipchat.rb
580
595
  - lib/backup/notifier/http_post.rb
581
596
  - lib/backup/notifier/mail.rb
@@ -584,6 +599,7 @@ files:
584
599
  - lib/backup/notifier/pushover.rb
585
600
  - lib/backup/notifier/slack.rb
586
601
  - lib/backup/notifier/twitter.rb
602
+ - lib/backup/notifier/zabbix.rb
587
603
  - lib/backup/package.rb
588
604
  - lib/backup/packager.rb
589
605
  - lib/backup/pipeline.rb
@@ -624,13 +640,16 @@ files:
624
640
  - templates/cli/encryptor/gpg
625
641
  - templates/cli/encryptor/openssl
626
642
  - templates/cli/model
643
+ - templates/cli/notifier/zabbix
627
644
  - templates/cli/notifiers/campfire
645
+ - templates/cli/notifiers/flowdock
628
646
  - templates/cli/notifiers/hipchat
629
647
  - templates/cli/notifiers/http_post
630
648
  - templates/cli/notifiers/mail
631
649
  - templates/cli/notifiers/nagios
632
650
  - templates/cli/notifiers/prowl
633
651
  - templates/cli/notifiers/pushover
652
+ - templates/cli/notifiers/slack
634
653
  - templates/cli/notifiers/twitter
635
654
  - templates/cli/splitter
636
655
  - templates/cli/storages/cloud_files