backup_checksum 3.0.23
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.
- data/.gitignore +7 -0
- data/.travis.yml +10 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +130 -0
- data/Guardfile +21 -0
- data/LICENSE.md +24 -0
- data/README.md +476 -0
- data/backup_checksum.gemspec +32 -0
- data/bin/backup +11 -0
- data/lib/backup.rb +217 -0
- data/lib/backup/archive.rb +117 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/checksum/base.rb +44 -0
- data/lib/backup/checksum/shasum.rb +16 -0
- data/lib/backup/cleaner.rb +121 -0
- data/lib/backup/cli/helpers.rb +88 -0
- data/lib/backup/cli/utility.rb +247 -0
- data/lib/backup/compressor/base.rb +29 -0
- data/lib/backup/compressor/bzip2.rb +50 -0
- data/lib/backup/compressor/gzip.rb +47 -0
- data/lib/backup/compressor/lzma.rb +50 -0
- data/lib/backup/compressor/pbzip2.rb +56 -0
- data/lib/backup/config.rb +173 -0
- data/lib/backup/configuration/base.rb +15 -0
- data/lib/backup/configuration/checksum/base.rb +9 -0
- data/lib/backup/configuration/checksum/shasum.rb +9 -0
- data/lib/backup/configuration/compressor/base.rb +9 -0
- data/lib/backup/configuration/compressor/bzip2.rb +23 -0
- data/lib/backup/configuration/compressor/gzip.rb +23 -0
- data/lib/backup/configuration/compressor/lzma.rb +23 -0
- data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
- data/lib/backup/configuration/database/base.rb +19 -0
- data/lib/backup/configuration/database/mongodb.rb +49 -0
- data/lib/backup/configuration/database/mysql.rb +42 -0
- data/lib/backup/configuration/database/postgresql.rb +41 -0
- data/lib/backup/configuration/database/redis.rb +39 -0
- data/lib/backup/configuration/database/riak.rb +29 -0
- data/lib/backup/configuration/encryptor/base.rb +9 -0
- data/lib/backup/configuration/encryptor/gpg.rb +17 -0
- data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
- data/lib/backup/configuration/helpers.rb +52 -0
- data/lib/backup/configuration/notifier/base.rb +28 -0
- data/lib/backup/configuration/notifier/campfire.rb +25 -0
- data/lib/backup/configuration/notifier/hipchat.rb +41 -0
- data/lib/backup/configuration/notifier/mail.rb +112 -0
- data/lib/backup/configuration/notifier/presently.rb +25 -0
- data/lib/backup/configuration/notifier/prowl.rb +23 -0
- data/lib/backup/configuration/notifier/twitter.rb +21 -0
- data/lib/backup/configuration/storage/base.rb +18 -0
- data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
- data/lib/backup/configuration/storage/dropbox.rb +58 -0
- data/lib/backup/configuration/storage/ftp.rb +29 -0
- data/lib/backup/configuration/storage/local.rb +17 -0
- data/lib/backup/configuration/storage/ninefold.rb +20 -0
- data/lib/backup/configuration/storage/rsync.rb +29 -0
- data/lib/backup/configuration/storage/s3.rb +25 -0
- data/lib/backup/configuration/storage/scp.rb +25 -0
- data/lib/backup/configuration/storage/sftp.rb +25 -0
- data/lib/backup/configuration/syncer/base.rb +10 -0
- data/lib/backup/configuration/syncer/cloud.rb +23 -0
- data/lib/backup/configuration/syncer/cloud_files.rb +30 -0
- data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
- data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
- data/lib/backup/configuration/syncer/s3.rb +23 -0
- data/lib/backup/database/base.rb +59 -0
- data/lib/backup/database/mongodb.rb +232 -0
- data/lib/backup/database/mysql.rb +163 -0
- data/lib/backup/database/postgresql.rb +146 -0
- data/lib/backup/database/redis.rb +139 -0
- data/lib/backup/database/riak.rb +69 -0
- data/lib/backup/dependency.rb +114 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +80 -0
- data/lib/backup/encryptor/open_ssl.rb +72 -0
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/logger.rb +152 -0
- data/lib/backup/model.rb +386 -0
- data/lib/backup/notifier/base.rb +81 -0
- data/lib/backup/notifier/campfire.rb +168 -0
- data/lib/backup/notifier/hipchat.rb +99 -0
- data/lib/backup/notifier/mail.rb +206 -0
- data/lib/backup/notifier/presently.rb +88 -0
- data/lib/backup/notifier/prowl.rb +65 -0
- data/lib/backup/notifier/twitter.rb +70 -0
- data/lib/backup/package.rb +51 -0
- data/lib/backup/packager.rb +108 -0
- data/lib/backup/pipeline.rb +107 -0
- data/lib/backup/splitter.rb +75 -0
- data/lib/backup/storage/base.rb +119 -0
- data/lib/backup/storage/cloudfiles.rb +87 -0
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +181 -0
- data/lib/backup/storage/ftp.rb +119 -0
- data/lib/backup/storage/local.rb +82 -0
- data/lib/backup/storage/ninefold.rb +116 -0
- data/lib/backup/storage/rsync.rb +149 -0
- data/lib/backup/storage/s3.rb +94 -0
- data/lib/backup/storage/scp.rb +99 -0
- data/lib/backup/storage/sftp.rb +108 -0
- data/lib/backup/syncer/base.rb +42 -0
- data/lib/backup/syncer/cloud.rb +190 -0
- data/lib/backup/syncer/cloud_files.rb +56 -0
- data/lib/backup/syncer/rsync/base.rb +52 -0
- data/lib/backup/syncer/rsync/local.rb +53 -0
- data/lib/backup/syncer/rsync/pull.rb +38 -0
- data/lib/backup/syncer/rsync/push.rb +113 -0
- data/lib/backup/syncer/s3.rb +47 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +43 -0
- data/spec/archive_spec.rb +335 -0
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +176 -0
- data/spec/cli/utility_spec.rb +363 -0
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +83 -0
- data/spec/compressor/gzip_spec.rb +83 -0
- data/spec/compressor/lzma_spec.rb +83 -0
- data/spec/compressor/pbzip2_spec.rb +124 -0
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +35 -0
- data/spec/configuration/compressor/bzip2_spec.rb +29 -0
- data/spec/configuration/compressor/gzip_spec.rb +29 -0
- data/spec/configuration/compressor/lzma_spec.rb +29 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +17 -0
- data/spec/configuration/database/mongodb_spec.rb +56 -0
- data/spec/configuration/database/mysql_spec.rb +53 -0
- data/spec/configuration/database/postgresql_spec.rb +53 -0
- data/spec/configuration/database/redis_spec.rb +50 -0
- data/spec/configuration/database/riak_spec.rb +35 -0
- data/spec/configuration/encryptor/gpg_spec.rb +26 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +32 -0
- data/spec/configuration/notifier/hipchat_spec.rb +44 -0
- data/spec/configuration/notifier/mail_spec.rb +71 -0
- data/spec/configuration/notifier/presently_spec.rb +35 -0
- data/spec/configuration/notifier/prowl_spec.rb +29 -0
- data/spec/configuration/notifier/twitter_spec.rb +35 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
- data/spec/configuration/storage/dropbox_spec.rb +38 -0
- data/spec/configuration/storage/ftp_spec.rb +44 -0
- data/spec/configuration/storage/local_spec.rb +29 -0
- data/spec/configuration/storage/ninefold_spec.rb +32 -0
- data/spec/configuration/storage/rsync_spec.rb +41 -0
- data/spec/configuration/storage/s3_spec.rb +38 -0
- data/spec/configuration/storage/scp_spec.rb +41 -0
- data/spec/configuration/storage/sftp_spec.rb +41 -0
- data/spec/configuration/syncer/cloud_files_spec.rb +44 -0
- data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
- data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
- data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
- data/spec/configuration/syncer/rsync/push_spec.rb +43 -0
- data/spec/configuration/syncer/s3_spec.rb +38 -0
- data/spec/database/base_spec.rb +54 -0
- data/spec/database/mongodb_spec.rb +428 -0
- data/spec/database/mysql_spec.rb +335 -0
- data/spec/database/postgresql_spec.rb +278 -0
- data/spec/database/redis_spec.rb +260 -0
- data/spec/database/riak_spec.rb +108 -0
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +134 -0
- data/spec/encryptor/open_ssl_spec.rb +129 -0
- data/spec/errors_spec.rb +306 -0
- data/spec/logger_spec.rb +363 -0
- data/spec/model_spec.rb +649 -0
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +199 -0
- data/spec/notifier/hipchat_spec.rb +188 -0
- data/spec/notifier/mail_spec.rb +280 -0
- data/spec/notifier/presently_spec.rb +181 -0
- data/spec/notifier/prowl_spec.rb +117 -0
- data/spec/notifier/twitter_spec.rb +132 -0
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +225 -0
- data/spec/pipeline_spec.rb +257 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/splitter_spec.rb +120 -0
- data/spec/storage/base_spec.rb +160 -0
- data/spec/storage/cloudfiles_spec.rb +230 -0
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +370 -0
- data/spec/storage/ftp_spec.rb +247 -0
- data/spec/storage/local_spec.rb +235 -0
- data/spec/storage/ninefold_spec.rb +319 -0
- data/spec/storage/rsync_spec.rb +345 -0
- data/spec/storage/s3_spec.rb +221 -0
- data/spec/storage/scp_spec.rb +209 -0
- data/spec/storage/sftp_spec.rb +220 -0
- data/spec/syncer/base_spec.rb +22 -0
- data/spec/syncer/cloud_files_spec.rb +192 -0
- data/spec/syncer/rsync/base_spec.rb +118 -0
- data/spec/syncer/rsync/local_spec.rb +121 -0
- data/spec/syncer/rsync/pull_spec.rb +90 -0
- data/spec/syncer/rsync/push_spec.rb +327 -0
- data/spec/syncer/s3_spec.rb +192 -0
- data/spec/version_spec.rb +21 -0
- data/templates/cli/utility/archive +25 -0
- data/templates/cli/utility/compressor/bzip2 +7 -0
- data/templates/cli/utility/compressor/gzip +7 -0
- data/templates/cli/utility/compressor/lzma +7 -0
- data/templates/cli/utility/compressor/pbzip2 +7 -0
- data/templates/cli/utility/config +31 -0
- data/templates/cli/utility/database/mongodb +18 -0
- data/templates/cli/utility/database/mysql +21 -0
- data/templates/cli/utility/database/postgresql +17 -0
- data/templates/cli/utility/database/redis +16 -0
- data/templates/cli/utility/database/riak +11 -0
- data/templates/cli/utility/encryptor/gpg +12 -0
- data/templates/cli/utility/encryptor/openssl +9 -0
- data/templates/cli/utility/model.erb +23 -0
- data/templates/cli/utility/notifier/campfire +12 -0
- data/templates/cli/utility/notifier/hipchat +15 -0
- data/templates/cli/utility/notifier/mail +22 -0
- data/templates/cli/utility/notifier/presently +13 -0
- data/templates/cli/utility/notifier/prowl +11 -0
- data/templates/cli/utility/notifier/twitter +13 -0
- data/templates/cli/utility/splitter +7 -0
- data/templates/cli/utility/storage/cloud_files +22 -0
- data/templates/cli/utility/storage/dropbox +20 -0
- data/templates/cli/utility/storage/ftp +12 -0
- data/templates/cli/utility/storage/local +7 -0
- data/templates/cli/utility/storage/ninefold +9 -0
- data/templates/cli/utility/storage/rsync +11 -0
- data/templates/cli/utility/storage/s3 +19 -0
- data/templates/cli/utility/storage/scp +11 -0
- data/templates/cli/utility/storage/sftp +11 -0
- data/templates/cli/utility/syncer/cloud_files +48 -0
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/rsync_pull +17 -0
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/cli/utility/syncer/s3 +45 -0
- data/templates/general/links +11 -0
- data/templates/general/version.erb +2 -0
- data/templates/notifier/mail/failure.erb +9 -0
- data/templates/notifier/mail/success.erb +7 -0
- data/templates/notifier/mail/warning.erb +9 -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 +311 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Database
|
|
5
|
+
class MySQL < Base
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Name of the database that needs to get dumped
|
|
9
|
+
# To dump all databases, set this to `:all` or leave blank.
|
|
10
|
+
attr_accessor :name
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Credentials for the specified database
|
|
14
|
+
attr_accessor :username, :password
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# Connectivity options
|
|
18
|
+
attr_accessor :host, :port, :socket
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Tables to skip while dumping the database
|
|
22
|
+
attr_accessor :skip_tables
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Tables to dump, tables that aren't specified won't get dumped
|
|
26
|
+
attr_accessor :only_tables
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Additional "mysqldump" options
|
|
30
|
+
attr_accessor :additional_options
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Path to mysqldump utility (optional)
|
|
34
|
+
attr_accessor :mysqldump_utility
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Creates a new instance of the MySQL adapter object
|
|
38
|
+
def initialize(model, &block)
|
|
39
|
+
super(model)
|
|
40
|
+
|
|
41
|
+
@skip_tables ||= Array.new
|
|
42
|
+
@only_tables ||= Array.new
|
|
43
|
+
@additional_options ||= Array.new
|
|
44
|
+
|
|
45
|
+
instance_eval(&block) if block_given?
|
|
46
|
+
|
|
47
|
+
@name ||= :all
|
|
48
|
+
|
|
49
|
+
if @utility_path
|
|
50
|
+
Logger.warn "[DEPRECATED] " +
|
|
51
|
+
"Database::MySQL#utility_path has been deprecated.\n" +
|
|
52
|
+
" Use Database::MySQL#mysqldump_utility instead."
|
|
53
|
+
@mysqldump_utility ||= @utility_path
|
|
54
|
+
end
|
|
55
|
+
@mysqldump_utility ||= utility(:mysqldump)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
# Performs the mysqldump command and outputs the
|
|
60
|
+
# data to the specified path based on the 'trigger'
|
|
61
|
+
def perform!
|
|
62
|
+
super
|
|
63
|
+
|
|
64
|
+
pipeline = Pipeline.new
|
|
65
|
+
dump_ext = 'sql'
|
|
66
|
+
|
|
67
|
+
pipeline << mysqldump
|
|
68
|
+
if @model.compressor
|
|
69
|
+
@model.compressor.compress_with do |command, ext|
|
|
70
|
+
pipeline << command
|
|
71
|
+
dump_ext << ext
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
pipeline << "cat > '#{ File.join(@dump_path, dump_filename) }.#{ dump_ext }'"
|
|
75
|
+
|
|
76
|
+
pipeline.run
|
|
77
|
+
if pipeline.success?
|
|
78
|
+
Logger.message "#{ database_name } Complete!"
|
|
79
|
+
else
|
|
80
|
+
raise Errors::Database::PipelineError,
|
|
81
|
+
"#{ database_name } Dump Failed!\n" +
|
|
82
|
+
pipeline.error_messages
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
##
|
|
89
|
+
# Builds the full mysqldump string based on all attributes
|
|
90
|
+
def mysqldump
|
|
91
|
+
"#{ mysqldump_utility } #{ credential_options } #{ connectivity_options } " +
|
|
92
|
+
"#{ user_options } #{ db_name } #{ tables_to_dump } #{ tables_to_skip }"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# Returns the filename to use for dumping the database(s)
|
|
97
|
+
def dump_filename
|
|
98
|
+
dump_all? ? 'all-databases' : name
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# Builds the credentials MySQL syntax to authenticate the user
|
|
103
|
+
# to perform the database dumping process
|
|
104
|
+
def credential_options
|
|
105
|
+
%w[username password].map do |option|
|
|
106
|
+
next if send(option).to_s.empty?
|
|
107
|
+
"--#{option}='#{send(option)}'".gsub('--username', '--user')
|
|
108
|
+
end.compact.join(' ')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
##
|
|
112
|
+
# Builds the MySQL connectivity options syntax to connect the user
|
|
113
|
+
# to perform the database dumping process
|
|
114
|
+
def connectivity_options
|
|
115
|
+
%w[host port socket].map do |option|
|
|
116
|
+
next if send(option).to_s.empty?
|
|
117
|
+
"--#{option}='#{send(option)}'"
|
|
118
|
+
end.compact.join(' ')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# Builds a MySQL compatible string for the additional options
|
|
123
|
+
# specified by the user
|
|
124
|
+
def user_options
|
|
125
|
+
additional_options.join(' ')
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
##
|
|
129
|
+
# Returns the database name to use in the mysqldump command.
|
|
130
|
+
# When dumping all databases, the database name is replaced
|
|
131
|
+
# with the command option to dump all databases.
|
|
132
|
+
def db_name
|
|
133
|
+
dump_all? ? '--all-databases' : name
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# Builds the MySQL syntax for specifying which tables to dump
|
|
138
|
+
# during the dumping of the database
|
|
139
|
+
def tables_to_dump
|
|
140
|
+
only_tables.join(' ') unless dump_all?
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
##
|
|
144
|
+
# Builds the MySQL syntax for specifying which tables to skip
|
|
145
|
+
# during the dumping of the database
|
|
146
|
+
def tables_to_skip
|
|
147
|
+
skip_tables.map do |table|
|
|
148
|
+
table = (dump_all? || table['.']) ? table : "#{ name }.#{ table }"
|
|
149
|
+
"--ignore-table='#{ table }'"
|
|
150
|
+
end.join(' ')
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
##
|
|
154
|
+
# Return true if we're dumping all databases.
|
|
155
|
+
# `name` will be set to :all if it is not set,
|
|
156
|
+
# so this will be true by default
|
|
157
|
+
def dump_all?
|
|
158
|
+
name == :all
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Database
|
|
5
|
+
class PostgreSQL < Base
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Name of the database that needs to get dumped
|
|
9
|
+
attr_accessor :name
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Credentials for the specified database
|
|
13
|
+
attr_accessor :username, :password
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# Connectivity options
|
|
17
|
+
attr_accessor :host, :port, :socket
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Tables to skip while dumping the database
|
|
21
|
+
attr_accessor :skip_tables
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Tables to dump, tables that aren't specified won't get dumped
|
|
25
|
+
attr_accessor :only_tables
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Additional "pg_dump" options
|
|
29
|
+
attr_accessor :additional_options
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Path to pg_dump utility (optional)
|
|
33
|
+
attr_accessor :pg_dump_utility
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Creates a new instance of the PostgreSQL adapter object
|
|
37
|
+
# Sets the PGPASSWORD environment variable to the password
|
|
38
|
+
# so it doesn't prompt and hang in the process
|
|
39
|
+
def initialize(model, &block)
|
|
40
|
+
super(model)
|
|
41
|
+
|
|
42
|
+
@skip_tables ||= Array.new
|
|
43
|
+
@only_tables ||= Array.new
|
|
44
|
+
@additional_options ||= Array.new
|
|
45
|
+
|
|
46
|
+
instance_eval(&block) if block_given?
|
|
47
|
+
|
|
48
|
+
if @utility_path
|
|
49
|
+
Logger.warn "[DEPRECATED] " +
|
|
50
|
+
"Database::PostgreSQL#utility_path has been deprecated.\n" +
|
|
51
|
+
" Use Database::PostgreSQL#pg_dump_utility instead."
|
|
52
|
+
@pg_dump_utility ||= @utility_path
|
|
53
|
+
end
|
|
54
|
+
@pg_dump_utility ||= utility(:pg_dump)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# Performs the pgdump command and outputs the
|
|
59
|
+
# data to the specified path based on the 'trigger'
|
|
60
|
+
def perform!
|
|
61
|
+
super
|
|
62
|
+
|
|
63
|
+
pipeline = Pipeline.new
|
|
64
|
+
dump_ext = 'sql'
|
|
65
|
+
|
|
66
|
+
pipeline << pgdump
|
|
67
|
+
if @model.compressor
|
|
68
|
+
@model.compressor.compress_with do |command, ext|
|
|
69
|
+
pipeline << command
|
|
70
|
+
dump_ext << ext
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
pipeline << "cat > '#{ File.join(@dump_path, name) }.#{ dump_ext }'"
|
|
74
|
+
|
|
75
|
+
pipeline.run
|
|
76
|
+
if pipeline.success?
|
|
77
|
+
Logger.message "#{ database_name } Complete!"
|
|
78
|
+
else
|
|
79
|
+
raise Errors::Database::PipelineError,
|
|
80
|
+
"#{ database_name } Dump Failed!\n" +
|
|
81
|
+
pipeline.error_messages
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# Builds the full pgdump string based on all attributes
|
|
87
|
+
def pgdump
|
|
88
|
+
"#{password_options}" +
|
|
89
|
+
"#{ pg_dump_utility } #{ username_options } #{ connectivity_options } " +
|
|
90
|
+
"#{ user_options } #{ tables_to_dump } #{ tables_to_skip } #{ name }"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
##
|
|
94
|
+
# Builds the password syntax PostgreSQL uses to authenticate the user
|
|
95
|
+
# to perform database dumping
|
|
96
|
+
def password_options
|
|
97
|
+
password.to_s.empty? ? '' : "PGPASSWORD='#{password}' "
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# Builds the credentials PostgreSQL syntax to authenticate the user
|
|
102
|
+
# to perform the database dumping process
|
|
103
|
+
def username_options
|
|
104
|
+
username.to_s.empty? ? '' : "--username='#{username}'"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# Builds the PostgreSQL connectivity options syntax to connect the user
|
|
109
|
+
# to perform the database dumping process, socket gets gsub'd to host since
|
|
110
|
+
# that's the option PostgreSQL takes for socket connections as well. In case
|
|
111
|
+
# both the host and the socket are specified, the socket will take priority over the host
|
|
112
|
+
def connectivity_options
|
|
113
|
+
%w[host port socket].map do |option|
|
|
114
|
+
next if send(option).to_s.empty?
|
|
115
|
+
"--#{option}='#{send(option)}'".gsub('--socket=', '--host=')
|
|
116
|
+
end.compact.join(' ')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
##
|
|
120
|
+
# Builds a PostgreSQL compatible string for the additional options
|
|
121
|
+
# specified by the user
|
|
122
|
+
def user_options
|
|
123
|
+
additional_options.join(' ')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
##
|
|
127
|
+
# Builds the PostgreSQL syntax for specifying which tables to dump
|
|
128
|
+
# during the dumping of the database
|
|
129
|
+
def tables_to_dump
|
|
130
|
+
only_tables.map do |table|
|
|
131
|
+
"--table='#{table}'"
|
|
132
|
+
end.join(' ')
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# Builds the PostgreSQL syntax for specifying which tables to skip
|
|
137
|
+
# during the dumping of the database
|
|
138
|
+
def tables_to_skip
|
|
139
|
+
skip_tables.map do |table|
|
|
140
|
+
"--exclude-table='#{table}'"
|
|
141
|
+
end.join(' ')
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Database
|
|
5
|
+
class Redis < Base
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Name of and path to the database that needs to get dumped
|
|
9
|
+
attr_accessor :name, :path
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Credentials for the specified database
|
|
13
|
+
attr_accessor :password
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# Determines whether Backup should invoke the SAVE command through
|
|
17
|
+
# the 'redis-cli' utility to persist the most recent data before
|
|
18
|
+
# copying over the dump file
|
|
19
|
+
attr_accessor :invoke_save
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# Connectivity options
|
|
23
|
+
attr_accessor :host, :port, :socket
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Additional "redis-cli" options
|
|
27
|
+
attr_accessor :additional_options
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Path to the redis-cli utility (optional)
|
|
31
|
+
attr_accessor :redis_cli_utility
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Creates a new instance of the Redis database object
|
|
35
|
+
def initialize(model, &block)
|
|
36
|
+
super(model)
|
|
37
|
+
|
|
38
|
+
@additional_options ||= Array.new
|
|
39
|
+
|
|
40
|
+
instance_eval(&block) if block_given?
|
|
41
|
+
|
|
42
|
+
@name ||= 'dump'
|
|
43
|
+
|
|
44
|
+
if @utility_path
|
|
45
|
+
Logger.warn "[DEPRECATED] " +
|
|
46
|
+
"Database::Redis#utility_path has been deprecated.\n" +
|
|
47
|
+
" Use Database::Redis#redis_cli_utility instead."
|
|
48
|
+
@redis_cli_utility ||= @utility_path
|
|
49
|
+
end
|
|
50
|
+
@redis_cli_utility ||= utility('redis-cli')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
##
|
|
54
|
+
# Performs the Redis backup by using the 'cp' unix utility
|
|
55
|
+
# to copy the persisted Redis dump file to the Backup archive.
|
|
56
|
+
# Additionally, when 'invoke_save' is set to true, it'll tell
|
|
57
|
+
# the Redis server to persist the current state to the dump file
|
|
58
|
+
# before copying the dump to get the most recent updates in to the backup
|
|
59
|
+
def perform!
|
|
60
|
+
super
|
|
61
|
+
|
|
62
|
+
invoke_save! if invoke_save
|
|
63
|
+
copy!
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
# Tells Redis to persist the current state of the
|
|
70
|
+
# in-memory database to the persisted dump file
|
|
71
|
+
def invoke_save!
|
|
72
|
+
response = run("#{ redis_cli_utility } #{ credential_options } " +
|
|
73
|
+
"#{ connectivity_options } #{ user_options } SAVE")
|
|
74
|
+
unless response =~ /OK/
|
|
75
|
+
raise Errors::Database::Redis::CommandError, <<-EOS
|
|
76
|
+
Could not invoke the Redis SAVE command.
|
|
77
|
+
The #{ database } file might not contain the most recent data.
|
|
78
|
+
Please check if the server is running, the credentials (if any) are correct,
|
|
79
|
+
and the host/port/socket are correct.
|
|
80
|
+
|
|
81
|
+
Redis CLI response: #{ response }
|
|
82
|
+
EOS
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
# Performs the copy command to copy over the Redis dump file to the Backup archive
|
|
88
|
+
def copy!
|
|
89
|
+
src_path = File.join(path, database)
|
|
90
|
+
unless File.exist?(src_path)
|
|
91
|
+
raise Errors::Database::Redis::NotFoundError, <<-EOS
|
|
92
|
+
Redis database dump not found
|
|
93
|
+
File path was #{ src_path }
|
|
94
|
+
EOS
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
dst_path = File.join(@dump_path, database)
|
|
98
|
+
if @model.compressor
|
|
99
|
+
@model.compressor.compress_with do |command, ext|
|
|
100
|
+
run("#{ command } -c #{ src_path } > #{ dst_path + ext }")
|
|
101
|
+
end
|
|
102
|
+
else
|
|
103
|
+
FileUtils.cp(src_path, dst_path)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# Returns the Redis database file name
|
|
109
|
+
def database
|
|
110
|
+
"#{ name }.rdb"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
##
|
|
114
|
+
# Builds the Redis credentials syntax to authenticate the user
|
|
115
|
+
# to perform the database dumping process
|
|
116
|
+
def credential_options
|
|
117
|
+
password.to_s.empty? ? '' : "-a '#{password}'"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
##
|
|
121
|
+
# Builds the Redis connectivity options syntax to connect the user
|
|
122
|
+
# to perform the database dumping process
|
|
123
|
+
def connectivity_options
|
|
124
|
+
%w[host port socket].map do |option|
|
|
125
|
+
next if send(option).to_s.empty?
|
|
126
|
+
"-#{option[0,1]} '#{send(option)}'"
|
|
127
|
+
end.compact.join(' ')
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
# Builds a Redis compatible string for the
|
|
132
|
+
# additional options specified by the user
|
|
133
|
+
def user_options
|
|
134
|
+
@additional_options.join(' ')
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Database
|
|
5
|
+
class Riak < Base
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Name is the name of the backup
|
|
9
|
+
attr_accessor :name
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Node is the node from which to perform the backup.
|
|
13
|
+
attr_accessor :node
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# Cookie is the Erlang cookie/shared secret used to connect to the node.
|
|
17
|
+
attr_accessor :cookie
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Path to riak-admin utility (optional)
|
|
21
|
+
attr_accessor :riak_admin_utility
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Creates a new instance of the Riak adapter object
|
|
25
|
+
def initialize(model, &block)
|
|
26
|
+
super(model)
|
|
27
|
+
|
|
28
|
+
instance_eval(&block) if block_given?
|
|
29
|
+
|
|
30
|
+
if @utility_path
|
|
31
|
+
Logger.warn "[DEPRECATED] " +
|
|
32
|
+
"Database::Riak#utility_path has been deprecated.\n" +
|
|
33
|
+
" Use Database::Riak#riak_admin_utility instead."
|
|
34
|
+
@riak_admin_utility ||= @utility_path
|
|
35
|
+
end
|
|
36
|
+
@riak_admin_utility ||= utility('riak-admin')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Performs the riak-admin command and outputs the
|
|
41
|
+
# data to the specified path based on the 'trigger'
|
|
42
|
+
def perform!
|
|
43
|
+
super
|
|
44
|
+
# have to make riak the owner since the riak-admin tool runs
|
|
45
|
+
# as the riak user in a default setup.
|
|
46
|
+
FileUtils.chown_R('riak', 'riak', @dump_path)
|
|
47
|
+
|
|
48
|
+
backup_file = File.join(@dump_path, name)
|
|
49
|
+
run("#{ riakadmin } #{ backup_file } node")
|
|
50
|
+
|
|
51
|
+
if @model.compressor
|
|
52
|
+
@model.compressor.compress_with do |command, ext|
|
|
53
|
+
run("#{ command } -c #{ backup_file } > #{ backup_file + ext }")
|
|
54
|
+
FileUtils.rm_f(backup_file)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# Builds the full riak-admin string based on all attributes
|
|
63
|
+
def riakadmin
|
|
64
|
+
"#{ riak_admin_utility } backup #{ node } #{ cookie }"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|