backup-remote 0.0.2
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 +7 -0
- data/README.md +112 -0
- data/bin/backup-remote +5 -0
- data/lib/backup.rb +155 -0
- data/lib/backup/archive.rb +170 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/cleaner.rb +116 -0
- data/lib/backup/cli.rb +374 -0
- data/lib/backup/cloud_io/base.rb +41 -0
- data/lib/backup/cloud_io/cloud_files.rb +298 -0
- data/lib/backup/cloud_io/s3.rb +260 -0
- data/lib/backup/compressor/base.rb +35 -0
- data/lib/backup/compressor/bzip2.rb +39 -0
- data/lib/backup/compressor/custom.rb +53 -0
- data/lib/backup/compressor/gzip.rb +74 -0
- data/lib/backup/config.rb +121 -0
- data/lib/backup/config/dsl.rb +106 -0
- data/lib/backup/config/helpers.rb +143 -0
- data/lib/backup/database/base.rb +85 -0
- data/lib/backup/database/mongodb.rb +187 -0
- data/lib/backup/database/mysql.rb +192 -0
- data/lib/backup/database/openldap.rb +95 -0
- data/lib/backup/database/postgresql.rb +133 -0
- data/lib/backup/database/redis.rb +179 -0
- data/lib/backup/database/remote_mysql.rb +248 -0
- data/lib/backup/database/riak.rb +82 -0
- data/lib/backup/database/sqlite.rb +57 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +747 -0
- data/lib/backup/encryptor/open_ssl.rb +77 -0
- data/lib/backup/errors.rb +58 -0
- data/lib/backup/logger.rb +199 -0
- data/lib/backup/logger/console.rb +51 -0
- data/lib/backup/logger/fog_adapter.rb +29 -0
- data/lib/backup/logger/logfile.rb +133 -0
- data/lib/backup/logger/syslog.rb +116 -0
- data/lib/backup/model.rb +479 -0
- data/lib/backup/notifier/base.rb +128 -0
- data/lib/backup/notifier/campfire.rb +63 -0
- data/lib/backup/notifier/command.rb +102 -0
- data/lib/backup/notifier/datadog.rb +107 -0
- data/lib/backup/notifier/flowdock.rb +103 -0
- data/lib/backup/notifier/hipchat.rb +118 -0
- data/lib/backup/notifier/http_post.rb +117 -0
- data/lib/backup/notifier/mail.rb +249 -0
- data/lib/backup/notifier/nagios.rb +69 -0
- data/lib/backup/notifier/pagerduty.rb +81 -0
- data/lib/backup/notifier/prowl.rb +68 -0
- data/lib/backup/notifier/pushover.rb +74 -0
- data/lib/backup/notifier/ses.rb +105 -0
- data/lib/backup/notifier/slack.rb +148 -0
- data/lib/backup/notifier/twitter.rb +58 -0
- data/lib/backup/notifier/zabbix.rb +63 -0
- data/lib/backup/package.rb +55 -0
- data/lib/backup/packager.rb +107 -0
- data/lib/backup/pipeline.rb +128 -0
- data/lib/backup/remote/command.rb +82 -0
- data/lib/backup/splitter.rb +76 -0
- data/lib/backup/storage/base.rb +69 -0
- data/lib/backup/storage/cloud_files.rb +158 -0
- data/lib/backup/storage/cycler.rb +75 -0
- data/lib/backup/storage/dropbox.rb +212 -0
- data/lib/backup/storage/ftp.rb +112 -0
- data/lib/backup/storage/local.rb +64 -0
- data/lib/backup/storage/qiniu.rb +65 -0
- data/lib/backup/storage/rsync.rb +248 -0
- data/lib/backup/storage/s3.rb +156 -0
- data/lib/backup/storage/scp.rb +67 -0
- data/lib/backup/storage/sftp.rb +82 -0
- data/lib/backup/syncer/base.rb +70 -0
- data/lib/backup/syncer/cloud/base.rb +179 -0
- data/lib/backup/syncer/cloud/cloud_files.rb +83 -0
- data/lib/backup/syncer/cloud/local_file.rb +100 -0
- data/lib/backup/syncer/cloud/s3.rb +110 -0
- data/lib/backup/syncer/rsync/base.rb +54 -0
- data/lib/backup/syncer/rsync/local.rb +31 -0
- data/lib/backup/syncer/rsync/pull.rb +51 -0
- data/lib/backup/syncer/rsync/push.rb +205 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/utilities.rb +224 -0
- data/lib/backup/version.rb +5 -0
- data/templates/cli/archive +28 -0
- data/templates/cli/compressor/bzip2 +4 -0
- data/templates/cli/compressor/custom +7 -0
- data/templates/cli/compressor/gzip +4 -0
- data/templates/cli/config +123 -0
- data/templates/cli/databases/mongodb +15 -0
- data/templates/cli/databases/mysql +18 -0
- data/templates/cli/databases/openldap +24 -0
- data/templates/cli/databases/postgresql +16 -0
- data/templates/cli/databases/redis +16 -0
- data/templates/cli/databases/riak +17 -0
- data/templates/cli/databases/sqlite +11 -0
- data/templates/cli/encryptor/gpg +27 -0
- data/templates/cli/encryptor/openssl +9 -0
- data/templates/cli/model +26 -0
- data/templates/cli/notifier/zabbix +15 -0
- data/templates/cli/notifiers/campfire +12 -0
- data/templates/cli/notifiers/command +32 -0
- data/templates/cli/notifiers/datadog +57 -0
- data/templates/cli/notifiers/flowdock +16 -0
- data/templates/cli/notifiers/hipchat +16 -0
- data/templates/cli/notifiers/http_post +32 -0
- data/templates/cli/notifiers/mail +24 -0
- data/templates/cli/notifiers/nagios +13 -0
- data/templates/cli/notifiers/pagerduty +12 -0
- data/templates/cli/notifiers/prowl +11 -0
- data/templates/cli/notifiers/pushover +11 -0
- data/templates/cli/notifiers/ses +15 -0
- data/templates/cli/notifiers/slack +22 -0
- data/templates/cli/notifiers/twitter +13 -0
- data/templates/cli/splitter +7 -0
- data/templates/cli/storages/cloud_files +11 -0
- data/templates/cli/storages/dropbox +20 -0
- data/templates/cli/storages/ftp +13 -0
- data/templates/cli/storages/local +8 -0
- data/templates/cli/storages/qiniu +12 -0
- data/templates/cli/storages/rsync +17 -0
- data/templates/cli/storages/s3 +16 -0
- data/templates/cli/storages/scp +15 -0
- data/templates/cli/storages/sftp +15 -0
- data/templates/cli/syncers/cloud_files +22 -0
- data/templates/cli/syncers/rsync_local +20 -0
- data/templates/cli/syncers/rsync_pull +28 -0
- data/templates/cli/syncers/rsync_push +28 -0
- data/templates/cli/syncers/s3 +27 -0
- data/templates/general/links +3 -0
- data/templates/general/version.erb +2 -0
- data/templates/notifier/mail/failure.erb +16 -0
- data/templates/notifier/mail/success.erb +16 -0
- data/templates/notifier/mail/warning.erb +16 -0
- data/templates/storage/dropbox/authorization_url.erb +6 -0
- data/templates/storage/dropbox/authorized.erb +4 -0
- data/templates/storage/dropbox/cache_file_written.erb +10 -0
- metadata +1122 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Database
|
|
5
|
+
class Error < Backup::Error; end
|
|
6
|
+
|
|
7
|
+
class Base
|
|
8
|
+
include Utilities::Helpers
|
|
9
|
+
include Config::Helpers
|
|
10
|
+
|
|
11
|
+
attr_reader :model, :database_id, :dump_path
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# If given, +database_id+ will be appended to the #dump_filename.
|
|
15
|
+
# This is required if multiple Databases of the same class are added to
|
|
16
|
+
# the model.
|
|
17
|
+
def initialize(model, database_id = nil)
|
|
18
|
+
@model = model
|
|
19
|
+
@database_id = database_id.to_s.gsub(/\W/, '_') if database_id
|
|
20
|
+
@dump_path = File.join(Config.tmp_path, model.trigger, 'databases')
|
|
21
|
+
load_defaults!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def perform!
|
|
25
|
+
log!(:started)
|
|
26
|
+
prepare!
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def prepare!
|
|
32
|
+
FileUtils.mkdir_p(dump_path)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Sets the base filename for the final dump file to be saved in +dump_path+,
|
|
37
|
+
# based on the class name. e.g. databases/MySQL.sql
|
|
38
|
+
#
|
|
39
|
+
# +database_id+ will be appended if it is defined.
|
|
40
|
+
# e.g. databases/MySQL-database_id.sql
|
|
41
|
+
#
|
|
42
|
+
# If multiple Databases of the same class are defined and no +database_id+
|
|
43
|
+
# is defined, the user will be warned and one will be auto-generated.
|
|
44
|
+
#
|
|
45
|
+
# Model#initialize calls this method *after* all defined databases have
|
|
46
|
+
# been initialized so `backup check` can report these warnings.
|
|
47
|
+
def dump_filename
|
|
48
|
+
@dump_filename ||= begin
|
|
49
|
+
unless database_id
|
|
50
|
+
if model.databases.select {|d| d.class == self.class }.count > 1
|
|
51
|
+
sleep 1; @database_id = Time.now.to_i.to_s[-5, 5]
|
|
52
|
+
Logger.warn Error.new(<<-EOS)
|
|
53
|
+
Database Identifier Missing
|
|
54
|
+
When multiple Databases are configured in a single Backup Model
|
|
55
|
+
that have the same class (MySQL, PostgreSQL, etc.), the optional
|
|
56
|
+
+database_id+ must be specified to uniquely identify each instance.
|
|
57
|
+
e.g. database MySQL, :database_id do |db|
|
|
58
|
+
This will result in an output file in your final backup package like:
|
|
59
|
+
databases/MySQL-database_id.sql
|
|
60
|
+
|
|
61
|
+
Backup has auto-generated an identifier (#{ database_id }) for this
|
|
62
|
+
database dump and will now continue.
|
|
63
|
+
EOS
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
self.class.name.split('::').last + (database_id ? "-#{ database_id }" : '')
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def database_name
|
|
72
|
+
@database_name ||= self.class.to_s.sub('Backup::', '') +
|
|
73
|
+
(database_id ? " (#{ database_id })" : '')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def log!(action)
|
|
77
|
+
msg = case action
|
|
78
|
+
when :started then 'Started...'
|
|
79
|
+
when :finished then 'Finished!'
|
|
80
|
+
end
|
|
81
|
+
Logger.info "#{ database_name } #{ msg }"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Database
|
|
5
|
+
class MongoDB < Base
|
|
6
|
+
class Error < Backup::Error; end
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# Name of the database that needs to get dumped
|
|
10
|
+
attr_accessor :name
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Credentials for the specified database
|
|
14
|
+
attr_accessor :username, :password, :authdb
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# Connectivity options
|
|
18
|
+
attr_accessor :host, :port
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# IPv6 support (disabled by default)
|
|
22
|
+
attr_accessor :ipv6
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Collections to dump, collections that aren't specified won't get dumped
|
|
26
|
+
attr_accessor :only_collections
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Additional "mongodump" options
|
|
30
|
+
attr_accessor :additional_options
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Forces mongod to flush all pending write operations to the disk and
|
|
34
|
+
# locks the entire mongod instance to prevent additional writes until the
|
|
35
|
+
# dump is complete.
|
|
36
|
+
#
|
|
37
|
+
# Note that if Profiling is enabled, this will disable it and will not
|
|
38
|
+
# re-enable it after the dump is complete.
|
|
39
|
+
attr_accessor :lock
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Creates a dump of the database that includes an oplog, to create a
|
|
43
|
+
# point-in-time snapshot of the state of a mongod instance.
|
|
44
|
+
#
|
|
45
|
+
# If this option is used, you would not use the `lock` option.
|
|
46
|
+
#
|
|
47
|
+
# This will only work against nodes that maintain a oplog.
|
|
48
|
+
# This includes all members of a replica set, as well as master nodes in
|
|
49
|
+
# master/slave replication deployments.
|
|
50
|
+
attr_accessor :oplog
|
|
51
|
+
|
|
52
|
+
def initialize(model, database_id = nil, &block)
|
|
53
|
+
super
|
|
54
|
+
instance_eval(&block) if block_given?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def perform!
|
|
58
|
+
super
|
|
59
|
+
|
|
60
|
+
lock_database if @lock
|
|
61
|
+
dump!
|
|
62
|
+
package!
|
|
63
|
+
|
|
64
|
+
ensure
|
|
65
|
+
unlock_database if @lock
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Performs all required mongodump commands, dumping the output files
|
|
72
|
+
# into the +dump_packaging_path+ directory for packaging.
|
|
73
|
+
def dump!
|
|
74
|
+
FileUtils.mkdir_p dump_packaging_path
|
|
75
|
+
|
|
76
|
+
collections = Array(only_collections)
|
|
77
|
+
if collections.empty?
|
|
78
|
+
run(mongodump)
|
|
79
|
+
else
|
|
80
|
+
collections.each do |collection|
|
|
81
|
+
run("#{ mongodump } --collection='#{ collection }'")
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
# Creates a tar archive of the +dump_packaging_path+ directory
|
|
88
|
+
# and stores it in the +dump_path+ using +dump_filename+.
|
|
89
|
+
#
|
|
90
|
+
# <trigger>/databases/MongoDB[-<database_id>].tar[.gz]
|
|
91
|
+
#
|
|
92
|
+
# If successful, +dump_packaging_path+ is removed.
|
|
93
|
+
def package!
|
|
94
|
+
pipeline = Pipeline.new
|
|
95
|
+
dump_ext = 'tar'
|
|
96
|
+
|
|
97
|
+
pipeline << "#{ utility(:tar) } -cf - " +
|
|
98
|
+
"-C '#{ dump_path }' '#{ dump_filename }'"
|
|
99
|
+
|
|
100
|
+
model.compressor.compress_with do |command, ext|
|
|
101
|
+
pipeline << command
|
|
102
|
+
dump_ext << ext
|
|
103
|
+
end if model.compressor
|
|
104
|
+
|
|
105
|
+
pipeline << "#{ utility(:cat) } > " +
|
|
106
|
+
"'#{ File.join(dump_path, dump_filename) }.#{ dump_ext }'"
|
|
107
|
+
|
|
108
|
+
pipeline.run
|
|
109
|
+
if pipeline.success?
|
|
110
|
+
FileUtils.rm_rf dump_packaging_path
|
|
111
|
+
log!(:finished)
|
|
112
|
+
else
|
|
113
|
+
raise Error, "Dump Failed!\n" + pipeline.error_messages
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def dump_packaging_path
|
|
118
|
+
File.join(dump_path, dump_filename)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def mongodump
|
|
122
|
+
"#{ utility(:mongodump) } #{ name_option } #{ credential_options } " +
|
|
123
|
+
"#{ connectivity_options } #{ ipv6_option } #{ oplog_option } " +
|
|
124
|
+
"#{ user_options } --out='#{ dump_packaging_path }'"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def name_option
|
|
128
|
+
"--db='#{ name }'" if name
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def credential_options
|
|
132
|
+
opts = []
|
|
133
|
+
opts << "--username='#{ username }'" if username
|
|
134
|
+
opts << "--password='#{ password }'" if password
|
|
135
|
+
opts << "--authenticationDatabase='#{ authdb }'" if authdb
|
|
136
|
+
opts.join(' ')
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def connectivity_options
|
|
140
|
+
opts = []
|
|
141
|
+
opts << "--host='#{ host }'" if host
|
|
142
|
+
opts << "--port='#{ port }'" if port
|
|
143
|
+
opts.join(' ')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def ipv6_option
|
|
147
|
+
'--ipv6' if ipv6
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def oplog_option
|
|
151
|
+
'--oplog' if oplog
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def user_options
|
|
155
|
+
Array(additional_options).join(' ')
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def lock_database
|
|
159
|
+
lock_command = <<-EOS.gsub(/^ +/, '')
|
|
160
|
+
echo 'use admin
|
|
161
|
+
db.setProfilingLevel(0)
|
|
162
|
+
db.fsyncLock()' | #{ mongo_shell }
|
|
163
|
+
EOS
|
|
164
|
+
|
|
165
|
+
run(lock_command)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def unlock_database
|
|
169
|
+
unlock_command = <<-EOS.gsub(/^ +/, '')
|
|
170
|
+
echo 'use admin
|
|
171
|
+
db.fsyncUnlock()' | #{ mongo_shell }
|
|
172
|
+
EOS
|
|
173
|
+
|
|
174
|
+
run(unlock_command)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def mongo_shell
|
|
178
|
+
cmd = "#{ utility(:mongo) } #{ connectivity_options }".rstrip
|
|
179
|
+
cmd << " #{ credential_options }".rstrip
|
|
180
|
+
cmd << " #{ ipv6_option }".rstrip
|
|
181
|
+
cmd << " '#{ name }'" if name
|
|
182
|
+
cmd
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Database
|
|
5
|
+
class MySQL < Base
|
|
6
|
+
class Error < Backup::Error; end
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# Name of the database that needs to get dumped
|
|
10
|
+
# To dump all databases, set this to `:all` or leave blank.
|
|
11
|
+
attr_accessor :name
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Credentials for the specified database
|
|
15
|
+
attr_accessor :username, :password
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
# Connectivity options
|
|
19
|
+
attr_accessor :host, :port, :socket
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# Tables to skip while dumping the database
|
|
23
|
+
#
|
|
24
|
+
# If `name` is set to :all (or not specified), these must include
|
|
25
|
+
# a database name. e.g. 'name.table'.
|
|
26
|
+
# If `name` is given, these may simply be table names.
|
|
27
|
+
attr_accessor :skip_tables
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Tables to dump. This in only valid if `name` is specified.
|
|
31
|
+
# If none are given, the entire database will be dumped.
|
|
32
|
+
attr_accessor :only_tables
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# Additional "mysqldump" or "innobackupex (backup creation)" options
|
|
36
|
+
attr_accessor :additional_options
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Additional innobackupex log preparation phase ("apply-logs") options
|
|
40
|
+
attr_accessor :prepare_options
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# Default is :mysqldump (which is built in MySQL and generates
|
|
44
|
+
# a textual SQL file), but can be changed to :innobackupex, which
|
|
45
|
+
# has more feasible restore times for large databases.
|
|
46
|
+
# See: http://www.percona.com/doc/percona-xtrabackup/
|
|
47
|
+
attr_accessor :backup_engine
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# If true (which is the default behaviour), the backup will be prepared
|
|
51
|
+
# after it has been successfuly created. This option is only valid if
|
|
52
|
+
# :backup_engine is set to :innobackupex.
|
|
53
|
+
attr_accessor :prepare_backup
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# If set the backup engine command block is executed as the given user
|
|
57
|
+
attr_accessor :sudo_user
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# If set, do not suppress innobackupdb output (useful for debugging)
|
|
61
|
+
attr_accessor :verbose
|
|
62
|
+
|
|
63
|
+
def initialize(model, database_id = nil, &block)
|
|
64
|
+
super
|
|
65
|
+
instance_eval(&block) if block_given?
|
|
66
|
+
|
|
67
|
+
@name ||= :all
|
|
68
|
+
@backup_engine ||= :mysqldump
|
|
69
|
+
@prepare_backup = true if @prepare_backup.nil?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
##
|
|
73
|
+
# Performs the mysqldump or innobackupex command and outputs
|
|
74
|
+
# the dump file in the +dump_path+ using +dump_filename+.
|
|
75
|
+
#
|
|
76
|
+
# <trigger>/databases/MySQL[-<database_id>].[sql|tar][.gz]
|
|
77
|
+
def perform!
|
|
78
|
+
super
|
|
79
|
+
|
|
80
|
+
pipeline = Pipeline.new
|
|
81
|
+
dump_ext = sql_backup? ? 'sql' : 'tar'
|
|
82
|
+
|
|
83
|
+
pipeline << sudo_option(sql_backup? ? mysqldump : innobackupex)
|
|
84
|
+
|
|
85
|
+
model.compressor.compress_with do |command, ext|
|
|
86
|
+
pipeline << command
|
|
87
|
+
dump_ext << ext
|
|
88
|
+
end if model.compressor
|
|
89
|
+
|
|
90
|
+
pipeline << "#{ utility(:cat) } > " +
|
|
91
|
+
"'#{ File.join(dump_path, dump_filename) }.#{ dump_ext }'"
|
|
92
|
+
|
|
93
|
+
pipeline.run
|
|
94
|
+
if pipeline.success?
|
|
95
|
+
log!(:finished)
|
|
96
|
+
else
|
|
97
|
+
raise Error, "Dump Failed!\n" + pipeline.error_messages
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
def mysqldump
|
|
104
|
+
"#{ utility(:mysqldump) } #{ user_options } #{ credential_options } " +
|
|
105
|
+
"#{ connectivity_options } #{ name_option } " +
|
|
106
|
+
"#{ tables_to_dump } #{ tables_to_skip }"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def credential_options
|
|
110
|
+
opts = []
|
|
111
|
+
opts << "--user=#{ Shellwords.escape(username) }" if username
|
|
112
|
+
opts << "--password=#{ Shellwords.escape(password) }" if password
|
|
113
|
+
opts.join(' ')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def connectivity_options
|
|
117
|
+
return "--socket='#{ socket }'" if socket
|
|
118
|
+
|
|
119
|
+
opts = []
|
|
120
|
+
opts << "--host='#{ host }'" if host
|
|
121
|
+
opts << "--port='#{ port }'" if port
|
|
122
|
+
opts.join(' ')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def user_options
|
|
126
|
+
Array(additional_options).join(' ')
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def user_prepare_options
|
|
130
|
+
Array(prepare_options).join(' ')
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def name_option
|
|
134
|
+
dump_all? ? '--all-databases' : name
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def tables_to_dump
|
|
138
|
+
Array(only_tables).join(' ') unless dump_all?
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def tables_to_skip
|
|
142
|
+
Array(skip_tables).map do |table|
|
|
143
|
+
table = (dump_all? || table['.']) ? table : "#{ name }.#{ table }"
|
|
144
|
+
"--ignore-table='#{ table }'"
|
|
145
|
+
end.join(' ')
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def dump_all?
|
|
149
|
+
name == :all
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def sql_backup?
|
|
153
|
+
backup_engine.to_sym == :mysqldump
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def innobackupex
|
|
157
|
+
# Creation phase
|
|
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
|
+
end
|
|
166
|
+
|
|
167
|
+
def innobackupex_prepare
|
|
168
|
+
return "" unless @prepare_backup
|
|
169
|
+
# Log applying phase (prepare for restore)
|
|
170
|
+
"#{ utility(:innobackupex) } --apply-log #{ temp_dir } " +
|
|
171
|
+
"#{ user_prepare_options } #{ quiet_option } && "
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def sudo_option(command_block)
|
|
175
|
+
return command_block unless sudo_user
|
|
176
|
+
|
|
177
|
+
"sudo -s -u #{ sudo_user } -- <<END_OF_SUDO\n" +
|
|
178
|
+
"#{command_block}\n" +
|
|
179
|
+
"END_OF_SUDO\n"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def quiet_option
|
|
183
|
+
verbose ? "" : " 2> /dev/null "
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def temp_dir
|
|
187
|
+
File.join(dump_path, dump_filename + ".bkpdir")
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|