backup 2.4.5.1 → 3.0.0.build.0

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.
Files changed (168) hide show
  1. data/.gitignore +2 -0
  2. data/.infinity_test +7 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +17 -0
  5. data/Gemfile.lock +88 -0
  6. data/LICENSE.md +24 -0
  7. data/README.md +189 -75
  8. data/backup.gemspec +41 -0
  9. data/bin/backup +161 -90
  10. data/lib/backup.rb +133 -117
  11. data/lib/backup/archive.rb +54 -0
  12. data/lib/backup/cli.rb +50 -0
  13. data/lib/backup/compressor/base.rb +17 -0
  14. data/lib/backup/compressor/gzip.rb +61 -0
  15. data/lib/backup/configuration/base.rb +7 -67
  16. data/lib/backup/configuration/compressor/base.rb +10 -0
  17. data/lib/backup/configuration/compressor/gzip.rb +23 -0
  18. data/lib/backup/configuration/database/base.rb +18 -0
  19. data/lib/backup/configuration/database/mongodb.rb +37 -0
  20. data/lib/backup/configuration/database/mysql.rb +37 -0
  21. data/lib/backup/configuration/database/postgresql.rb +37 -0
  22. data/lib/backup/configuration/database/redis.rb +35 -0
  23. data/lib/backup/configuration/encryptor/base.rb +10 -0
  24. data/lib/backup/configuration/encryptor/gpg.rb +17 -0
  25. data/lib/backup/configuration/encryptor/open_ssl.rb +26 -0
  26. data/lib/backup/configuration/helpers.rb +47 -17
  27. data/lib/backup/configuration/notifier/base.rb +39 -0
  28. data/lib/backup/configuration/notifier/mail.rb +52 -0
  29. data/lib/backup/configuration/storage/base.rb +18 -0
  30. data/lib/backup/configuration/storage/cloudfiles.rb +21 -0
  31. data/lib/backup/configuration/storage/dropbox.rb +25 -0
  32. data/lib/backup/configuration/storage/ftp.rb +25 -0
  33. data/lib/backup/configuration/storage/rsync.rb +25 -0
  34. data/lib/backup/configuration/storage/s3.rb +25 -0
  35. data/lib/backup/configuration/storage/scp.rb +25 -0
  36. data/lib/backup/configuration/storage/sftp.rb +25 -0
  37. data/lib/backup/database/base.rb +33 -0
  38. data/lib/backup/database/mongodb.rb +137 -0
  39. data/lib/backup/database/mysql.rb +104 -0
  40. data/lib/backup/database/postgresql.rb +111 -0
  41. data/lib/backup/database/redis.rb +105 -0
  42. data/lib/backup/encryptor/base.rb +17 -0
  43. data/lib/backup/encryptor/gpg.rb +78 -0
  44. data/lib/backup/encryptor/open_ssl.rb +67 -0
  45. data/lib/backup/finder.rb +39 -0
  46. data/lib/backup/logger.rb +80 -0
  47. data/lib/backup/model.rb +249 -0
  48. data/lib/backup/notifier/base.rb +29 -0
  49. data/lib/backup/notifier/binder.rb +32 -0
  50. data/lib/backup/notifier/mail.rb +141 -0
  51. data/lib/backup/notifier/templates/notify_failure.erb +31 -0
  52. data/lib/backup/notifier/templates/notify_success.erb +16 -0
  53. data/lib/backup/storage/base.rb +60 -3
  54. data/lib/backup/storage/cloudfiles.rb +85 -6
  55. data/lib/backup/storage/dropbox.rb +74 -4
  56. data/lib/backup/storage/ftp.rb +103 -27
  57. data/lib/backup/storage/object.rb +45 -0
  58. data/lib/backup/storage/rsync.rb +100 -0
  59. data/lib/backup/storage/s3.rb +100 -7
  60. data/lib/backup/storage/scp.rb +94 -19
  61. data/lib/backup/storage/sftp.rb +94 -19
  62. data/lib/backup/version.rb +70 -1
  63. data/lib/templates/archive +4 -0
  64. data/lib/templates/compressor/gzip +4 -0
  65. data/lib/templates/database/mongodb +10 -0
  66. data/lib/templates/database/mysql +11 -0
  67. data/lib/templates/database/postgresql +11 -0
  68. data/lib/templates/database/redis +10 -0
  69. data/lib/templates/encryptor/gpg +9 -0
  70. data/lib/templates/encryptor/openssl +5 -0
  71. data/lib/templates/notifier/mail +14 -0
  72. data/lib/templates/readme +15 -0
  73. data/lib/templates/storage/cloudfiles +7 -0
  74. data/lib/templates/storage/dropbox +8 -0
  75. data/lib/templates/storage/ftp +8 -0
  76. data/lib/templates/storage/rsync +7 -0
  77. data/lib/templates/storage/s3 +8 -0
  78. data/lib/templates/storage/scp +8 -0
  79. data/lib/templates/storage/sftp +8 -0
  80. data/spec/archive_spec.rb +53 -0
  81. data/spec/backup_spec.rb +11 -0
  82. data/spec/compressor/gzip_spec.rb +59 -0
  83. data/spec/configuration/base_spec.rb +35 -0
  84. data/spec/configuration/compressor/gzip_spec.rb +28 -0
  85. data/spec/configuration/database/base_spec.rb +16 -0
  86. data/spec/configuration/database/mongodb_spec.rb +30 -0
  87. data/spec/configuration/database/mysql_spec.rb +32 -0
  88. data/spec/configuration/database/postgresql_spec.rb +32 -0
  89. data/spec/configuration/database/redis_spec.rb +30 -0
  90. data/spec/configuration/encryptor/gpg_spec.rb +25 -0
  91. data/spec/configuration/encryptor/open_ssl_spec.rb +31 -0
  92. data/spec/configuration/notifier/mail_spec.rb +32 -0
  93. data/spec/configuration/storage/cloudfiles_spec.rb +34 -0
  94. data/spec/configuration/storage/dropbox_spec.rb +40 -0
  95. data/spec/configuration/storage/ftp_spec.rb +40 -0
  96. data/spec/configuration/storage/rsync_spec.rb +37 -0
  97. data/spec/configuration/storage/s3_spec.rb +37 -0
  98. data/spec/configuration/storage/scp_spec.rb +40 -0
  99. data/spec/configuration/storage/sftp_spec.rb +40 -0
  100. data/spec/database/base_spec.rb +30 -0
  101. data/spec/database/mongodb_spec.rb +144 -0
  102. data/spec/database/mysql_spec.rb +150 -0
  103. data/spec/database/postgresql_spec.rb +164 -0
  104. data/spec/database/redis_spec.rb +122 -0
  105. data/spec/encryptor/gpg_spec.rb +57 -0
  106. data/spec/encryptor/open_ssl_spec.rb +102 -0
  107. data/spec/logger_spec.rb +37 -0
  108. data/spec/model_spec.rb +236 -0
  109. data/spec/notifier/mail_spec.rb +97 -0
  110. data/spec/spec_helper.rb +21 -0
  111. data/spec/storage/base_spec.rb +33 -0
  112. data/spec/storage/cloudfiles_spec.rb +102 -0
  113. data/spec/storage/dropbox_spec.rb +89 -0
  114. data/spec/storage/ftp_spec.rb +133 -0
  115. data/spec/storage/object_spec.rb +74 -0
  116. data/spec/storage/rsync_spec.rb +115 -0
  117. data/spec/storage/s3_spec.rb +110 -0
  118. data/spec/storage/scp_spec.rb +129 -0
  119. data/spec/storage/sftp_spec.rb +125 -0
  120. data/spec/version_spec.rb +32 -0
  121. metadata +139 -123
  122. data/CHANGELOG +0 -131
  123. data/LICENSE +0 -20
  124. data/generators/backup/backup_generator.rb +0 -69
  125. data/generators/backup/templates/backup.rake +0 -56
  126. data/generators/backup/templates/backup.rb +0 -253
  127. data/generators/backup/templates/create_backup_tables.rb +0 -18
  128. data/generators/backup_update/backup_update_generator.rb +0 -50
  129. data/generators/backup_update/templates/migrations/update_backup_tables.rb +0 -27
  130. data/lib/backup/adapters/archive.rb +0 -34
  131. data/lib/backup/adapters/base.rb +0 -167
  132. data/lib/backup/adapters/custom.rb +0 -41
  133. data/lib/backup/adapters/mongo_db.rb +0 -139
  134. data/lib/backup/adapters/mysql.rb +0 -60
  135. data/lib/backup/adapters/postgresql.rb +0 -60
  136. data/lib/backup/adapters/sqlite.rb +0 -25
  137. data/lib/backup/command_helper.rb +0 -14
  138. data/lib/backup/configuration/adapter.rb +0 -21
  139. data/lib/backup/configuration/adapter_options.rb +0 -8
  140. data/lib/backup/configuration/attributes.rb +0 -19
  141. data/lib/backup/configuration/mail.rb +0 -20
  142. data/lib/backup/configuration/smtp.rb +0 -8
  143. data/lib/backup/configuration/storage.rb +0 -8
  144. data/lib/backup/connection/cloudfiles.rb +0 -75
  145. data/lib/backup/connection/dropbox.rb +0 -63
  146. data/lib/backup/connection/s3.rb +0 -88
  147. data/lib/backup/core_ext/object.rb +0 -5
  148. data/lib/backup/environment/base.rb +0 -12
  149. data/lib/backup/environment/rails_configuration.rb +0 -15
  150. data/lib/backup/environment/unix_configuration.rb +0 -109
  151. data/lib/backup/mail/base.rb +0 -97
  152. data/lib/backup/mail/mail.txt +0 -7
  153. data/lib/backup/record/base.rb +0 -65
  154. data/lib/backup/record/cloudfiles.rb +0 -28
  155. data/lib/backup/record/dropbox.rb +0 -27
  156. data/lib/backup/record/ftp.rb +0 -39
  157. data/lib/backup/record/local.rb +0 -26
  158. data/lib/backup/record/s3.rb +0 -25
  159. data/lib/backup/record/scp.rb +0 -33
  160. data/lib/backup/record/sftp.rb +0 -38
  161. data/lib/backup/storage/local.rb +0 -22
  162. data/lib/generators/backup/USAGE +0 -10
  163. data/lib/generators/backup/backup_generator.rb +0 -47
  164. data/lib/generators/backup/templates/backup.rake +0 -56
  165. data/lib/generators/backup/templates/backup.rb +0 -236
  166. data/lib/generators/backup/templates/create_backup_tables.rb +0 -18
  167. data/setup/backup.rb +0 -257
  168. data/setup/backup.sqlite3 +0 -0
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Encryptor
5
+ class Base
6
+ include Backup::CLI
7
+ include Backup::Configuration::Helpers
8
+
9
+ ##
10
+ # Logs a message to the console and log file to inform
11
+ # the client that Backup is encrypting the archive
12
+ def log!
13
+ Logger.message "#{ self.class } started encrypting the archive."
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ ##
4
+ # Require the tempfile Ruby library when Backup::Encryptor::GPG is loaded
5
+ require 'tempfile'
6
+
7
+ module Backup
8
+ module Encryptor
9
+ class GPG < Base
10
+
11
+ ##
12
+ # The GPG Public key that'll be used to encrypt the backup
13
+ attr_accessor :key
14
+
15
+ ##
16
+ # Contains the GPG encryption key id which'll be extracted from the public key file
17
+ attr_accessor :encryption_key_id
18
+
19
+ ##
20
+ # Contains the temporary file with the public key
21
+ attr_accessor :tmp_file
22
+
23
+ ##
24
+ # Creates a new instance of Backup::Encryptor::GPG and
25
+ # sets the key to the provided GPG key. To enhance the DSL
26
+ # the user may use tabs and spaces to indent the multi-line key string
27
+ # since we gsub() every preceding 'space' and 'tab' on each line
28
+ def initialize(&block)
29
+ load_defaults!
30
+
31
+ instance_eval(&block) if block_given?
32
+
33
+ @key = key.gsub(/^(\s|\t)+/, '')
34
+ end
35
+
36
+ ##
37
+ # Performs the encrypting of the backup file and will
38
+ # remove the unencrypted backup file, as well as the temp file
39
+ def perform!
40
+ log!
41
+ write_tmp_file!
42
+ extract_encryption_key_id!
43
+
44
+ run("#{ utility(:gpg) } #{ options } -o '#{ Backup::Model.file }.gpg' '#{ Backup::Model.file }'")
45
+
46
+ rm(Backup::Model.file)
47
+ tmp_file.unlink
48
+
49
+ Backup::Model.extension += '.gpg'
50
+ end
51
+
52
+ private
53
+
54
+ ##
55
+ # GPG options
56
+ # Sets the gpg mode to 'encrypt' and passes in the encryption_key_id
57
+ def options
58
+ "-e --trust-model always -r '#{ encryption_key_id }'"
59
+ end
60
+
61
+ ##
62
+ # Creates a new temp file and writes the provided public gpg key to it
63
+ def write_tmp_file!
64
+ @tmp_file = Tempfile.new('backup.pub')
65
+ @tmp_file.write(key)
66
+ @tmp_file.close
67
+ end
68
+
69
+ ##
70
+ # Extracts the 'encryption key id' from the '@tmp_file'
71
+ # and stores it in '@encryption_key_id'
72
+ def extract_encryption_key_id!
73
+ @encryption_key_id = run("#{ utility(:gpg) } --import '#{tmp_file.path}' 2>&1").match(/<(.+)>/)[1]
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Encryptor
5
+ class OpenSSL < Base
6
+
7
+ ##
8
+ # The password that'll be used to encrypt the backup. This
9
+ # password will be required to decrypt the backup later on.
10
+ attr_accessor :password
11
+
12
+ ##
13
+ # Determines whether the 'base64' should be used or not
14
+ attr_writer :base64
15
+
16
+ ##
17
+ # Determines whether the 'salt' flag should be used
18
+ attr_writer :salt
19
+
20
+ ##
21
+ # Creates a new instance of Backup::Encryptor::OpenSSL and
22
+ # sets the password attribute to what was provided
23
+ def initialize(&block)
24
+ load_defaults!
25
+
26
+ @base64 ||= false
27
+ @salt ||= false
28
+
29
+ instance_eval(&block) if block_given?
30
+ end
31
+
32
+ ##
33
+ # Performs the encryption of the backup file
34
+ def perform!
35
+ log!
36
+ run("#{ utility(:openssl) } #{ options } -in '#{ Backup::Model.file }' -out '#{ Backup::Model.file }.enc' -k '#{ password }'")
37
+ rm(Backup::Model.file)
38
+ Backup::Model.extension += '.enc'
39
+ end
40
+
41
+ private
42
+
43
+ ##
44
+ # Backup::Encryptor::OpenSSL uses the 256bit AES encryption cipher.
45
+ # 256bit AES is what the US Government uses to encrypt information at the "Top Secret" level.
46
+ def options
47
+ (['aes-256-cbc'] + base64 + salt).join("\s")
48
+ end
49
+
50
+ ##
51
+ # Returns '-a' if @base64 is set to 'true'.
52
+ # This option will make the encrypted output base64 encoded,
53
+ # this makes the encrypted file readable using text editors
54
+ def base64
55
+ return ['-base64'] if @base64; []
56
+ end
57
+
58
+ ##
59
+ # Returns '-salt' if @salt is set to 'true'.
60
+ # This options adds strength to the encryption
61
+ def salt
62
+ return ['-salt'] if @salt; []
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ class Finder
5
+ attr_accessor :trigger, :config
6
+
7
+ ##
8
+ # Initializes a new Backup::Finder object
9
+ # and stores the path to the configuration file
10
+ def initialize(trigger, config)
11
+ @trigger = trigger.to_sym
12
+ @config = config
13
+ end
14
+
15
+ ##
16
+ # Tries to find and load the configuration file and return the proper
17
+ # backup model configuration (specified by the 'trigger')
18
+ def find
19
+ unless File.exist?(config)
20
+ puts "Could not find a configuration file in '#{config}'."; exit
21
+ end
22
+
23
+ ##
24
+ # Loads the backup configuration file
25
+ instance_eval(File.read(config))
26
+
27
+ ##
28
+ # Iterates through all the instantiated backup models and returns
29
+ # the one that matches the specified 'trigger'
30
+ Backup::Model.all.each do |model|
31
+ if model.trigger.eql?(trigger)
32
+ return Backup::Model.current = model
33
+ end
34
+ end
35
+
36
+ puts "Could not find trigger '#{trigger}' in '#{config}'."; exit
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ class Logger
5
+
6
+ ##
7
+ # Outputs a messages to the console and writes it to the backup.log
8
+ def self.message(string)
9
+ puts loggify(:message, string, :green)
10
+ to_file loggify(:message, string)
11
+ end
12
+
13
+ ##
14
+ # Outputs an error to the console and writes it to the backup.log
15
+ def self.error(string)
16
+ puts loggify(:error, string, :red)
17
+ to_file loggify(:error, string)
18
+ end
19
+
20
+ ##
21
+ # Outputs a notice to the console and writes it to the backup.log
22
+ def self.warn(string)
23
+ puts loggify(:warning, string, :yellow)
24
+ to_file loggify(:warning, string)
25
+ end
26
+
27
+ ##
28
+ # Returns the time in [YYYY/MM/DD HH:MM:SS] format
29
+ def self.time
30
+ Time.now.strftime("%Y/%m/%d %H:%M:%S")
31
+ end
32
+
33
+ ##
34
+ # Builds the string in a log format with the date/time, the type (colorized)
35
+ # based on whether it's a message, notice or error, and the message itself.
36
+ # ANSI color codes are only used in the console, and are not written to the log
37
+ # since it doesn't do anything and just adds more unnecessary bloat to the log file
38
+ def self.loggify(type, string, color = false)
39
+ return "[#{time}][#{type}] #{string}" unless color
40
+ "[#{time}][#{send(color, type)}] #{string}"
41
+ end
42
+
43
+ ##
44
+ # Writes (appends) a string to the backup.log file
45
+ def self.to_file(string)
46
+ File.open(File.join(LOG_PATH, 'backup.log'), 'a') do |file|
47
+ file.write("#{string}\n")
48
+ end
49
+ end
50
+
51
+ ##
52
+ # Invokes the #colorize method with the provided string
53
+ # and the color code "32" (for green)
54
+ def self.green(string)
55
+ colorize(string, 32)
56
+ end
57
+
58
+ ##
59
+ # Invokes the #colorize method with the provided string
60
+ # and the color code "33" (for yellow)
61
+ def self.yellow(string)
62
+ colorize(string, 33)
63
+ end
64
+
65
+ ##
66
+ # Invokes the #colorize method the with provided string
67
+ # and the color code "31" (for red)
68
+ def self.red(string)
69
+ colorize(string, 31)
70
+ end
71
+
72
+ ##
73
+ # Wraps the provided string in colorizing tags to provide
74
+ # easier to view output to the client
75
+ def self.colorize(string, code)
76
+ "\e[#{code}m#{string}\e[0m"
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,249 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ class Model
5
+ include Backup::CLI
6
+
7
+ ##
8
+ # The trigger is used as an identifier for
9
+ # initializing the backup process
10
+ attr_accessor :trigger
11
+
12
+ ##
13
+ # The label is used for a more friendly user output
14
+ attr_accessor :label
15
+
16
+ ##
17
+ # The databases attribute holds an array of database objects
18
+ attr_accessor :databases
19
+
20
+ ##
21
+ # The archives attr_accessor holds an array of archive objects
22
+ attr_accessor :archives
23
+
24
+ ##
25
+ # The encryptors attr_accessor holds an array of encryptor objects
26
+ attr_accessor :encryptors
27
+
28
+ ##
29
+ # The compressors attr_accessor holds an array of compressor objects
30
+ attr_accessor :compressors
31
+
32
+ ##
33
+ # The notifiers attr_accessor holds an array of notifier objects
34
+ attr_accessor :notifiers
35
+
36
+ ##
37
+ # The storages attribute holds an array of storage objects
38
+ attr_accessor :storages
39
+
40
+ ##
41
+ # The time when the backup initiated (in format: 2011.02.20.03.29.59)
42
+ attr_accessor :time
43
+
44
+ class << self
45
+ ##
46
+ # The Backup::Model.all class method keeps track of all the models
47
+ # that have been instantiated. It returns the @all class variable,
48
+ # which contains an array of all the models
49
+ attr_accessor :all
50
+
51
+ ##
52
+ # Contains the current file extension (this changes from time to time after a file
53
+ # gets compressed or encrypted so we can keep track of the correct file when new
54
+ # extensions get appended to the current file name)
55
+ attr_accessor :extension
56
+
57
+ ##
58
+ # Contains the currently-in-use model. This attribute should get set by Backup::Finder.
59
+ # Use Backup::Model.current to retrieve the actual data of the model
60
+ attr_accessor :current
61
+
62
+ ##
63
+ # Returns the full path to the current file (including the current extension).
64
+ # To just return the filename and extension without the path, use File.basename(Backup::Model.file)
65
+ def file
66
+ File.join(TMP_PATH, "#{ TIME }.#{ TRIGGER }.#{ Backup::Model.extension }")
67
+ end
68
+
69
+ ##
70
+ # Returns the temporary trigger path of the current model
71
+ # e.g. /Users/Michael/tmp/backup/my_trigger
72
+ def tmp_path
73
+ File.join(TMP_PATH, TRIGGER)
74
+ end
75
+ end
76
+
77
+ ##
78
+ # Accessible through "Backup::Model.all", it stores an array of Backup::Model instances.
79
+ # Everytime a new Backup::Model gets instantiated it gets pushed into this array
80
+ @all = Array.new
81
+
82
+ ##
83
+ # Contains the current file extension (should change after each compression or encryption)
84
+ @extension = 'tar'
85
+
86
+ ##
87
+ # Takes a trigger, label and the configuration block and instantiates the model.
88
+ # The TIME (time of execution) gets stored in the @time attribute.
89
+ # After the instance has evaluated the configuration block and properly set the
90
+ # configuration for the model, it will append the newly created "model" instance
91
+ # to the @all class variable (Array) so it can be accessed by Backup::Finder
92
+ # and any other location
93
+ def initialize(trigger, label, &block)
94
+ @trigger = trigger
95
+ @label = label
96
+ @time = TIME
97
+
98
+ @databases = Array.new
99
+ @archives = Array.new
100
+ @encryptors = Array.new
101
+ @compressors = Array.new
102
+ @storages = Array.new
103
+ @notifiers = Array.new
104
+
105
+ instance_eval(&block)
106
+ Backup::Model.all << self
107
+ end
108
+
109
+ ##
110
+ # Adds a database to the array of databases
111
+ # to dump during the backup process
112
+ def database(database, &block)
113
+ @databases << Backup::Database.const_get(
114
+ last_constant(database)
115
+ ).new(&block)
116
+ end
117
+
118
+ ##
119
+ # Adds an archive to the array of archives
120
+ # to store during the backup process
121
+ def archive(name, &block)
122
+ @archives << Backup::Archive.new(name, &block)
123
+ end
124
+
125
+ ##
126
+ # Adds an encryptor to the array of encryptors
127
+ # to use during the backup process
128
+ def encrypt_with(name, &block)
129
+ @encryptors << Backup::Encryptor.const_get(
130
+ last_constant(name)
131
+ ).new(&block)
132
+ end
133
+
134
+ ##
135
+ # Adds a compressor to the array of compressors
136
+ # to use during the backup process
137
+ def compress_with(name, &block)
138
+ @compressors << Backup::Compressor.const_get(
139
+ last_constant(name)
140
+ ).new(&block)
141
+ end
142
+
143
+ ##
144
+ # Adds a notifier to the array of notifiers
145
+ # to use during the backup process
146
+ def notify_by(name, &block)
147
+ @notifiers << Backup::Notifier.const_get(
148
+ last_constant(name)
149
+ ).new(&block)
150
+ end
151
+
152
+ ##
153
+ # Adds a storage method to the array of storage
154
+ # methods to use during the backup process
155
+ def store_with(storage, &block)
156
+ @storages << Backup::Storage.const_get(
157
+ last_constant(storage)
158
+ ).new(&block)
159
+ end
160
+
161
+ ##
162
+ # Performs the backup process
163
+ ##
164
+ # [Databases]
165
+ # Runs all (if any) database objects to dump the databases
166
+ ##
167
+ # [Archives]
168
+ # Runs all (if any) archive objects to package all their
169
+ # paths in to a single tar file and places it in the backup folder
170
+ ##
171
+ # [Package]
172
+ # After all the database dumps and archives are placed inside
173
+ # the folder, it'll make a single .tar package (archive) out of it
174
+ ##
175
+ # [Encryption]
176
+ # Optionally encrypts the packaged file with one or more encryptors
177
+ ##
178
+ # [Compression]
179
+ # Optionally compresses the packaged file with one or more compressors
180
+ ##
181
+ # [Storages]
182
+ # Runs all (if any) storage objects to store the backups to remote locations
183
+ # and (if configured) it'll cycle the files on the remote location to limit the
184
+ # amount of backups stored on each individual location
185
+ ##
186
+ # [Notifiers]
187
+ # Runs all (if any) notifier objects when a backup proces finished with or without
188
+ # any errors.
189
+ ##
190
+ # [Cleaning]
191
+ # After the whole backup process finishes, it'll go ahead and remove any temporary
192
+ # file that it produced. If an exception(error) is raised during this process which
193
+ # breaks the process, it'll always ensure it removes the temporary files regardless
194
+ # to avoid mass consumption of storage space on the machine
195
+ def perform!
196
+ begin
197
+ databases.each { |d| d.perform! }
198
+ archives.each { |a| a.perform! }
199
+ package!
200
+ encryptors.each { |e| e.perform! }
201
+ compressors.each { |c| c.perform! }
202
+ storages.each { |s| s.perform! }
203
+ notifiers.each { |n| n.perform!(self) }
204
+ clean!
205
+ rescue Exception => exception
206
+ clean!
207
+ notifiers.each { |n| n.perform!(self, exception) }
208
+ show_exception!(exception)
209
+ end
210
+ end
211
+
212
+ private
213
+
214
+ ##
215
+ # After all the databases and archives have been dumped and sorted,
216
+ # these files will be bundled in to a .tar archive (uncompressed) so it
217
+ # becomes a single (transferrable) packaged file.
218
+ def package!
219
+ Logger.message "Backup started packaging everything to a single archive file."
220
+ run("#{ utility(:tar) } -c -C '#{ TMP_PATH }' '#{ TRIGGER }' > '#{ File.join(TMP_PATH, "#{TIME}.#{TRIGGER}.tar") }'")
221
+ end
222
+
223
+ ##
224
+ # Cleans up the temporary files that were created after the backup process finishes
225
+ def clean!
226
+ Logger.message "Backup started cleaning up the temporary files."
227
+ run("#{ utility(:rm) } -rf '#{ File.join(TMP_PATH, TRIGGER) }' '#{ File.join(TMP_PATH, "#{TIME}.#{TRIGGER}.#{Backup::Model.extension}") }'")
228
+ end
229
+
230
+ ##
231
+ # Returns the string representation of the last value of a nested constant
232
+ # example:
233
+ # Backup::Model::MySQL
234
+ # becomes and returns:
235
+ # "MySQL"
236
+ def last_constant(constant)
237
+ constant.to_s.split("::").last
238
+ end
239
+
240
+ ##
241
+ # Formats an exception
242
+ def show_exception!(exception)
243
+ puts ("=" * 75) + "\nException that got raised:\n#{exception}\n" + ("=" * 75) + "\n" + exception.backtrace.join("\n")
244
+ puts ("=" * 75) + "\n\nYou are running Backup version \"#{Backup::Version.current}\" and Ruby version \"#{ENV['RUBY_VERSION']}\".\n"
245
+ puts "If you've setup a \"Notification\" in your configuration file, the above error will have been sent."
246
+ end
247
+
248
+ end
249
+ end