backup 3.0.20 → 3.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. data/Gemfile +1 -5
  2. data/Gemfile.lock +46 -50
  3. data/README.md +54 -27
  4. data/lib/backup.rb +16 -39
  5. data/lib/backup/archive.rb +42 -18
  6. data/lib/backup/cleaner.rb +110 -25
  7. data/lib/backup/cli/helpers.rb +17 -32
  8. data/lib/backup/cli/utility.rb +46 -107
  9. data/lib/backup/compressor/base.rb +14 -2
  10. data/lib/backup/compressor/bzip2.rb +10 -24
  11. data/lib/backup/compressor/gzip.rb +10 -24
  12. data/lib/backup/compressor/lzma.rb +10 -23
  13. data/lib/backup/compressor/pbzip2.rb +12 -32
  14. data/lib/backup/config.rb +171 -0
  15. data/lib/backup/configuration/compressor/base.rb +1 -2
  16. data/lib/backup/configuration/compressor/pbzip2.rb +4 -4
  17. data/lib/backup/configuration/database/base.rb +2 -1
  18. data/lib/backup/configuration/database/mongodb.rb +8 -0
  19. data/lib/backup/configuration/database/mysql.rb +4 -0
  20. data/lib/backup/configuration/database/postgresql.rb +4 -0
  21. data/lib/backup/configuration/database/redis.rb +4 -0
  22. data/lib/backup/configuration/database/riak.rb +5 -1
  23. data/lib/backup/configuration/encryptor/base.rb +1 -2
  24. data/lib/backup/configuration/encryptor/open_ssl.rb +1 -1
  25. data/lib/backup/configuration/helpers.rb +7 -2
  26. data/lib/backup/configuration/notifier/base.rb +4 -28
  27. data/lib/backup/configuration/storage/base.rb +1 -1
  28. data/lib/backup/configuration/storage/dropbox.rb +14 -4
  29. data/lib/backup/configuration/syncer/base.rb +10 -0
  30. data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
  31. data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
  32. data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
  33. data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
  34. data/lib/backup/configuration/syncer/s3.rb +0 -4
  35. data/lib/backup/database/base.rb +25 -7
  36. data/lib/backup/database/mongodb.rb +112 -75
  37. data/lib/backup/database/mysql.rb +54 -29
  38. data/lib/backup/database/postgresql.rb +60 -42
  39. data/lib/backup/database/redis.rb +61 -39
  40. data/lib/backup/database/riak.rb +35 -11
  41. data/lib/backup/dependency.rb +4 -5
  42. data/lib/backup/encryptor/base.rb +13 -1
  43. data/lib/backup/encryptor/gpg.rb +39 -39
  44. data/lib/backup/encryptor/open_ssl.rb +28 -38
  45. data/lib/backup/logger.rb +20 -11
  46. data/lib/backup/model.rb +206 -163
  47. data/lib/backup/notifier/base.rb +27 -25
  48. data/lib/backup/notifier/campfire.rb +7 -13
  49. data/lib/backup/notifier/hipchat.rb +28 -28
  50. data/lib/backup/notifier/mail.rb +24 -26
  51. data/lib/backup/notifier/presently.rb +10 -18
  52. data/lib/backup/notifier/prowl.rb +9 -17
  53. data/lib/backup/notifier/twitter.rb +11 -18
  54. data/lib/backup/package.rb +47 -0
  55. data/lib/backup/packager.rb +81 -16
  56. data/lib/backup/splitter.rb +48 -35
  57. data/lib/backup/storage/base.rb +44 -172
  58. data/lib/backup/storage/cloudfiles.rb +31 -46
  59. data/lib/backup/storage/cycler.rb +117 -0
  60. data/lib/backup/storage/dropbox.rb +92 -76
  61. data/lib/backup/storage/ftp.rb +30 -40
  62. data/lib/backup/storage/local.rb +44 -45
  63. data/lib/backup/storage/ninefold.rb +55 -49
  64. data/lib/backup/storage/rsync.rb +49 -56
  65. data/lib/backup/storage/s3.rb +33 -44
  66. data/lib/backup/storage/scp.rb +21 -48
  67. data/lib/backup/storage/sftp.rb +26 -40
  68. data/lib/backup/syncer/base.rb +7 -0
  69. data/lib/backup/syncer/rsync/base.rb +78 -0
  70. data/lib/backup/syncer/rsync/local.rb +53 -0
  71. data/lib/backup/syncer/rsync/pull.rb +38 -0
  72. data/lib/backup/syncer/rsync/push.rb +113 -0
  73. data/lib/backup/syncer/s3.rb +42 -32
  74. data/lib/backup/version.rb +1 -1
  75. data/spec/archive_spec.rb +235 -69
  76. data/spec/cleaner_spec.rb +304 -0
  77. data/spec/cli/helpers_spec.rb +142 -1
  78. data/spec/cli/utility_spec.rb +338 -13
  79. data/spec/compressor/base_spec.rb +31 -0
  80. data/spec/compressor/bzip2_spec.rb +60 -35
  81. data/spec/compressor/gzip_spec.rb +60 -35
  82. data/spec/compressor/lzma_spec.rb +60 -35
  83. data/spec/compressor/pbzip2_spec.rb +98 -37
  84. data/spec/config_spec.rb +321 -0
  85. data/spec/configuration/base_spec.rb +4 -4
  86. data/spec/configuration/compressor/bzip2_spec.rb +1 -0
  87. data/spec/configuration/compressor/gzip_spec.rb +1 -0
  88. data/spec/configuration/compressor/lzma_spec.rb +1 -0
  89. data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
  90. data/spec/configuration/database/base_spec.rb +2 -1
  91. data/spec/configuration/database/mongodb_spec.rb +26 -16
  92. data/spec/configuration/database/mysql_spec.rb +4 -0
  93. data/spec/configuration/database/postgresql_spec.rb +4 -0
  94. data/spec/configuration/database/redis_spec.rb +4 -0
  95. data/spec/configuration/database/riak_spec.rb +4 -0
  96. data/spec/configuration/encryptor/gpg_spec.rb +1 -0
  97. data/spec/configuration/encryptor/open_ssl_spec.rb +1 -0
  98. data/spec/configuration/notifier/base_spec.rb +32 -0
  99. data/spec/configuration/notifier/campfire_spec.rb +1 -0
  100. data/spec/configuration/notifier/hipchat_spec.rb +1 -0
  101. data/spec/configuration/notifier/mail_spec.rb +1 -0
  102. data/spec/configuration/notifier/presently_spec.rb +1 -0
  103. data/spec/configuration/notifier/prowl_spec.rb +1 -0
  104. data/spec/configuration/notifier/twitter_spec.rb +1 -0
  105. data/spec/configuration/storage/cloudfiles_spec.rb +1 -0
  106. data/spec/configuration/storage/dropbox_spec.rb +4 -3
  107. data/spec/configuration/storage/ftp_spec.rb +1 -0
  108. data/spec/configuration/storage/local_spec.rb +1 -0
  109. data/spec/configuration/storage/ninefold_spec.rb +1 -0
  110. data/spec/configuration/storage/rsync_spec.rb +3 -1
  111. data/spec/configuration/storage/s3_spec.rb +1 -0
  112. data/spec/configuration/storage/scp_spec.rb +1 -0
  113. data/spec/configuration/storage/sftp_spec.rb +1 -0
  114. data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
  115. data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
  116. data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
  117. data/spec/configuration/syncer/{rsync_spec.rb → rsync/push_spec.rb} +12 -15
  118. data/spec/configuration/syncer/s3_spec.rb +2 -3
  119. data/spec/database/base_spec.rb +35 -20
  120. data/spec/database/mongodb_spec.rb +298 -119
  121. data/spec/database/mysql_spec.rb +147 -72
  122. data/spec/database/postgresql_spec.rb +155 -100
  123. data/spec/database/redis_spec.rb +200 -97
  124. data/spec/database/riak_spec.rb +82 -24
  125. data/spec/dependency_spec.rb +49 -0
  126. data/spec/encryptor/base_spec.rb +30 -0
  127. data/spec/encryptor/gpg_spec.rb +105 -28
  128. data/spec/encryptor/open_ssl_spec.rb +85 -114
  129. data/spec/logger_spec.rb +74 -8
  130. data/spec/model_spec.rb +528 -220
  131. data/spec/notifier/base_spec.rb +89 -0
  132. data/spec/notifier/campfire_spec.rb +147 -119
  133. data/spec/notifier/hipchat_spec.rb +140 -145
  134. data/spec/notifier/mail_spec.rb +190 -248
  135. data/spec/notifier/presently_spec.rb +147 -282
  136. data/spec/notifier/prowl_spec.rb +79 -111
  137. data/spec/notifier/twitter_spec.rb +87 -106
  138. data/spec/package_spec.rb +61 -0
  139. data/spec/packager_spec.rb +154 -0
  140. data/spec/spec_helper.rb +36 -13
  141. data/spec/splitter_spec.rb +90 -41
  142. data/spec/storage/base_spec.rb +95 -239
  143. data/spec/storage/cloudfiles_spec.rb +185 -75
  144. data/spec/storage/cycler_spec.rb +239 -0
  145. data/spec/storage/dropbox_spec.rb +318 -87
  146. data/spec/storage/ftp_spec.rb +165 -152
  147. data/spec/storage/local_spec.rb +206 -54
  148. data/spec/storage/ninefold_spec.rb +264 -128
  149. data/spec/storage/rsync_spec.rb +244 -163
  150. data/spec/storage/s3_spec.rb +175 -64
  151. data/spec/storage/scp_spec.rb +156 -150
  152. data/spec/storage/sftp_spec.rb +153 -135
  153. data/spec/syncer/base_spec.rb +22 -0
  154. data/spec/syncer/rsync/base_spec.rb +118 -0
  155. data/spec/syncer/rsync/local_spec.rb +121 -0
  156. data/spec/syncer/rsync/pull_spec.rb +90 -0
  157. data/spec/syncer/rsync/push_spec.rb +327 -0
  158. data/spec/syncer/s3_spec.rb +180 -91
  159. data/templates/cli/utility/config +1 -1
  160. data/templates/cli/utility/database/mongodb +4 -0
  161. data/templates/cli/utility/database/mysql +3 -0
  162. data/templates/cli/utility/database/postgresql +3 -0
  163. data/templates/cli/utility/database/redis +3 -0
  164. data/templates/cli/utility/database/riak +3 -0
  165. data/templates/cli/utility/storage/dropbox +4 -1
  166. data/templates/cli/utility/syncer/rsync_local +12 -0
  167. data/templates/cli/utility/syncer/{rsync → rsync_pull} +2 -2
  168. data/templates/cli/utility/syncer/rsync_push +17 -0
  169. data/templates/storage/dropbox/authorization_url.erb +1 -1
  170. metadata +42 -17
  171. data/lib/backup/configuration/syncer/rsync.rb +0 -45
  172. data/lib/backup/finder.rb +0 -87
  173. data/lib/backup/storage/object.rb +0 -47
  174. data/lib/backup/syncer/rsync.rb +0 -152
  175. data/spec/backup_spec.rb +0 -11
  176. data/spec/finder_spec.rb +0 -91
  177. data/spec/storage/object_spec.rb +0 -74
  178. data/spec/syncer/rsync_spec.rb +0 -195
@@ -3,8 +3,7 @@
3
3
  module Backup
4
4
  module Configuration
5
5
  module Compressor
6
- class Base < Backup::Configuration::Base
7
- end
6
+ class Base < Configuration::Base; end
8
7
  end
9
8
  end
10
9
  end
@@ -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
- attr_writer :processors
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 < Backup::Configuration::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
@@ -30,6 +30,10 @@ module Backup
30
30
  # Additional "mysqldump" options
31
31
  attr_accessor :additional_options
32
32
 
33
+ ##
34
+ # Path to mysqldump utility (optional)
35
+ attr_accessor :mysqldump_utility
36
+
33
37
  end
34
38
  end
35
39
  end
@@ -30,6 +30,10 @@ module Backup
30
30
  # Additional "pg_dump" options
31
31
  attr_accessor :additional_options
32
32
 
33
+ ##
34
+ # Path to pg_dump utility (optional)
35
+ attr_accessor :pg_dump_utility
36
+
33
37
  end
34
38
  end
35
39
  end
@@ -28,6 +28,10 @@ module Backup
28
28
  # Additional "redis-cli" options
29
29
  attr_accessor :additional_options
30
30
 
31
+ ##
32
+ # Path to the redis-cli utility (optional)
33
+ attr_accessor :redis_cli_utility
34
+
31
35
  end
32
36
  end
33
37
  end
@@ -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
@@ -3,8 +3,7 @@
3
3
  module Backup
4
4
  module Configuration
5
5
  module Encryptor
6
- class Base < Backup::Configuration::Base
7
- end
6
+ class Base < Configuration::Base; end
8
7
  end
9
8
  end
10
9
  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
- c = self.class.name.split('::')
13
- configuration = Backup::Configuration.const_get(c[1]).const_get(c[2])
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 < Backup::Configuration::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
- attr_writer :on_success
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
- attr_writer :on_warning
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
- attr_writer :on_failure
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
@@ -3,7 +3,7 @@
3
3
  module Backup
4
4
  module Configuration
5
5
  module Storage
6
- class Base < Backup::Configuration::Base
6
+ class Base < Configuration::Base
7
7
  class << self
8
8
 
9
9
  ##
@@ -11,16 +11,26 @@ module Backup
11
11
  attr_accessor :api_key, :api_secret
12
12
 
13
13
  ##
14
- # Path to where the backups will be stored
15
- attr_accessor :path
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
- # Dropbox connection timeout
19
- attr_accessor :timeout
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,10 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Configuration
5
+ module Syncer
6
+ class Base < Configuration::Base; end
7
+ end
8
+ end
9
+ end
10
+
@@ -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,11 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Configuration
5
+ module Syncer
6
+ module RSync
7
+ class Local < Base; end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Configuration
5
+ module Syncer
6
+ module RSync
7
+ class Pull < Push; end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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
@@ -14,10 +14,6 @@ module Backup
14
14
  # Amazon S3 bucket name and path to sync to
15
15
  attr_accessor :bucket, :path
16
16
 
17
- ##
18
- # Directories to sync
19
- attr_accessor :directories
20
-
21
17
  ##
22
18
  # Flag to enable mirroring
23
19
  attr_accessor :mirror
@@ -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(TMP_PATH, TRIGGER, self.class.name.split('::').last)
30
- mkdir(dump_path)
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 "#{self.class} started dumping and archiving '#{ name }'."
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
- load_defaults!
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
- # Builds the MongoDB credentials syntax to authenticate the user
50
- # to perform the database dumping process
51
- def credential_options
52
- %w[username password].map do |option|
53
- next if send(option).nil? or send(option).empty?
54
- "--#{option}='#{send(option)}'"
55
- end.compact.join("\s")
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
- # Builds the MongoDB connectivity options syntax to connect the user
60
- # to perform the database dumping process
61
- def connectivity_options
62
- %w[host port].map do |option|
63
- next if send(option).nil? or (send(option).respond_to?(:empty?) and send(option).empty?)
64
- "--#{option}='#{send(option)}'"
65
- end.compact.join("\s")
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 a MongoDB compatible string for the
70
- # additional options specified by the user
71
- def additional_options
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
- # Returns an array of collections to dump
77
- def collections_to_dump
78
- @only_collections
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
- # Returns the MongoDB database selector syntax
83
- def database
84
- "--db='#{ name }'"
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
- # Returns the mongodump syntax for enabling ipv6
89
- def ipv6
90
- @ipv6.eql?(true) ? '--ipv6' : ''
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 syntax for determining where to output all the database dumps,
95
- # e.g. ~/Backup/.tmp/MongoDB/<databases here>/<database collections>
96
- def dump_directory
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 full mongodump string based on all attributes
102
- def mongodump
103
- "#{ utility(:mongodump) } #{ database } #{ credential_options } " +
104
- "#{ connectivity_options } #{ ipv6 } #{ additional_options } #{ dump_directory }"
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
- # Performs the mongodump command and outputs the data to the
109
- # specified path based on the 'trigger'. If the user hasn't specified any
110
- # specific collections to dump, it'll dump everything. If the user has specified
111
- # collections to dump, it'll loop through the array of collections and invoke the
112
- # 'mongodump' command once per collection
113
- def perform!
114
- super
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
- # Builds and runs the mongodump command
130
- def dump!
131
- run(mongodump)
161
+ # Returns the mongodump syntax for enabling ipv6
162
+ def ipv6_option
163
+ @ipv6 ? '--ipv6' : ''
132
164
  end
133
165
 
134
166
  ##
135
- # For each collection in the @only_collections array, it'll
136
- # build the whole 'mongodump' command, append the '--collection' option,
137
- # and run the command built command
138
- def specific_collection_dump!
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
- # Builds a Mongo URI based on the provided attributes
146
- def mongo_uri
147
- ["#{ host }:#{ port }#{ name.is_a?(String) && !name.empty? ? "/#{ name }" : "" }", credential_options, ipv6].join(' ').strip
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})' | #{ "#{ utility(:mongo) } #{ mongo_uri }" }
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()' | #{ "#{ utility(:mongo) } #{ mongo_uri }" }
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