backup 4.4.1 → 5.0.0.beta.1
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 +5 -5
- data/LICENSE +19 -0
- data/README.md +1 -1
- data/lib/backup.rb +74 -78
- data/lib/backup/archive.rb +31 -32
- data/lib/backup/binder.rb +2 -6
- data/lib/backup/cleaner.rb +14 -18
- data/lib/backup/cli.rb +104 -108
- data/lib/backup/cloud_io/base.rb +4 -7
- data/lib/backup/cloud_io/cloud_files.rb +60 -62
- data/lib/backup/cloud_io/s3.rb +69 -76
- data/lib/backup/compressor/base.rb +4 -7
- data/lib/backup/compressor/bzip2.rb +3 -7
- data/lib/backup/compressor/custom.rb +2 -6
- data/lib/backup/compressor/gzip.rb +16 -17
- data/lib/backup/config.rb +17 -18
- data/lib/backup/config/dsl.rb +16 -17
- data/lib/backup/config/helpers.rb +10 -16
- data/lib/backup/database/base.rb +22 -21
- data/lib/backup/database/mongodb.rb +36 -37
- data/lib/backup/database/mysql.rb +40 -41
- data/lib/backup/database/openldap.rb +8 -10
- data/lib/backup/database/postgresql.rb +29 -30
- data/lib/backup/database/redis.rb +27 -30
- data/lib/backup/database/riak.rb +15 -18
- data/lib/backup/database/sqlite.rb +4 -6
- data/lib/backup/encryptor/base.rb +2 -4
- data/lib/backup/encryptor/gpg.rb +49 -59
- data/lib/backup/encryptor/open_ssl.rb +11 -14
- data/lib/backup/errors.rb +7 -12
- data/lib/backup/logger.rb +16 -18
- data/lib/backup/logger/console.rb +5 -8
- data/lib/backup/logger/fog_adapter.rb +2 -6
- data/lib/backup/logger/logfile.rb +10 -12
- data/lib/backup/logger/syslog.rb +2 -4
- data/lib/backup/model.rb +75 -40
- data/lib/backup/notifier/base.rb +24 -26
- data/lib/backup/notifier/campfire.rb +9 -11
- data/lib/backup/notifier/command.rb +0 -3
- data/lib/backup/notifier/datadog.rb +9 -12
- data/lib/backup/notifier/flowdock.rb +13 -17
- data/lib/backup/notifier/hipchat.rb +11 -13
- data/lib/backup/notifier/http_post.rb +11 -14
- data/lib/backup/notifier/mail.rb +44 -47
- data/lib/backup/notifier/nagios.rb +5 -9
- data/lib/backup/notifier/pagerduty.rb +10 -12
- data/lib/backup/notifier/prowl.rb +15 -15
- data/lib/backup/notifier/pushover.rb +7 -10
- data/lib/backup/notifier/ses.rb +34 -16
- data/lib/backup/notifier/slack.rb +39 -40
- data/lib/backup/notifier/twitter.rb +2 -5
- data/lib/backup/notifier/zabbix.rb +11 -14
- data/lib/backup/package.rb +5 -9
- data/lib/backup/packager.rb +16 -17
- data/lib/backup/pipeline.rb +17 -21
- data/lib/backup/splitter.rb +8 -11
- data/lib/backup/storage/base.rb +5 -8
- data/lib/backup/storage/cloud_files.rb +21 -23
- data/lib/backup/storage/cycler.rb +10 -15
- data/lib/backup/storage/dropbox.rb +15 -21
- data/lib/backup/storage/ftp.rb +8 -10
- data/lib/backup/storage/local.rb +5 -8
- data/lib/backup/storage/qiniu.rb +8 -8
- data/lib/backup/storage/rsync.rb +24 -26
- data/lib/backup/storage/s3.rb +27 -28
- data/lib/backup/storage/scp.rb +10 -12
- data/lib/backup/storage/sftp.rb +10 -12
- data/lib/backup/syncer/base.rb +5 -8
- data/lib/backup/syncer/cloud/base.rb +27 -30
- data/lib/backup/syncer/cloud/cloud_files.rb +16 -18
- data/lib/backup/syncer/cloud/local_file.rb +5 -8
- data/lib/backup/syncer/cloud/s3.rb +23 -24
- data/lib/backup/syncer/rsync/base.rb +6 -10
- data/lib/backup/syncer/rsync/local.rb +1 -5
- data/lib/backup/syncer/rsync/pull.rb +6 -10
- data/lib/backup/syncer/rsync/push.rb +18 -22
- data/lib/backup/template.rb +9 -14
- data/lib/backup/utilities.rb +82 -69
- data/lib/backup/version.rb +1 -3
- metadata +100 -660
data/lib/backup/config/dsl.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
module Config
|
5
3
|
# Context for loading user config.rb and model files.
|
@@ -27,23 +25,23 @@ module Backup
|
|
27
25
|
create_modules(
|
28
26
|
DSL,
|
29
27
|
[ # Databases
|
30
|
-
[
|
28
|
+
["MySQL", "PostgreSQL", "MongoDB", "Redis", "Riak", "OpenLDAP", "SQLite"],
|
31
29
|
# Storages
|
32
|
-
[
|
33
|
-
|
30
|
+
["S3", "CloudFiles", "Dropbox", "FTP",
|
31
|
+
"SFTP", "SCP", "RSync", "Local", "Qiniu"],
|
34
32
|
# Compressors
|
35
|
-
[
|
33
|
+
["Gzip", "Bzip2", "Custom"],
|
36
34
|
# Encryptors
|
37
|
-
[
|
35
|
+
["OpenSSL", "GPG"],
|
38
36
|
# Syncers
|
39
37
|
[
|
40
|
-
{
|
41
|
-
{
|
38
|
+
{ "Cloud" => ["CloudFiles", "S3"] },
|
39
|
+
{ "RSync" => ["Push", "Pull", "Local"] }
|
42
40
|
],
|
43
41
|
# Notifiers
|
44
|
-
[
|
45
|
-
|
46
|
-
|
42
|
+
["Mail", "Twitter", "Campfire", "Prowl",
|
43
|
+
"Hipchat", "PagerDuty", "Pushover", "HttpPost", "Nagios",
|
44
|
+
"Slack", "FlowDock", "Zabbix", "Ses", "DataDog", "Command"]
|
47
45
|
]
|
48
46
|
)
|
49
47
|
end
|
@@ -69,7 +67,7 @@ module Backup
|
|
69
67
|
end
|
70
68
|
end
|
71
69
|
|
72
|
-
add_dsl_constants
|
70
|
+
add_dsl_constants # add constants on load
|
73
71
|
|
74
72
|
attr_reader :_config_options
|
75
73
|
|
@@ -79,25 +77,26 @@ module Backup
|
|
79
77
|
|
80
78
|
# Allow users to set command line path options in config.rb
|
81
79
|
[:root_path, :data_path, :tmp_path].each do |name|
|
82
|
-
define_method name
|
80
|
+
define_method name do |path|
|
81
|
+
_config_options[name] = path
|
82
|
+
end
|
83
83
|
end
|
84
84
|
|
85
85
|
# Allows users to create preconfigured models.
|
86
86
|
def preconfigure(name, &block)
|
87
87
|
unless name.is_a?(String) && name =~ /^[A-Z]/
|
88
|
-
raise Error, "Preconfigured model names must be given as a string "
|
88
|
+
raise Error, "Preconfigured model names must be given as a string " \
|
89
89
|
"and start with a capital letter."
|
90
90
|
end
|
91
91
|
|
92
92
|
if DSL.const_defined?(name)
|
93
|
-
raise Error, "'#{
|
93
|
+
raise Error, "'#{name}' is already in use " \
|
94
94
|
"and can not be used for a preconfigured model."
|
95
95
|
end
|
96
96
|
|
97
97
|
DSL.const_set(name, Class.new(Model))
|
98
98
|
DSL.const_get(name).preconfigure(&block)
|
99
99
|
end
|
100
|
-
|
101
100
|
end
|
102
101
|
end
|
103
102
|
end
|
@@ -1,16 +1,13 @@
|
|
1
|
-
|
2
|
-
require 'ostruct'
|
1
|
+
require "ostruct"
|
3
2
|
|
4
3
|
module Backup
|
5
4
|
module Config
|
6
5
|
module Helpers
|
7
|
-
|
8
6
|
def self.included(klass)
|
9
7
|
klass.extend ClassMethods
|
10
8
|
end
|
11
9
|
|
12
10
|
module ClassMethods
|
13
|
-
|
14
11
|
def defaults
|
15
12
|
@defaults ||= Config::Defaults.new
|
16
13
|
|
@@ -31,12 +28,12 @@ module Backup
|
|
31
28
|
end
|
32
29
|
|
33
30
|
def log_deprecation_warning(name, deprecation)
|
34
|
-
msg = "#{
|
35
|
-
"backup v.#{
|
36
|
-
msg << "\n#{
|
31
|
+
msg = "#{self}##{name} has been deprecated as of " \
|
32
|
+
"backup v.#{deprecation[:version]}"
|
33
|
+
msg << "\n#{deprecation[:message]}" if deprecation[:message]
|
37
34
|
Logger.warn Config::Error.new(<<-EOS)
|
38
35
|
[DEPRECATION WARNING]
|
39
|
-
#{
|
36
|
+
#{msg}
|
40
37
|
EOS
|
41
38
|
end
|
42
39
|
|
@@ -65,12 +62,11 @@ module Backup
|
|
65
62
|
#
|
66
63
|
def attr_deprecate(name, args = {})
|
67
64
|
deprecations[name] = {
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
65
|
+
version: nil,
|
66
|
+
message: nil,
|
67
|
+
action: nil
|
71
68
|
}.merge(args)
|
72
69
|
end
|
73
|
-
|
74
70
|
end # ClassMethods
|
75
71
|
|
76
72
|
private
|
@@ -107,10 +103,10 @@ module Backup
|
|
107
103
|
#
|
108
104
|
def method_missing(name, *args)
|
109
105
|
deprecation = nil
|
110
|
-
if method = name.to_s.chomp!(
|
106
|
+
if method = name.to_s.chomp!("=")
|
111
107
|
if (len = args.count) != 1
|
112
108
|
raise ArgumentError,
|
113
|
-
"wrong number of arguments (#{
|
109
|
+
"wrong number of arguments (#{len} for 1)", caller(1)
|
114
110
|
end
|
115
111
|
deprecation = self.class.deprecations[method.to_sym]
|
116
112
|
end
|
@@ -122,7 +118,6 @@ module Backup
|
|
122
118
|
super
|
123
119
|
end
|
124
120
|
end
|
125
|
-
|
126
121
|
end # Helpers
|
127
122
|
|
128
123
|
# Store for pre-configured defaults.
|
@@ -138,6 +133,5 @@ module Backup
|
|
138
133
|
@table.clear
|
139
134
|
end
|
140
135
|
end
|
141
|
-
|
142
136
|
end
|
143
137
|
end
|
data/lib/backup/database/base.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
module Database
|
5
3
|
class Error < Backup::Error; end
|
@@ -16,8 +14,8 @@ module Backup
|
|
16
14
|
# the model.
|
17
15
|
def initialize(model, database_id = nil)
|
18
16
|
@model = model
|
19
|
-
@database_id = database_id.to_s.gsub(/\W/,
|
20
|
-
@dump_path = File.join(Config.tmp_path, model.trigger,
|
17
|
+
@database_id = database_id.to_s.gsub(/\W/, "_") if database_id
|
18
|
+
@dump_path = File.join(Config.tmp_path, model.trigger, "databases")
|
21
19
|
load_defaults!
|
22
20
|
end
|
23
21
|
|
@@ -45,11 +43,13 @@ module Backup
|
|
45
43
|
# Model#initialize calls this method *after* all defined databases have
|
46
44
|
# been initialized so `backup check` can report these warnings.
|
47
45
|
def dump_filename
|
48
|
-
@dump_filename ||=
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
@dump_filename ||=
|
47
|
+
begin
|
48
|
+
unless database_id
|
49
|
+
if model.databases.select { |d| d.class == self.class }.count > 1
|
50
|
+
sleep 1
|
51
|
+
@database_id = Time.now.to_i.to_s[-5, 5]
|
52
|
+
Logger.warn Error.new(<<-EOS)
|
53
53
|
Database Identifier Missing
|
54
54
|
When multiple Databases are configured in a single Backup Model
|
55
55
|
that have the same class (MySQL, PostgreSQL, etc.), the optional
|
@@ -58,27 +58,28 @@ module Backup
|
|
58
58
|
This will result in an output file in your final backup package like:
|
59
59
|
databases/MySQL-database_id.sql
|
60
60
|
|
61
|
-
Backup has auto-generated an identifier (#{
|
61
|
+
Backup has auto-generated an identifier (#{database_id}) for this
|
62
62
|
database dump and will now continue.
|
63
|
-
|
63
|
+
EOS
|
64
|
+
end
|
64
65
|
end
|
65
|
-
end
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
self.class.name.split("::").last + (database_id ? "-#{database_id}" : "")
|
68
|
+
end
|
69
69
|
end
|
70
70
|
|
71
71
|
def database_name
|
72
|
-
@database_name ||= self.class.to_s.sub(
|
73
|
-
|
72
|
+
@database_name ||= self.class.to_s.sub("Backup::", "") +
|
73
|
+
(database_id ? " (#{database_id})" : "")
|
74
74
|
end
|
75
75
|
|
76
76
|
def log!(action)
|
77
|
-
msg =
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
msg =
|
78
|
+
case action
|
79
|
+
when :started then "Started..."
|
80
|
+
when :finished then "Finished!"
|
81
|
+
end
|
82
|
+
Logger.info "#{database_name} #{msg}"
|
82
83
|
end
|
83
84
|
end
|
84
85
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
module Database
|
5
3
|
class MongoDB < Base
|
@@ -60,7 +58,6 @@ module Backup
|
|
60
58
|
lock_database if @lock
|
61
59
|
dump!
|
62
60
|
package!
|
63
|
-
|
64
61
|
ensure
|
65
62
|
unlock_database if @lock
|
66
63
|
end
|
@@ -78,7 +75,7 @@ module Backup
|
|
78
75
|
run(mongodump)
|
79
76
|
else
|
80
77
|
collections.each do |collection|
|
81
|
-
run("#{
|
78
|
+
run("#{mongodump} --collection='#{collection}'")
|
82
79
|
end
|
83
80
|
end
|
84
81
|
end
|
@@ -92,25 +89,27 @@ module Backup
|
|
92
89
|
# If successful, +dump_packaging_path+ is removed.
|
93
90
|
def package!
|
94
91
|
pipeline = Pipeline.new
|
95
|
-
dump_ext =
|
92
|
+
dump_ext = "tar"
|
96
93
|
|
97
|
-
pipeline << "#{
|
98
|
-
"-C '#{
|
94
|
+
pipeline << "#{utility(:tar)} -cf - " \
|
95
|
+
"-C '#{dump_path}' '#{dump_filename}'"
|
99
96
|
|
100
|
-
model.compressor
|
101
|
-
|
102
|
-
|
103
|
-
|
97
|
+
if model.compressor
|
98
|
+
model.compressor.compress_with do |command, ext|
|
99
|
+
pipeline << command
|
100
|
+
dump_ext << ext
|
101
|
+
end
|
102
|
+
end
|
104
103
|
|
105
|
-
pipeline << "#{
|
106
|
-
|
104
|
+
pipeline << "#{utility(:cat)} > " \
|
105
|
+
"'#{File.join(dump_path, dump_filename)}.#{dump_ext}'"
|
107
106
|
|
108
107
|
pipeline.run
|
109
108
|
if pipeline.success?
|
110
109
|
FileUtils.rm_rf dump_packaging_path
|
111
110
|
log!(:finished)
|
112
111
|
else
|
113
|
-
raise Error, "Dump Failed!\n
|
112
|
+
raise Error, "Dump Failed!\n#{pipeline.error_messages}"
|
114
113
|
end
|
115
114
|
end
|
116
115
|
|
@@ -119,69 +118,69 @@ module Backup
|
|
119
118
|
end
|
120
119
|
|
121
120
|
def mongodump
|
122
|
-
"#{
|
123
|
-
|
124
|
-
|
121
|
+
"#{utility(:mongodump)} #{name_option} #{credential_options} " \
|
122
|
+
"#{connectivity_options} #{ipv6_option} #{oplog_option} " \
|
123
|
+
"#{user_options} --out='#{dump_packaging_path}'"
|
125
124
|
end
|
126
125
|
|
127
126
|
def name_option
|
128
|
-
|
127
|
+
return unless name
|
128
|
+
"--db='#{name}'"
|
129
129
|
end
|
130
130
|
|
131
131
|
def credential_options
|
132
132
|
opts = []
|
133
|
-
opts << "--username='#{
|
134
|
-
opts << "--password='#{
|
135
|
-
opts << "--authenticationDatabase='#{
|
136
|
-
opts.join(
|
133
|
+
opts << "--username='#{username}'" if username
|
134
|
+
opts << "--password='#{password}'" if password
|
135
|
+
opts << "--authenticationDatabase='#{authdb}'" if authdb
|
136
|
+
opts.join(" ")
|
137
137
|
end
|
138
138
|
|
139
139
|
def connectivity_options
|
140
140
|
opts = []
|
141
|
-
opts << "--host='#{
|
142
|
-
opts << "--port='#{
|
143
|
-
opts.join(
|
141
|
+
opts << "--host='#{host}'" if host
|
142
|
+
opts << "--port='#{port}'" if port
|
143
|
+
opts.join(" ")
|
144
144
|
end
|
145
145
|
|
146
146
|
def ipv6_option
|
147
|
-
|
147
|
+
"--ipv6" if ipv6
|
148
148
|
end
|
149
149
|
|
150
150
|
def oplog_option
|
151
|
-
|
151
|
+
"--oplog" if oplog
|
152
152
|
end
|
153
153
|
|
154
154
|
def user_options
|
155
|
-
Array(additional_options).join(
|
155
|
+
Array(additional_options).join(" ")
|
156
156
|
end
|
157
157
|
|
158
158
|
def lock_database
|
159
|
-
lock_command = <<-EOS.gsub(/^ +/,
|
159
|
+
lock_command = <<-EOS.gsub(/^ +/, "")
|
160
160
|
echo 'use admin
|
161
161
|
db.setProfilingLevel(0)
|
162
|
-
db.fsyncLock()' | #{
|
162
|
+
db.fsyncLock()' | #{mongo_shell}
|
163
163
|
EOS
|
164
164
|
|
165
165
|
run(lock_command)
|
166
166
|
end
|
167
167
|
|
168
168
|
def unlock_database
|
169
|
-
unlock_command = <<-EOS.gsub(/^ +/,
|
169
|
+
unlock_command = <<-EOS.gsub(/^ +/, "")
|
170
170
|
echo 'use admin
|
171
|
-
db.fsyncUnlock()' | #{
|
171
|
+
db.fsyncUnlock()' | #{mongo_shell}
|
172
172
|
EOS
|
173
173
|
|
174
174
|
run(unlock_command)
|
175
175
|
end
|
176
176
|
|
177
177
|
def mongo_shell
|
178
|
-
cmd = "#{
|
179
|
-
cmd << " #{
|
180
|
-
cmd << " #{
|
181
|
-
cmd << " '#{
|
178
|
+
cmd = "#{utility(:mongo)} #{connectivity_options}".rstrip
|
179
|
+
cmd << " #{credential_options}".rstrip
|
180
|
+
cmd << " #{ipv6_option}".rstrip
|
181
|
+
cmd << " '#{name}'" if name
|
182
182
|
cmd
|
183
183
|
end
|
184
|
-
|
185
184
|
end
|
186
185
|
end
|
187
186
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Backup
|
4
2
|
module Database
|
5
3
|
class MySQL < Base
|
@@ -78,71 +76,73 @@ module Backup
|
|
78
76
|
super
|
79
77
|
|
80
78
|
pipeline = Pipeline.new
|
81
|
-
dump_ext = sql_backup? ?
|
79
|
+
dump_ext = sql_backup? ? "sql" : "tar"
|
82
80
|
|
83
81
|
pipeline << sudo_option(sql_backup? ? mysqldump : innobackupex)
|
84
82
|
|
85
|
-
model.compressor
|
86
|
-
|
87
|
-
|
88
|
-
|
83
|
+
if model.compressor
|
84
|
+
model.compressor.compress_with do |command, ext|
|
85
|
+
pipeline << command
|
86
|
+
dump_ext << ext
|
87
|
+
end
|
88
|
+
end
|
89
89
|
|
90
|
-
pipeline << "#{
|
91
|
-
|
90
|
+
pipeline << "#{utility(:cat)} > " \
|
91
|
+
"'#{File.join(dump_path, dump_filename)}.#{dump_ext}'"
|
92
92
|
|
93
93
|
pipeline.run
|
94
94
|
if pipeline.success?
|
95
95
|
log!(:finished)
|
96
96
|
else
|
97
|
-
raise Error, "Dump Failed!\n
|
97
|
+
raise Error, "Dump Failed!\n#{pipeline.error_messages}"
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
private
|
102
102
|
|
103
103
|
def mysqldump
|
104
|
-
"#{
|
105
|
-
|
106
|
-
|
104
|
+
"#{utility(:mysqldump)} #{user_options} #{credential_options} " \
|
105
|
+
"#{connectivity_options} #{name_option} " \
|
106
|
+
"#{tables_to_dump} #{tables_to_skip}"
|
107
107
|
end
|
108
108
|
|
109
109
|
def credential_options
|
110
110
|
opts = []
|
111
|
-
opts << "--user=#{
|
112
|
-
opts << "--password=#{
|
113
|
-
opts.join(
|
111
|
+
opts << "--user=#{Shellwords.escape(username)}" if username
|
112
|
+
opts << "--password=#{Shellwords.escape(password)}" if password
|
113
|
+
opts.join(" ")
|
114
114
|
end
|
115
115
|
|
116
116
|
def connectivity_options
|
117
|
-
return "--socket='#{
|
117
|
+
return "--socket='#{socket}'" if socket
|
118
118
|
|
119
119
|
opts = []
|
120
|
-
opts << "--host='#{
|
121
|
-
opts << "--port='#{
|
122
|
-
opts.join(
|
120
|
+
opts << "--host='#{host}'" if host
|
121
|
+
opts << "--port='#{port}'" if port
|
122
|
+
opts.join(" ")
|
123
123
|
end
|
124
124
|
|
125
125
|
def user_options
|
126
|
-
Array(additional_options).join(
|
126
|
+
Array(additional_options).join(" ")
|
127
127
|
end
|
128
128
|
|
129
129
|
def user_prepare_options
|
130
|
-
Array(prepare_options).join(
|
130
|
+
Array(prepare_options).join(" ")
|
131
131
|
end
|
132
132
|
|
133
133
|
def name_option
|
134
|
-
dump_all? ?
|
134
|
+
dump_all? ? "--all-databases" : name
|
135
135
|
end
|
136
136
|
|
137
137
|
def tables_to_dump
|
138
|
-
Array(only_tables).join(
|
138
|
+
Array(only_tables).join(" ") unless dump_all?
|
139
139
|
end
|
140
140
|
|
141
141
|
def tables_to_skip
|
142
142
|
Array(skip_tables).map do |table|
|
143
|
-
table =
|
144
|
-
"--ignore-table='#{
|
145
|
-
end.join(
|
143
|
+
table = dump_all? || table["."] ? table : "#{name}.#{table}"
|
144
|
+
"--ignore-table='#{table}'"
|
145
|
+
end.join(" ")
|
146
146
|
end
|
147
147
|
|
148
148
|
def dump_all?
|
@@ -155,28 +155,28 @@ module Backup
|
|
155
155
|
|
156
156
|
def innobackupex
|
157
157
|
# Creation phase
|
158
|
-
"#{
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
158
|
+
"#{utility(:innobackupex)} #{credential_options} " \
|
159
|
+
"#{connectivity_options} #{user_options} " \
|
160
|
+
"--no-timestamp #{temp_dir} #{quiet_option} && " +
|
161
|
+
innobackupex_prepare +
|
162
|
+
# Move files to tar-ed stream on stdout
|
163
|
+
"#{utility(:tar)} --remove-files -cf - " \
|
164
|
+
"-C #{File.dirname(temp_dir)} #{File.basename(temp_dir)}"
|
165
165
|
end
|
166
166
|
|
167
167
|
def innobackupex_prepare
|
168
168
|
return "" unless @prepare_backup
|
169
169
|
# Log applying phase (prepare for restore)
|
170
|
-
"#{
|
171
|
-
|
170
|
+
"#{utility(:innobackupex)} --apply-log #{temp_dir} " \
|
171
|
+
"#{user_prepare_options} #{quiet_option} && "
|
172
172
|
end
|
173
173
|
|
174
174
|
def sudo_option(command_block)
|
175
175
|
return command_block unless sudo_user
|
176
176
|
|
177
|
-
"sudo -s -u #{
|
178
|
-
|
179
|
-
|
177
|
+
"sudo -s -u #{sudo_user} -- <<END_OF_SUDO\n" \
|
178
|
+
"#{command_block}\n" \
|
179
|
+
"END_OF_SUDO\n"
|
180
180
|
end
|
181
181
|
|
182
182
|
def quiet_option
|
@@ -184,9 +184,8 @@ module Backup
|
|
184
184
|
end
|
185
185
|
|
186
186
|
def temp_dir
|
187
|
-
File.join(dump_path, dump_filename
|
187
|
+
File.join(dump_path, "#{dump_filename}.bkpdir")
|
188
188
|
end
|
189
|
-
|
190
189
|
end
|
191
190
|
end
|
192
191
|
end
|