backup 3.0.20 → 3.0.21
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/Gemfile +1 -5
- data/Gemfile.lock +46 -50
- data/README.md +54 -27
- data/lib/backup.rb +16 -39
- data/lib/backup/archive.rb +42 -18
- data/lib/backup/cleaner.rb +110 -25
- data/lib/backup/cli/helpers.rb +17 -32
- data/lib/backup/cli/utility.rb +46 -107
- data/lib/backup/compressor/base.rb +14 -2
- data/lib/backup/compressor/bzip2.rb +10 -24
- data/lib/backup/compressor/gzip.rb +10 -24
- data/lib/backup/compressor/lzma.rb +10 -23
- data/lib/backup/compressor/pbzip2.rb +12 -32
- data/lib/backup/config.rb +171 -0
- data/lib/backup/configuration/compressor/base.rb +1 -2
- data/lib/backup/configuration/compressor/pbzip2.rb +4 -4
- data/lib/backup/configuration/database/base.rb +2 -1
- data/lib/backup/configuration/database/mongodb.rb +8 -0
- data/lib/backup/configuration/database/mysql.rb +4 -0
- data/lib/backup/configuration/database/postgresql.rb +4 -0
- data/lib/backup/configuration/database/redis.rb +4 -0
- data/lib/backup/configuration/database/riak.rb +5 -1
- data/lib/backup/configuration/encryptor/base.rb +1 -2
- data/lib/backup/configuration/encryptor/open_ssl.rb +1 -1
- data/lib/backup/configuration/helpers.rb +7 -2
- data/lib/backup/configuration/notifier/base.rb +4 -28
- data/lib/backup/configuration/storage/base.rb +1 -1
- data/lib/backup/configuration/storage/dropbox.rb +14 -4
- data/lib/backup/configuration/syncer/base.rb +10 -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 +0 -4
- data/lib/backup/database/base.rb +25 -7
- data/lib/backup/database/mongodb.rb +112 -75
- data/lib/backup/database/mysql.rb +54 -29
- data/lib/backup/database/postgresql.rb +60 -42
- data/lib/backup/database/redis.rb +61 -39
- data/lib/backup/database/riak.rb +35 -11
- data/lib/backup/dependency.rb +4 -5
- data/lib/backup/encryptor/base.rb +13 -1
- data/lib/backup/encryptor/gpg.rb +39 -39
- data/lib/backup/encryptor/open_ssl.rb +28 -38
- data/lib/backup/logger.rb +20 -11
- data/lib/backup/model.rb +206 -163
- data/lib/backup/notifier/base.rb +27 -25
- data/lib/backup/notifier/campfire.rb +7 -13
- data/lib/backup/notifier/hipchat.rb +28 -28
- data/lib/backup/notifier/mail.rb +24 -26
- data/lib/backup/notifier/presently.rb +10 -18
- data/lib/backup/notifier/prowl.rb +9 -17
- data/lib/backup/notifier/twitter.rb +11 -18
- data/lib/backup/package.rb +47 -0
- data/lib/backup/packager.rb +81 -16
- data/lib/backup/splitter.rb +48 -35
- data/lib/backup/storage/base.rb +44 -172
- data/lib/backup/storage/cloudfiles.rb +31 -46
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +92 -76
- data/lib/backup/storage/ftp.rb +30 -40
- data/lib/backup/storage/local.rb +44 -45
- data/lib/backup/storage/ninefold.rb +55 -49
- data/lib/backup/storage/rsync.rb +49 -56
- data/lib/backup/storage/s3.rb +33 -44
- data/lib/backup/storage/scp.rb +21 -48
- data/lib/backup/storage/sftp.rb +26 -40
- data/lib/backup/syncer/base.rb +7 -0
- data/lib/backup/syncer/rsync/base.rb +78 -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 +42 -32
- data/lib/backup/version.rb +1 -1
- data/spec/archive_spec.rb +235 -69
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +142 -1
- data/spec/cli/utility_spec.rb +338 -13
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +60 -35
- data/spec/compressor/gzip_spec.rb +60 -35
- data/spec/compressor/lzma_spec.rb +60 -35
- data/spec/compressor/pbzip2_spec.rb +98 -37
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +4 -4
- data/spec/configuration/compressor/bzip2_spec.rb +1 -0
- data/spec/configuration/compressor/gzip_spec.rb +1 -0
- data/spec/configuration/compressor/lzma_spec.rb +1 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +2 -1
- data/spec/configuration/database/mongodb_spec.rb +26 -16
- data/spec/configuration/database/mysql_spec.rb +4 -0
- data/spec/configuration/database/postgresql_spec.rb +4 -0
- data/spec/configuration/database/redis_spec.rb +4 -0
- data/spec/configuration/database/riak_spec.rb +4 -0
- data/spec/configuration/encryptor/gpg_spec.rb +1 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +1 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +1 -0
- data/spec/configuration/notifier/hipchat_spec.rb +1 -0
- data/spec/configuration/notifier/mail_spec.rb +1 -0
- data/spec/configuration/notifier/presently_spec.rb +1 -0
- data/spec/configuration/notifier/prowl_spec.rb +1 -0
- data/spec/configuration/notifier/twitter_spec.rb +1 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +1 -0
- data/spec/configuration/storage/dropbox_spec.rb +4 -3
- data/spec/configuration/storage/ftp_spec.rb +1 -0
- data/spec/configuration/storage/local_spec.rb +1 -0
- data/spec/configuration/storage/ninefold_spec.rb +1 -0
- data/spec/configuration/storage/rsync_spec.rb +3 -1
- data/spec/configuration/storage/s3_spec.rb +1 -0
- data/spec/configuration/storage/scp_spec.rb +1 -0
- data/spec/configuration/storage/sftp_spec.rb +1 -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_spec.rb → rsync/push_spec.rb} +12 -15
- data/spec/configuration/syncer/s3_spec.rb +2 -3
- data/spec/database/base_spec.rb +35 -20
- data/spec/database/mongodb_spec.rb +298 -119
- data/spec/database/mysql_spec.rb +147 -72
- data/spec/database/postgresql_spec.rb +155 -100
- data/spec/database/redis_spec.rb +200 -97
- data/spec/database/riak_spec.rb +82 -24
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +105 -28
- data/spec/encryptor/open_ssl_spec.rb +85 -114
- data/spec/logger_spec.rb +74 -8
- data/spec/model_spec.rb +528 -220
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +147 -119
- data/spec/notifier/hipchat_spec.rb +140 -145
- data/spec/notifier/mail_spec.rb +190 -248
- data/spec/notifier/presently_spec.rb +147 -282
- data/spec/notifier/prowl_spec.rb +79 -111
- data/spec/notifier/twitter_spec.rb +87 -106
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +154 -0
- data/spec/spec_helper.rb +36 -13
- data/spec/splitter_spec.rb +90 -41
- data/spec/storage/base_spec.rb +95 -239
- data/spec/storage/cloudfiles_spec.rb +185 -75
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +318 -87
- data/spec/storage/ftp_spec.rb +165 -152
- data/spec/storage/local_spec.rb +206 -54
- data/spec/storage/ninefold_spec.rb +264 -128
- data/spec/storage/rsync_spec.rb +244 -163
- data/spec/storage/s3_spec.rb +175 -64
- data/spec/storage/scp_spec.rb +156 -150
- data/spec/storage/sftp_spec.rb +153 -135
- data/spec/syncer/base_spec.rb +22 -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 +180 -91
- data/templates/cli/utility/config +1 -1
- data/templates/cli/utility/database/mongodb +4 -0
- data/templates/cli/utility/database/mysql +3 -0
- data/templates/cli/utility/database/postgresql +3 -0
- data/templates/cli/utility/database/redis +3 -0
- data/templates/cli/utility/database/riak +3 -0
- data/templates/cli/utility/storage/dropbox +4 -1
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/{rsync → rsync_pull} +2 -2
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/storage/dropbox/authorization_url.erb +1 -1
- metadata +42 -17
- data/lib/backup/configuration/syncer/rsync.rb +0 -45
- data/lib/backup/finder.rb +0 -87
- data/lib/backup/storage/object.rb +0 -47
- data/lib/backup/syncer/rsync.rb +0 -152
- data/spec/backup_spec.rb +0 -11
- data/spec/finder_spec.rb +0 -91
- data/spec/storage/object_spec.rb +0 -74
- data/spec/syncer/rsync_spec.rb +0 -195
|
@@ -16,10 +16,10 @@ module Backup
|
|
|
16
16
|
# faster (-1) (but not significantly faster)
|
|
17
17
|
attr_accessor :fast
|
|
18
18
|
|
|
19
|
-
##
|
|
20
|
-
# Tells Backup::Compressor::Pbzip2 how many processors
|
|
21
|
-
# use, by default autodetect is used
|
|
22
|
-
|
|
19
|
+
##
|
|
20
|
+
# Tells Backup::Compressor::Pbzip2 how many processors
|
|
21
|
+
# use, by default autodetect is used
|
|
22
|
+
attr_accessor :processors
|
|
23
23
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
module Backup
|
|
4
4
|
module Configuration
|
|
5
5
|
module Database
|
|
6
|
-
class Base <
|
|
6
|
+
class Base < Configuration::Base
|
|
7
7
|
class << self
|
|
8
8
|
|
|
9
9
|
##
|
|
10
10
|
# Allows the user to specify the path to a "dump" utility
|
|
11
11
|
# in case it cannot be auto-detected by Backup
|
|
12
|
+
# [DEPRECATED] - use <utility_name>_utility methods
|
|
12
13
|
attr_accessor :utility_path
|
|
13
14
|
|
|
14
15
|
end
|
|
@@ -30,6 +30,14 @@ module Backup
|
|
|
30
30
|
# Additional "mongodump" options
|
|
31
31
|
attr_accessor :additional_options
|
|
32
32
|
|
|
33
|
+
##
|
|
34
|
+
# Path to the mongodump utility (optional)
|
|
35
|
+
attr_accessor :mongodump_utility
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Path to the mongo utility (optional)
|
|
39
|
+
attr_accessor :mongo_utility
|
|
40
|
+
|
|
33
41
|
##
|
|
34
42
|
# 'lock' dump meaning wrapping mongodump with fsync & lock
|
|
35
43
|
attr_accessor :lock
|
|
@@ -18,8 +18,12 @@ module Backup
|
|
|
18
18
|
# Cookie is the Erlang cookie/shared secret used to connect to the node.
|
|
19
19
|
attr_accessor :cookie
|
|
20
20
|
|
|
21
|
+
##
|
|
22
|
+
# Path to riak-admin utility (optional)
|
|
23
|
+
attr_accessor :riak_admin_utility
|
|
24
|
+
|
|
21
25
|
end
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|
|
25
|
-
end
|
|
29
|
+
end
|
|
@@ -10,7 +10,7 @@ module Backup
|
|
|
10
10
|
# The password that'll be used to encrypt the backup. This
|
|
11
11
|
# password will be required to decrypt the backup later on.
|
|
12
12
|
attr_accessor :password
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
##
|
|
15
15
|
# The password file used for encrypting the backup. This
|
|
16
16
|
# password file will be required to decrypt the backup later
|
|
@@ -9,8 +9,11 @@ module Backup
|
|
|
9
9
|
# configuration for these methods, if they respond then they will
|
|
10
10
|
# assign the object's attribute(s) to that particular global configuration's attribute
|
|
11
11
|
def load_defaults!
|
|
12
|
-
|
|
13
|
-
configuration
|
|
12
|
+
module_names = self.class.name.split('::')[1..-1]
|
|
13
|
+
configuration = Backup::Configuration
|
|
14
|
+
module_names.each do |module_name|
|
|
15
|
+
configuration = configuration.const_get(module_name)
|
|
16
|
+
end
|
|
14
17
|
|
|
15
18
|
getter_methods.each do |attribute|
|
|
16
19
|
if configuration.respond_to?(attribute)
|
|
@@ -27,6 +30,8 @@ module Backup
|
|
|
27
30
|
end
|
|
28
31
|
end
|
|
29
32
|
|
|
33
|
+
private
|
|
34
|
+
|
|
30
35
|
##
|
|
31
36
|
# Returns an Array of the setter methods (as String)
|
|
32
37
|
def setter_methods
|
|
@@ -3,49 +3,25 @@
|
|
|
3
3
|
module Backup
|
|
4
4
|
module Configuration
|
|
5
5
|
module Notifier
|
|
6
|
-
class Base <
|
|
6
|
+
class Base < Configuration::Base
|
|
7
7
|
class << self
|
|
8
8
|
|
|
9
9
|
##
|
|
10
10
|
# When set to true, the user will be notified by email
|
|
11
11
|
# when a backup process ends without raising any exceptions
|
|
12
|
-
|
|
12
|
+
attr_accessor :on_success
|
|
13
13
|
|
|
14
14
|
##
|
|
15
15
|
# When set to true, the user will be notified by email
|
|
16
16
|
# when a backup process ends successfully, but logged warnings
|
|
17
|
-
|
|
17
|
+
attr_accessor :on_warning
|
|
18
18
|
|
|
19
19
|
##
|
|
20
20
|
# When set to true, the user will be notified by email
|
|
21
21
|
# when a backup process raises an exception before finishing
|
|
22
|
-
|
|
22
|
+
attr_accessor :on_failure
|
|
23
23
|
|
|
24
24
|
end
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
# When @on_success is nil it means it hasn't been defined
|
|
28
|
-
# and will then default to true
|
|
29
|
-
def self.on_success
|
|
30
|
-
return true if @on_success.nil?
|
|
31
|
-
@on_success
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
##
|
|
35
|
-
# When @on_success is nil it means it hasn't been defined
|
|
36
|
-
# and will then default to true
|
|
37
|
-
def self.on_warning
|
|
38
|
-
return true if @on_warning.nil?
|
|
39
|
-
@on_warning
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
##
|
|
43
|
-
# When @on_failure is nil it means it hasn't been defined
|
|
44
|
-
# and will then default to true
|
|
45
|
-
def self.on_failure
|
|
46
|
-
return true if @on_failure.nil?
|
|
47
|
-
@on_failure
|
|
48
|
-
end
|
|
49
25
|
end
|
|
50
26
|
end
|
|
51
27
|
end
|
|
@@ -11,16 +11,26 @@ module Backup
|
|
|
11
11
|
attr_accessor :api_key, :api_secret
|
|
12
12
|
|
|
13
13
|
##
|
|
14
|
-
#
|
|
15
|
-
|
|
14
|
+
# Dropbox Access Type
|
|
15
|
+
# Valid values are:
|
|
16
|
+
# :app_folder (default)
|
|
17
|
+
# :dropbox (full access)
|
|
18
|
+
attr_accessor :access_type
|
|
16
19
|
|
|
17
20
|
##
|
|
18
|
-
#
|
|
19
|
-
attr_accessor :
|
|
21
|
+
# Path to where the backups will be stored
|
|
22
|
+
attr_accessor :path
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
# DEPRECATED METHODS #############################################
|
|
23
26
|
|
|
27
|
+
# Deprecated as of v3.0.21 - for move to official 'dropbox-sdk' gem (v1.1)
|
|
28
|
+
attr_reader :timeout
|
|
29
|
+
def timeout=(value)
|
|
30
|
+
Logger.warn "[DEPRECATED] Backup::Configuration::Storage::Dropbox.timeout=\n" +
|
|
31
|
+
" is deprecated and will be removed at some point."
|
|
32
|
+
end
|
|
33
|
+
|
|
24
34
|
def email
|
|
25
35
|
Logger.warn "[DEPRECATED] Backup::Configuration::Storage::Dropbox.email\n" +
|
|
26
36
|
" is deprecated and will be removed at some point."
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Configuration
|
|
5
|
+
module Syncer
|
|
6
|
+
module RSync
|
|
7
|
+
class Base < Syncer::Base
|
|
8
|
+
class << self
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Path to store the synced files/directories to
|
|
12
|
+
attr_accessor :path
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Flag for mirroring the files/directories
|
|
16
|
+
attr_accessor :mirror
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# Additional options for the rsync cli
|
|
20
|
+
attr_accessor :additional_options
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Configuration
|
|
5
|
+
module Syncer
|
|
6
|
+
module RSync
|
|
7
|
+
class Push < Base
|
|
8
|
+
class << self
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Server credentials
|
|
12
|
+
attr_accessor :username, :password
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Server IP Address and SSH port
|
|
16
|
+
attr_accessor :ip
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# The SSH port to connect to
|
|
20
|
+
attr_accessor :port
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# Flag for compressing (only compresses for the transfer)
|
|
24
|
+
attr_accessor :compress
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/backup/database/base.rb
CHANGED
|
@@ -6,15 +6,20 @@ module Backup
|
|
|
6
6
|
include Backup::CLI::Helpers
|
|
7
7
|
include Backup::Configuration::Helpers
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
# Contains the path to where the database should be dumped
|
|
11
|
-
attr_accessor :dump_path
|
|
12
|
-
|
|
13
9
|
##
|
|
14
10
|
# Allows the user to specify the path to a "dump" utility
|
|
15
11
|
# in case it cannot be auto-detected by Backup
|
|
12
|
+
# [DEPRECATED] - use each subclass' <utility_name>_utility method
|
|
16
13
|
attr_accessor :utility_path
|
|
17
14
|
|
|
15
|
+
##
|
|
16
|
+
# Creates a new instance of the MongoDB database object
|
|
17
|
+
# * Called using super(model) from subclasses *
|
|
18
|
+
def initialize(model)
|
|
19
|
+
@model = model
|
|
20
|
+
load_defaults!
|
|
21
|
+
end
|
|
22
|
+
|
|
18
23
|
##
|
|
19
24
|
# Super method for all child (database) objects. Every database object's #perform!
|
|
20
25
|
# method should call #super before anything else to prepare
|
|
@@ -23,18 +28,31 @@ module Backup
|
|
|
23
28
|
log!
|
|
24
29
|
end
|
|
25
30
|
|
|
31
|
+
private
|
|
32
|
+
|
|
26
33
|
##
|
|
27
34
|
# Defines the @dump_path and ensures it exists by creating it
|
|
28
35
|
def prepare!
|
|
29
|
-
@dump_path = File.join(
|
|
30
|
-
|
|
36
|
+
@dump_path = File.join(
|
|
37
|
+
Config.tmp_path,
|
|
38
|
+
@model.trigger,
|
|
39
|
+
'databases',
|
|
40
|
+
self.class.name.split('::').last
|
|
41
|
+
)
|
|
42
|
+
FileUtils.mkdir_p(@dump_path)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Return the database name, with Backup namespace removed
|
|
47
|
+
def database_name
|
|
48
|
+
self.class.to_s.sub('Backup::', '')
|
|
31
49
|
end
|
|
32
50
|
|
|
33
51
|
##
|
|
34
52
|
# Logs a message to the console and log file to inform
|
|
35
53
|
# the client that Backup is dumping the database
|
|
36
54
|
def log!
|
|
37
|
-
Logger.message "#{
|
|
55
|
+
Logger.message "#{ database_name } started dumping and archiving '#{ name }'."
|
|
38
56
|
end
|
|
39
57
|
end
|
|
40
58
|
end
|
|
@@ -28,123 +28,153 @@ module Backup
|
|
|
28
28
|
# Additional "mongodump" options
|
|
29
29
|
attr_accessor :additional_options
|
|
30
30
|
|
|
31
|
+
##
|
|
32
|
+
# Path to the mongodump utility (optional)
|
|
33
|
+
attr_accessor :mongodump_utility
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Path to the mongo utility (optional)
|
|
37
|
+
attr_accessor :mongo_utility
|
|
38
|
+
|
|
31
39
|
##
|
|
32
40
|
# 'lock' dump meaning wrapping mongodump with fsync & lock
|
|
33
41
|
attr_accessor :lock
|
|
34
42
|
|
|
35
43
|
##
|
|
36
44
|
# Creates a new instance of the MongoDB database object
|
|
37
|
-
def initialize(&block)
|
|
38
|
-
|
|
45
|
+
def initialize(model, &block)
|
|
46
|
+
super(model)
|
|
39
47
|
|
|
40
48
|
@only_collections ||= Array.new
|
|
41
49
|
@additional_options ||= Array.new
|
|
42
50
|
@ipv6 ||= false
|
|
43
51
|
@lock ||= false
|
|
44
52
|
|
|
45
|
-
instance_eval(&block)
|
|
46
|
-
end
|
|
53
|
+
instance_eval(&block) if block_given?
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
if @utility_path
|
|
56
|
+
Logger.warn "[DEPRECATED] " +
|
|
57
|
+
"Database::MongoDB#utility_path has been deprecated.\n" +
|
|
58
|
+
" Use Database::MongoDB#mongodump_utility instead."
|
|
59
|
+
@mongodump_utility ||= @utility_path
|
|
60
|
+
end
|
|
61
|
+
@mongodump_utility ||= utility(:mongodump)
|
|
62
|
+
@mongo_utility ||= utility(:mongo)
|
|
56
63
|
end
|
|
57
64
|
|
|
58
65
|
##
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
# Performs the mongodump command and outputs the data to the
|
|
67
|
+
# specified path based on the 'trigger'. If the user hasn't specified any
|
|
68
|
+
# specific collections to dump, it'll dump everything. If the user has specified
|
|
69
|
+
# collections to dump, it'll loop through the array of collections and invoke the
|
|
70
|
+
# 'mongodump' command once per collection
|
|
71
|
+
def perform!
|
|
72
|
+
super
|
|
73
|
+
|
|
74
|
+
lock_database if @lock
|
|
75
|
+
@only_collections.empty? ? dump! : specific_collection_dump!
|
|
76
|
+
|
|
77
|
+
rescue => err
|
|
78
|
+
raise Errors::Database::MongoDBError.wrap(err, 'Database Dump Failed!')
|
|
79
|
+
ensure
|
|
80
|
+
unlock_database if @lock
|
|
81
|
+
package! unless err
|
|
66
82
|
end
|
|
67
83
|
|
|
84
|
+
private
|
|
85
|
+
|
|
68
86
|
##
|
|
69
|
-
# Builds
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
@additional_options.join("\s")
|
|
87
|
+
# Builds and runs the mongodump command
|
|
88
|
+
def dump!
|
|
89
|
+
run(mongodump)
|
|
73
90
|
end
|
|
74
91
|
|
|
75
92
|
##
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
# For each collection in the @only_collections array, it'll
|
|
94
|
+
# build the whole 'mongodump' command, append the '--collection' option,
|
|
95
|
+
# and run the command built command
|
|
96
|
+
def specific_collection_dump!
|
|
97
|
+
@only_collections.each do |collection|
|
|
98
|
+
run("#{mongodump} --collection='#{collection}'")
|
|
99
|
+
end
|
|
79
100
|
end
|
|
80
101
|
|
|
81
102
|
##
|
|
82
|
-
#
|
|
83
|
-
def
|
|
84
|
-
"
|
|
103
|
+
# Builds the full mongodump string based on all attributes
|
|
104
|
+
def mongodump
|
|
105
|
+
"#{ mongodump_utility } #{ database } #{ credential_options } " +
|
|
106
|
+
"#{ connectivity_options } #{ ipv6_option } #{ user_options } #{ dump_directory }"
|
|
85
107
|
end
|
|
86
108
|
|
|
87
109
|
##
|
|
88
|
-
#
|
|
89
|
-
|
|
90
|
-
|
|
110
|
+
# If a compressor is configured, packages the dump_path into a
|
|
111
|
+
# single compressed tar archive, then removes the dump_path.
|
|
112
|
+
# e.g.
|
|
113
|
+
# if the database was dumped to:
|
|
114
|
+
# ~/Backup/.tmp/databases/MongoDB/
|
|
115
|
+
# then it will be packaged into:
|
|
116
|
+
# ~/Backup/.tmp/databases/MongoDB-<timestamp>.tar.gz
|
|
117
|
+
def package!
|
|
118
|
+
return unless @model.compressor
|
|
119
|
+
|
|
120
|
+
base_dir = File.dirname(@dump_path)
|
|
121
|
+
dump_dir = File.basename(@dump_path)
|
|
122
|
+
timestamp = Time.now.to_i.to_s[-5, 5]
|
|
123
|
+
outfile = @dump_path + '-' + timestamp + '.tar'
|
|
124
|
+
|
|
125
|
+
@model.compressor.compress_with do |command, ext|
|
|
126
|
+
run("#{ utility(:tar) } -cf - " +
|
|
127
|
+
"-C '#{ base_dir }' '#{ dump_dir }'" +
|
|
128
|
+
" | #{ command } > #{ outfile + ext }")
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
FileUtils.rm_rf(@dump_path)
|
|
91
132
|
end
|
|
92
133
|
|
|
93
134
|
##
|
|
94
|
-
# Returns the MongoDB
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"--out='#{ dump_path }'"
|
|
135
|
+
# Returns the MongoDB database selector syntax
|
|
136
|
+
def database
|
|
137
|
+
"--db='#{ name }'" if name
|
|
98
138
|
end
|
|
99
139
|
|
|
100
140
|
##
|
|
101
|
-
# Builds the
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
141
|
+
# Builds the MongoDB credentials syntax to authenticate the user
|
|
142
|
+
# to perform the database dumping process
|
|
143
|
+
def credential_options
|
|
144
|
+
%w[username password].map do |option|
|
|
145
|
+
next if send(option).to_s.empty?
|
|
146
|
+
"--#{option}='#{send(option)}'"
|
|
147
|
+
end.compact.join(' ')
|
|
105
148
|
end
|
|
106
149
|
|
|
107
150
|
##
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
lock_database if @lock.eql?(true)
|
|
117
|
-
if collections_to_dump.is_a?(Array) and not collections_to_dump.empty?
|
|
118
|
-
specific_collection_dump!
|
|
119
|
-
else
|
|
120
|
-
dump!
|
|
121
|
-
end
|
|
122
|
-
unlock_database if @lock.eql?(true)
|
|
123
|
-
rescue => exception
|
|
124
|
-
unlock_database if @lock.eql?(true)
|
|
125
|
-
raise exception
|
|
151
|
+
# Builds the MongoDB connectivity options syntax to connect the user
|
|
152
|
+
# to perform the database dumping process
|
|
153
|
+
def connectivity_options
|
|
154
|
+
%w[host port].map do |option|
|
|
155
|
+
next if send(option).to_s.empty?
|
|
156
|
+
"--#{option}='#{send(option)}'"
|
|
157
|
+
end.compact.join(' ')
|
|
126
158
|
end
|
|
127
159
|
|
|
128
160
|
##
|
|
129
|
-
#
|
|
130
|
-
def
|
|
131
|
-
|
|
161
|
+
# Returns the mongodump syntax for enabling ipv6
|
|
162
|
+
def ipv6_option
|
|
163
|
+
@ipv6 ? '--ipv6' : ''
|
|
132
164
|
end
|
|
133
165
|
|
|
134
166
|
##
|
|
135
|
-
#
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
collections_to_dump.each do |collection|
|
|
140
|
-
run("#{mongodump} --collection='#{collection}'")
|
|
141
|
-
end
|
|
167
|
+
# Builds a MongoDB compatible string for the
|
|
168
|
+
# additional options specified by the user
|
|
169
|
+
def user_options
|
|
170
|
+
@additional_options.join(' ')
|
|
142
171
|
end
|
|
143
172
|
|
|
144
173
|
##
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
|
|
174
|
+
# Returns the MongoDB syntax for determining where to output all the database dumps,
|
|
175
|
+
# e.g. ~/Backup/.tmp/databases/MongoDB/<databases here>/<database collections>
|
|
176
|
+
def dump_directory
|
|
177
|
+
"--out='#{ @dump_path }'"
|
|
148
178
|
end
|
|
149
179
|
|
|
150
180
|
##
|
|
@@ -152,9 +182,9 @@ module Backup
|
|
|
152
182
|
# and ensure no 'write operations' are performed during the
|
|
153
183
|
# dump process
|
|
154
184
|
def lock_database
|
|
155
|
-
lock_command = <<-EOS
|
|
185
|
+
lock_command = <<-EOS.gsub(/^ +/, ' ')
|
|
156
186
|
echo 'use admin
|
|
157
|
-
db.runCommand({"fsync" : 1, "lock" : 1})' | #{ "#{
|
|
187
|
+
db.runCommand({"fsync" : 1, "lock" : 1})' | #{ "#{ mongo_utility } #{ mongo_uri }" }
|
|
158
188
|
EOS
|
|
159
189
|
|
|
160
190
|
run(lock_command)
|
|
@@ -163,14 +193,21 @@ module Backup
|
|
|
163
193
|
##
|
|
164
194
|
# Unlocks the (locked) database
|
|
165
195
|
def unlock_database
|
|
166
|
-
unlock_command = <<-EOS
|
|
196
|
+
unlock_command = <<-EOS.gsub(/^ +/, ' ')
|
|
167
197
|
echo 'use admin
|
|
168
|
-
db.$cmd.sys.unlock.findOne()' | #{ "#{
|
|
198
|
+
db.$cmd.sys.unlock.findOne()' | #{ "#{ mongo_utility } #{ mongo_uri }" }
|
|
169
199
|
EOS
|
|
170
200
|
|
|
171
201
|
run(unlock_command)
|
|
172
202
|
end
|
|
173
203
|
|
|
204
|
+
##
|
|
205
|
+
# Builds a Mongo URI based on the provided attributes
|
|
206
|
+
def mongo_uri
|
|
207
|
+
["#{ host }:#{ port }#{ ('/' + name) if name }",
|
|
208
|
+
credential_options, ipv6_option].join(' ').strip
|
|
209
|
+
end
|
|
210
|
+
|
|
174
211
|
end
|
|
175
212
|
end
|
|
176
213
|
end
|