backup-agoddard 3.0.27
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 +8 -0
- data/.travis.yml +10 -0
- data/Gemfile +28 -0
- data/Guardfile +23 -0
- data/LICENSE.md +24 -0
- data/README.md +478 -0
- data/backup.gemspec +32 -0
- data/bin/backup +11 -0
- data/lib/backup.rb +133 -0
- data/lib/backup/archive.rb +117 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/cleaner.rb +121 -0
- data/lib/backup/cli/helpers.rb +93 -0
- data/lib/backup/cli/utility.rb +255 -0
- data/lib/backup/compressor/base.rb +35 -0
- data/lib/backup/compressor/bzip2.rb +50 -0
- data/lib/backup/compressor/custom.rb +53 -0
- data/lib/backup/compressor/gzip.rb +50 -0
- data/lib/backup/compressor/lzma.rb +52 -0
- data/lib/backup/compressor/pbzip2.rb +59 -0
- data/lib/backup/config.rb +174 -0
- data/lib/backup/configuration.rb +33 -0
- data/lib/backup/configuration/helpers.rb +130 -0
- data/lib/backup/configuration/store.rb +24 -0
- data/lib/backup/database/base.rb +53 -0
- data/lib/backup/database/mongodb.rb +230 -0
- data/lib/backup/database/mysql.rb +160 -0
- data/lib/backup/database/postgresql.rb +144 -0
- data/lib/backup/database/redis.rb +136 -0
- data/lib/backup/database/riak.rb +67 -0
- data/lib/backup/dependency.rb +108 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +760 -0
- data/lib/backup/encryptor/open_ssl.rb +72 -0
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/hooks.rb +68 -0
- data/lib/backup/logger.rb +152 -0
- data/lib/backup/model.rb +409 -0
- data/lib/backup/notifier/base.rb +81 -0
- data/lib/backup/notifier/campfire.rb +155 -0
- data/lib/backup/notifier/hipchat.rb +93 -0
- data/lib/backup/notifier/mail.rb +206 -0
- data/lib/backup/notifier/prowl.rb +65 -0
- data/lib/backup/notifier/pushover.rb +88 -0
- data/lib/backup/notifier/twitter.rb +70 -0
- data/lib/backup/package.rb +47 -0
- data/lib/backup/packager.rb +100 -0
- data/lib/backup/pipeline.rb +110 -0
- data/lib/backup/splitter.rb +75 -0
- data/lib/backup/storage/base.rb +99 -0
- data/lib/backup/storage/cloudfiles.rb +87 -0
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +178 -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 +46 -0
- data/lib/backup/syncer/cloud/base.rb +247 -0
- data/lib/backup/syncer/cloud/cloud_files.rb +78 -0
- data/lib/backup/syncer/cloud/s3.rb +68 -0
- data/lib/backup/syncer/rsync/base.rb +49 -0
- data/lib/backup/syncer/rsync/local.rb +55 -0
- data/lib/backup/syncer/rsync/pull.rb +36 -0
- data/lib/backup/syncer/rsync/push.rb +116 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +43 -0
- data/spec-live/.gitignore +6 -0
- data/spec-live/README +7 -0
- data/spec-live/backups/config.rb +83 -0
- data/spec-live/backups/config.yml.template +46 -0
- data/spec-live/backups/models.rb +184 -0
- data/spec-live/compressor/custom_spec.rb +30 -0
- data/spec-live/compressor/gzip_spec.rb +30 -0
- data/spec-live/encryptor/gpg_keys.rb +239 -0
- data/spec-live/encryptor/gpg_spec.rb +287 -0
- data/spec-live/notifier/mail_spec.rb +121 -0
- data/spec-live/spec_helper.rb +151 -0
- data/spec-live/storage/dropbox_spec.rb +151 -0
- data/spec-live/storage/local_spec.rb +83 -0
- data/spec-live/storage/scp_spec.rb +193 -0
- data/spec-live/syncer/cloud/s3_spec.rb +124 -0
- data/spec/archive_spec.rb +335 -0
- data/spec/cleaner_spec.rb +312 -0
- data/spec/cli/helpers_spec.rb +301 -0
- data/spec/cli/utility_spec.rb +411 -0
- data/spec/compressor/base_spec.rb +52 -0
- data/spec/compressor/bzip2_spec.rb +217 -0
- data/spec/compressor/custom_spec.rb +106 -0
- data/spec/compressor/gzip_spec.rb +217 -0
- data/spec/compressor/lzma_spec.rb +123 -0
- data/spec/compressor/pbzip2_spec.rb +165 -0
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/helpers_spec.rb +247 -0
- data/spec/configuration/store_spec.rb +39 -0
- data/spec/configuration_spec.rb +62 -0
- data/spec/database/base_spec.rb +63 -0
- data/spec/database/mongodb_spec.rb +510 -0
- data/spec/database/mysql_spec.rb +411 -0
- data/spec/database/postgresql_spec.rb +353 -0
- data/spec/database/redis_spec.rb +334 -0
- data/spec/database/riak_spec.rb +176 -0
- data/spec/dependency_spec.rb +51 -0
- data/spec/encryptor/base_spec.rb +40 -0
- data/spec/encryptor/gpg_spec.rb +909 -0
- data/spec/encryptor/open_ssl_spec.rb +148 -0
- data/spec/errors_spec.rb +306 -0
- data/spec/hooks_spec.rb +35 -0
- data/spec/logger_spec.rb +367 -0
- data/spec/model_spec.rb +694 -0
- data/spec/notifier/base_spec.rb +104 -0
- data/spec/notifier/campfire_spec.rb +217 -0
- data/spec/notifier/hipchat_spec.rb +211 -0
- data/spec/notifier/mail_spec.rb +316 -0
- data/spec/notifier/prowl_spec.rb +138 -0
- data/spec/notifier/pushover_spec.rb +123 -0
- data/spec/notifier/twitter_spec.rb +153 -0
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +213 -0
- data/spec/pipeline_spec.rb +259 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/splitter_spec.rb +120 -0
- data/spec/storage/base_spec.rb +166 -0
- data/spec/storage/cloudfiles_spec.rb +254 -0
- data/spec/storage/cycler_spec.rb +247 -0
- data/spec/storage/dropbox_spec.rb +480 -0
- data/spec/storage/ftp_spec.rb +271 -0
- data/spec/storage/local_spec.rb +259 -0
- data/spec/storage/ninefold_spec.rb +343 -0
- data/spec/storage/rsync_spec.rb +362 -0
- data/spec/storage/s3_spec.rb +245 -0
- data/spec/storage/scp_spec.rb +233 -0
- data/spec/storage/sftp_spec.rb +244 -0
- data/spec/syncer/base_spec.rb +109 -0
- data/spec/syncer/cloud/base_spec.rb +515 -0
- data/spec/syncer/cloud/cloud_files_spec.rb +181 -0
- data/spec/syncer/cloud/s3_spec.rb +174 -0
- data/spec/syncer/rsync/base_spec.rb +98 -0
- data/spec/syncer/rsync/local_spec.rb +149 -0
- data/spec/syncer/rsync/pull_spec.rb +98 -0
- data/spec/syncer/rsync/push_spec.rb +333 -0
- data/spec/version_spec.rb +21 -0
- data/templates/cli/utility/archive +25 -0
- data/templates/cli/utility/compressor/bzip2 +4 -0
- data/templates/cli/utility/compressor/custom +11 -0
- data/templates/cli/utility/compressor/gzip +4 -0
- data/templates/cli/utility/compressor/lzma +10 -0
- data/templates/cli/utility/compressor/pbzip2 +10 -0
- data/templates/cli/utility/config +32 -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 +27 -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/prowl +11 -0
- data/templates/cli/utility/notifier/pushover +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 +46 -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 +43 -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 +277 -0
|
@@ -0,0 +1,144 @@
|
|
|
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
|
+
attr_deprecate :utility_path, :version => '3.0.21',
|
|
36
|
+
:message => 'Use PostgreSQL#pg_dump_utility instead.',
|
|
37
|
+
:action => lambda {|klass, val| klass.pg_dump_utility = val }
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Creates a new instance of the PostgreSQL adapter object
|
|
41
|
+
# Sets the PGPASSWORD environment variable to the password
|
|
42
|
+
# so it doesn't prompt and hang in the process
|
|
43
|
+
def initialize(model, &block)
|
|
44
|
+
super(model)
|
|
45
|
+
|
|
46
|
+
@skip_tables ||= Array.new
|
|
47
|
+
@only_tables ||= Array.new
|
|
48
|
+
@additional_options ||= Array.new
|
|
49
|
+
|
|
50
|
+
instance_eval(&block) if block_given?
|
|
51
|
+
|
|
52
|
+
@pg_dump_utility ||= utility(:pg_dump)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Performs the pgdump command and outputs the
|
|
57
|
+
# data to the specified path based on the 'trigger'
|
|
58
|
+
def perform!
|
|
59
|
+
super
|
|
60
|
+
|
|
61
|
+
pipeline = Pipeline.new
|
|
62
|
+
dump_ext = 'sql'
|
|
63
|
+
|
|
64
|
+
pipeline << pgdump
|
|
65
|
+
if @model.compressor
|
|
66
|
+
@model.compressor.compress_with do |command, ext|
|
|
67
|
+
pipeline << command
|
|
68
|
+
dump_ext << ext
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
pipeline << "cat > '#{ File.join(@dump_path, name) }.#{ dump_ext }'"
|
|
72
|
+
|
|
73
|
+
pipeline.run
|
|
74
|
+
if pipeline.success?
|
|
75
|
+
Logger.message "#{ database_name } Complete!"
|
|
76
|
+
else
|
|
77
|
+
raise Errors::Database::PipelineError,
|
|
78
|
+
"#{ database_name } Dump Failed!\n" +
|
|
79
|
+
pipeline.error_messages
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Builds the full pgdump string based on all attributes
|
|
85
|
+
def pgdump
|
|
86
|
+
"#{password_options}" +
|
|
87
|
+
"#{ pg_dump_utility } #{ username_options } #{ connectivity_options } " +
|
|
88
|
+
"#{ user_options } #{ tables_to_dump } #{ tables_to_skip } #{ name }"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
# Builds the password syntax PostgreSQL uses to authenticate the user
|
|
93
|
+
# to perform database dumping
|
|
94
|
+
def password_options
|
|
95
|
+
password.to_s.empty? ? '' : "PGPASSWORD='#{password}' "
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
##
|
|
99
|
+
# Builds the credentials PostgreSQL syntax to authenticate the user
|
|
100
|
+
# to perform the database dumping process
|
|
101
|
+
def username_options
|
|
102
|
+
username.to_s.empty? ? '' : "--username='#{username}'"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
##
|
|
106
|
+
# Builds the PostgreSQL connectivity options syntax to connect the user
|
|
107
|
+
# to perform the database dumping process, socket gets gsub'd to host since
|
|
108
|
+
# that's the option PostgreSQL takes for socket connections as well. In case
|
|
109
|
+
# both the host and the socket are specified, the socket will take priority over the host
|
|
110
|
+
def connectivity_options
|
|
111
|
+
%w[host port socket].map do |option|
|
|
112
|
+
next if send(option).to_s.empty?
|
|
113
|
+
"--#{option}='#{send(option)}'".gsub('--socket=', '--host=')
|
|
114
|
+
end.compact.join(' ')
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
##
|
|
118
|
+
# Builds a PostgreSQL compatible string for the additional options
|
|
119
|
+
# specified by the user
|
|
120
|
+
def user_options
|
|
121
|
+
additional_options.join(' ')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
##
|
|
125
|
+
# Builds the PostgreSQL syntax for specifying which tables to dump
|
|
126
|
+
# during the dumping of the database
|
|
127
|
+
def tables_to_dump
|
|
128
|
+
only_tables.map do |table|
|
|
129
|
+
"--table='#{table}'"
|
|
130
|
+
end.join(' ')
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
##
|
|
134
|
+
# Builds the PostgreSQL syntax for specifying which tables to skip
|
|
135
|
+
# during the dumping of the database
|
|
136
|
+
def tables_to_skip
|
|
137
|
+
skip_tables.map do |table|
|
|
138
|
+
"--exclude-table='#{table}'"
|
|
139
|
+
end.join(' ')
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
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
|
+
# Connectivity options
|
|
17
|
+
attr_accessor :host, :port, :socket
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Determines whether Backup should invoke the SAVE command through
|
|
21
|
+
# the 'redis-cli' utility to persist the most recent data before
|
|
22
|
+
# copying over the dump file
|
|
23
|
+
attr_accessor :invoke_save
|
|
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
|
+
attr_deprecate :utility_path, :version => '3.0.21',
|
|
34
|
+
:message => 'Use Redis#redis_cli_utility instead.',
|
|
35
|
+
:action => lambda {|klass, val| klass.redis_cli_utility = val }
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Creates a new instance of the Redis database object
|
|
39
|
+
def initialize(model, &block)
|
|
40
|
+
super(model)
|
|
41
|
+
|
|
42
|
+
@additional_options ||= Array.new
|
|
43
|
+
|
|
44
|
+
instance_eval(&block) if block_given?
|
|
45
|
+
|
|
46
|
+
@name ||= 'dump'
|
|
47
|
+
@redis_cli_utility ||= utility('redis-cli')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Performs the Redis backup by using the 'cp' unix utility
|
|
52
|
+
# to copy the persisted Redis dump file to the Backup archive.
|
|
53
|
+
# Additionally, when 'invoke_save' is set to true, it'll tell
|
|
54
|
+
# the Redis server to persist the current state to the dump file
|
|
55
|
+
# before copying the dump to get the most recent updates in to the backup
|
|
56
|
+
def perform!
|
|
57
|
+
super
|
|
58
|
+
|
|
59
|
+
invoke_save! if invoke_save
|
|
60
|
+
copy!
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Tells Redis to persist the current state of the
|
|
67
|
+
# in-memory database to the persisted dump file
|
|
68
|
+
def invoke_save!
|
|
69
|
+
response = run("#{ redis_cli_utility } #{ credential_options } " +
|
|
70
|
+
"#{ connectivity_options } #{ user_options } SAVE")
|
|
71
|
+
unless response =~ /OK/
|
|
72
|
+
raise Errors::Database::Redis::CommandError, <<-EOS
|
|
73
|
+
Could not invoke the Redis SAVE command.
|
|
74
|
+
The #{ database } file might not contain the most recent data.
|
|
75
|
+
Please check if the server is running, the credentials (if any) are correct,
|
|
76
|
+
and the host/port/socket are correct.
|
|
77
|
+
|
|
78
|
+
Redis CLI response: #{ response }
|
|
79
|
+
EOS
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Performs the copy command to copy over the Redis dump file to the Backup archive
|
|
85
|
+
def copy!
|
|
86
|
+
src_path = File.join(path, database)
|
|
87
|
+
unless File.exist?(src_path)
|
|
88
|
+
raise Errors::Database::Redis::NotFoundError, <<-EOS
|
|
89
|
+
Redis database dump not found
|
|
90
|
+
File path was #{ src_path }
|
|
91
|
+
EOS
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
dst_path = File.join(@dump_path, database)
|
|
95
|
+
if @model.compressor
|
|
96
|
+
@model.compressor.compress_with do |command, ext|
|
|
97
|
+
run("#{ command } -c #{ src_path } > #{ dst_path + ext }")
|
|
98
|
+
end
|
|
99
|
+
else
|
|
100
|
+
FileUtils.cp(src_path, dst_path)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
##
|
|
105
|
+
# Returns the Redis database file name
|
|
106
|
+
def database
|
|
107
|
+
"#{ name }.rdb"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
##
|
|
111
|
+
# Builds the Redis credentials syntax to authenticate the user
|
|
112
|
+
# to perform the database dumping process
|
|
113
|
+
def credential_options
|
|
114
|
+
password.to_s.empty? ? '' : "-a '#{password}'"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
##
|
|
118
|
+
# Builds the Redis connectivity options syntax to connect the user
|
|
119
|
+
# to perform the database dumping process
|
|
120
|
+
def connectivity_options
|
|
121
|
+
%w[host port socket].map do |option|
|
|
122
|
+
next if send(option).to_s.empty?
|
|
123
|
+
"-#{option[0,1]} '#{send(option)}'"
|
|
124
|
+
end.compact.join(' ')
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
##
|
|
128
|
+
# Builds a Redis compatible string for the
|
|
129
|
+
# additional options specified by the user
|
|
130
|
+
def user_options
|
|
131
|
+
@additional_options.join(' ')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
attr_deprecate :utility_path, :version => '3.0.21',
|
|
24
|
+
:message => 'Use Riak#riak_admin_utility instead.',
|
|
25
|
+
:action => lambda {|klass, val| klass.riak_admin_utility = val }
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Creates a new instance of the Riak adapter object
|
|
29
|
+
def initialize(model, &block)
|
|
30
|
+
super(model)
|
|
31
|
+
|
|
32
|
+
instance_eval(&block) if block_given?
|
|
33
|
+
|
|
34
|
+
@riak_admin_utility ||= utility('riak-admin')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Performs the riak-admin command and outputs the
|
|
39
|
+
# data to the specified path based on the 'trigger'
|
|
40
|
+
def perform!
|
|
41
|
+
super
|
|
42
|
+
# have to make riak the owner since the riak-admin tool runs
|
|
43
|
+
# as the riak user in a default setup.
|
|
44
|
+
FileUtils.chown_R('riak', 'riak', @dump_path)
|
|
45
|
+
|
|
46
|
+
backup_file = File.join(@dump_path, name)
|
|
47
|
+
run("#{ riakadmin } #{ backup_file } node")
|
|
48
|
+
|
|
49
|
+
if @model.compressor
|
|
50
|
+
@model.compressor.compress_with do |command, ext|
|
|
51
|
+
run("#{ command } -c #{ backup_file } > #{ backup_file + ext }")
|
|
52
|
+
FileUtils.rm_f(backup_file)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Builds the full riak-admin string based on all attributes
|
|
61
|
+
def riakadmin
|
|
62
|
+
"#{ riak_admin_utility } backup #{ node } #{ cookie }"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# A little self-contained gem manager for Backup.
|
|
7
|
+
# Rather than specifying hard dependencies in the gemspec, forcing users
|
|
8
|
+
# to install gems they do not want/need, Backup will notify them when a gem
|
|
9
|
+
# has not been installed, or when the gem's version is incorrect, and provide the
|
|
10
|
+
# command to install the gem. These dependencies are dynamically loaded in the Gemfile
|
|
11
|
+
class Dependency
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Returns a hash of dependencies that Backup requires
|
|
15
|
+
# in order to run every available feature
|
|
16
|
+
def self.all
|
|
17
|
+
{
|
|
18
|
+
'fog' => {
|
|
19
|
+
:require => 'fog',
|
|
20
|
+
:version => '~> 1.4.0',
|
|
21
|
+
:for => 'Amazon S3, Rackspace Cloud Files (S3, CloudFiles Storages)'
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
'dropbox-sdk' => {
|
|
25
|
+
:require => 'dropbox_sdk',
|
|
26
|
+
:version => '~> 1.2.0',
|
|
27
|
+
:for => 'Dropbox Web Service (Dropbox Storage)'
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
'net-sftp' => {
|
|
31
|
+
:require => 'net/sftp',
|
|
32
|
+
:version => '~> 2.0.5',
|
|
33
|
+
:for => 'SFTP Protocol (SFTP Storage)'
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
'net-scp' => {
|
|
37
|
+
:require => 'net/scp',
|
|
38
|
+
:version => '~> 1.0.4',
|
|
39
|
+
:for => 'SCP Protocol (SCP Storage)'
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
'net-ssh' => {
|
|
43
|
+
:require => 'net/ssh',
|
|
44
|
+
:version => '~> 2.3.0',
|
|
45
|
+
:for => 'SSH Protocol (SSH Storage)'
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
'mail' => {
|
|
49
|
+
:require => 'mail',
|
|
50
|
+
:version => '~> 2.4.0',
|
|
51
|
+
:for => 'Sending Emails (Mail Notifier)'
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
'twitter' => {
|
|
55
|
+
:require => 'twitter',
|
|
56
|
+
:version => '>= 1.7.1',
|
|
57
|
+
:for => 'Sending Twitter Updates (Twitter Notifier)'
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
'httparty' => {
|
|
61
|
+
:require => 'httparty',
|
|
62
|
+
:version => '~> 0.8.1',
|
|
63
|
+
:for => 'Sending Http Updates'
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
'prowler' => {
|
|
67
|
+
:require => 'prowler',
|
|
68
|
+
:version => '>= 1.3.1',
|
|
69
|
+
:for => 'Sending iOS push notifications (Prowl Notifier)'
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
'hipchat' => {
|
|
73
|
+
:require => 'hipchat',
|
|
74
|
+
:version => '~> 0.4.1',
|
|
75
|
+
:for => 'Sending notifications to Hipchat'
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
'parallel' => {
|
|
79
|
+
:require => 'parallel',
|
|
80
|
+
:version => '~> 0.5.12',
|
|
81
|
+
:for => 'Adding concurrency to Cloud-based syncers.'
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
# Attempts to load the specified gem (by name and version).
|
|
88
|
+
# If the gem with the correct version cannot be found, it'll display a message
|
|
89
|
+
# to the user with instructions on how to install the required gem
|
|
90
|
+
def self.load(name)
|
|
91
|
+
begin
|
|
92
|
+
gem(name, all[name][:version])
|
|
93
|
+
require(all[name][:require])
|
|
94
|
+
rescue LoadError
|
|
95
|
+
Logger.error Errors::Dependency::LoadError.new(<<-EOS)
|
|
96
|
+
Dependency missing
|
|
97
|
+
Dependency required for:
|
|
98
|
+
#{all[name][:for]}
|
|
99
|
+
To install the gem, issue the following command:
|
|
100
|
+
> gem install #{name} -v '#{all[name][:version]}'
|
|
101
|
+
Please try again after installing the missing dependency.
|
|
102
|
+
EOS
|
|
103
|
+
exit 1
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
end
|