backup_checksum 3.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +10 -0
  3. data/Gemfile +28 -0
  4. data/Gemfile.lock +130 -0
  5. data/Guardfile +21 -0
  6. data/LICENSE.md +24 -0
  7. data/README.md +476 -0
  8. data/backup_checksum.gemspec +32 -0
  9. data/bin/backup +11 -0
  10. data/lib/backup.rb +217 -0
  11. data/lib/backup/archive.rb +117 -0
  12. data/lib/backup/binder.rb +22 -0
  13. data/lib/backup/checksum/base.rb +44 -0
  14. data/lib/backup/checksum/shasum.rb +16 -0
  15. data/lib/backup/cleaner.rb +121 -0
  16. data/lib/backup/cli/helpers.rb +88 -0
  17. data/lib/backup/cli/utility.rb +247 -0
  18. data/lib/backup/compressor/base.rb +29 -0
  19. data/lib/backup/compressor/bzip2.rb +50 -0
  20. data/lib/backup/compressor/gzip.rb +47 -0
  21. data/lib/backup/compressor/lzma.rb +50 -0
  22. data/lib/backup/compressor/pbzip2.rb +56 -0
  23. data/lib/backup/config.rb +173 -0
  24. data/lib/backup/configuration/base.rb +15 -0
  25. data/lib/backup/configuration/checksum/base.rb +9 -0
  26. data/lib/backup/configuration/checksum/shasum.rb +9 -0
  27. data/lib/backup/configuration/compressor/base.rb +9 -0
  28. data/lib/backup/configuration/compressor/bzip2.rb +23 -0
  29. data/lib/backup/configuration/compressor/gzip.rb +23 -0
  30. data/lib/backup/configuration/compressor/lzma.rb +23 -0
  31. data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
  32. data/lib/backup/configuration/database/base.rb +19 -0
  33. data/lib/backup/configuration/database/mongodb.rb +49 -0
  34. data/lib/backup/configuration/database/mysql.rb +42 -0
  35. data/lib/backup/configuration/database/postgresql.rb +41 -0
  36. data/lib/backup/configuration/database/redis.rb +39 -0
  37. data/lib/backup/configuration/database/riak.rb +29 -0
  38. data/lib/backup/configuration/encryptor/base.rb +9 -0
  39. data/lib/backup/configuration/encryptor/gpg.rb +17 -0
  40. data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
  41. data/lib/backup/configuration/helpers.rb +52 -0
  42. data/lib/backup/configuration/notifier/base.rb +28 -0
  43. data/lib/backup/configuration/notifier/campfire.rb +25 -0
  44. data/lib/backup/configuration/notifier/hipchat.rb +41 -0
  45. data/lib/backup/configuration/notifier/mail.rb +112 -0
  46. data/lib/backup/configuration/notifier/presently.rb +25 -0
  47. data/lib/backup/configuration/notifier/prowl.rb +23 -0
  48. data/lib/backup/configuration/notifier/twitter.rb +21 -0
  49. data/lib/backup/configuration/storage/base.rb +18 -0
  50. data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
  51. data/lib/backup/configuration/storage/dropbox.rb +58 -0
  52. data/lib/backup/configuration/storage/ftp.rb +29 -0
  53. data/lib/backup/configuration/storage/local.rb +17 -0
  54. data/lib/backup/configuration/storage/ninefold.rb +20 -0
  55. data/lib/backup/configuration/storage/rsync.rb +29 -0
  56. data/lib/backup/configuration/storage/s3.rb +25 -0
  57. data/lib/backup/configuration/storage/scp.rb +25 -0
  58. data/lib/backup/configuration/storage/sftp.rb +25 -0
  59. data/lib/backup/configuration/syncer/base.rb +10 -0
  60. data/lib/backup/configuration/syncer/cloud.rb +23 -0
  61. data/lib/backup/configuration/syncer/cloud_files.rb +30 -0
  62. data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
  63. data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
  64. data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
  65. data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
  66. data/lib/backup/configuration/syncer/s3.rb +23 -0
  67. data/lib/backup/database/base.rb +59 -0
  68. data/lib/backup/database/mongodb.rb +232 -0
  69. data/lib/backup/database/mysql.rb +163 -0
  70. data/lib/backup/database/postgresql.rb +146 -0
  71. data/lib/backup/database/redis.rb +139 -0
  72. data/lib/backup/database/riak.rb +69 -0
  73. data/lib/backup/dependency.rb +114 -0
  74. data/lib/backup/encryptor/base.rb +29 -0
  75. data/lib/backup/encryptor/gpg.rb +80 -0
  76. data/lib/backup/encryptor/open_ssl.rb +72 -0
  77. data/lib/backup/errors.rb +124 -0
  78. data/lib/backup/logger.rb +152 -0
  79. data/lib/backup/model.rb +386 -0
  80. data/lib/backup/notifier/base.rb +81 -0
  81. data/lib/backup/notifier/campfire.rb +168 -0
  82. data/lib/backup/notifier/hipchat.rb +99 -0
  83. data/lib/backup/notifier/mail.rb +206 -0
  84. data/lib/backup/notifier/presently.rb +88 -0
  85. data/lib/backup/notifier/prowl.rb +65 -0
  86. data/lib/backup/notifier/twitter.rb +70 -0
  87. data/lib/backup/package.rb +51 -0
  88. data/lib/backup/packager.rb +108 -0
  89. data/lib/backup/pipeline.rb +107 -0
  90. data/lib/backup/splitter.rb +75 -0
  91. data/lib/backup/storage/base.rb +119 -0
  92. data/lib/backup/storage/cloudfiles.rb +87 -0
  93. data/lib/backup/storage/cycler.rb +117 -0
  94. data/lib/backup/storage/dropbox.rb +181 -0
  95. data/lib/backup/storage/ftp.rb +119 -0
  96. data/lib/backup/storage/local.rb +82 -0
  97. data/lib/backup/storage/ninefold.rb +116 -0
  98. data/lib/backup/storage/rsync.rb +149 -0
  99. data/lib/backup/storage/s3.rb +94 -0
  100. data/lib/backup/storage/scp.rb +99 -0
  101. data/lib/backup/storage/sftp.rb +108 -0
  102. data/lib/backup/syncer/base.rb +42 -0
  103. data/lib/backup/syncer/cloud.rb +190 -0
  104. data/lib/backup/syncer/cloud_files.rb +56 -0
  105. data/lib/backup/syncer/rsync/base.rb +52 -0
  106. data/lib/backup/syncer/rsync/local.rb +53 -0
  107. data/lib/backup/syncer/rsync/pull.rb +38 -0
  108. data/lib/backup/syncer/rsync/push.rb +113 -0
  109. data/lib/backup/syncer/s3.rb +47 -0
  110. data/lib/backup/template.rb +46 -0
  111. data/lib/backup/version.rb +43 -0
  112. data/spec/archive_spec.rb +335 -0
  113. data/spec/cleaner_spec.rb +304 -0
  114. data/spec/cli/helpers_spec.rb +176 -0
  115. data/spec/cli/utility_spec.rb +363 -0
  116. data/spec/compressor/base_spec.rb +31 -0
  117. data/spec/compressor/bzip2_spec.rb +83 -0
  118. data/spec/compressor/gzip_spec.rb +83 -0
  119. data/spec/compressor/lzma_spec.rb +83 -0
  120. data/spec/compressor/pbzip2_spec.rb +124 -0
  121. data/spec/config_spec.rb +321 -0
  122. data/spec/configuration/base_spec.rb +35 -0
  123. data/spec/configuration/compressor/bzip2_spec.rb +29 -0
  124. data/spec/configuration/compressor/gzip_spec.rb +29 -0
  125. data/spec/configuration/compressor/lzma_spec.rb +29 -0
  126. data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
  127. data/spec/configuration/database/base_spec.rb +17 -0
  128. data/spec/configuration/database/mongodb_spec.rb +56 -0
  129. data/spec/configuration/database/mysql_spec.rb +53 -0
  130. data/spec/configuration/database/postgresql_spec.rb +53 -0
  131. data/spec/configuration/database/redis_spec.rb +50 -0
  132. data/spec/configuration/database/riak_spec.rb +35 -0
  133. data/spec/configuration/encryptor/gpg_spec.rb +26 -0
  134. data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
  135. data/spec/configuration/notifier/base_spec.rb +32 -0
  136. data/spec/configuration/notifier/campfire_spec.rb +32 -0
  137. data/spec/configuration/notifier/hipchat_spec.rb +44 -0
  138. data/spec/configuration/notifier/mail_spec.rb +71 -0
  139. data/spec/configuration/notifier/presently_spec.rb +35 -0
  140. data/spec/configuration/notifier/prowl_spec.rb +29 -0
  141. data/spec/configuration/notifier/twitter_spec.rb +35 -0
  142. data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
  143. data/spec/configuration/storage/dropbox_spec.rb +38 -0
  144. data/spec/configuration/storage/ftp_spec.rb +44 -0
  145. data/spec/configuration/storage/local_spec.rb +29 -0
  146. data/spec/configuration/storage/ninefold_spec.rb +32 -0
  147. data/spec/configuration/storage/rsync_spec.rb +41 -0
  148. data/spec/configuration/storage/s3_spec.rb +38 -0
  149. data/spec/configuration/storage/scp_spec.rb +41 -0
  150. data/spec/configuration/storage/sftp_spec.rb +41 -0
  151. data/spec/configuration/syncer/cloud_files_spec.rb +44 -0
  152. data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
  153. data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
  154. data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
  155. data/spec/configuration/syncer/rsync/push_spec.rb +43 -0
  156. data/spec/configuration/syncer/s3_spec.rb +38 -0
  157. data/spec/database/base_spec.rb +54 -0
  158. data/spec/database/mongodb_spec.rb +428 -0
  159. data/spec/database/mysql_spec.rb +335 -0
  160. data/spec/database/postgresql_spec.rb +278 -0
  161. data/spec/database/redis_spec.rb +260 -0
  162. data/spec/database/riak_spec.rb +108 -0
  163. data/spec/dependency_spec.rb +49 -0
  164. data/spec/encryptor/base_spec.rb +30 -0
  165. data/spec/encryptor/gpg_spec.rb +134 -0
  166. data/spec/encryptor/open_ssl_spec.rb +129 -0
  167. data/spec/errors_spec.rb +306 -0
  168. data/spec/logger_spec.rb +363 -0
  169. data/spec/model_spec.rb +649 -0
  170. data/spec/notifier/base_spec.rb +89 -0
  171. data/spec/notifier/campfire_spec.rb +199 -0
  172. data/spec/notifier/hipchat_spec.rb +188 -0
  173. data/spec/notifier/mail_spec.rb +280 -0
  174. data/spec/notifier/presently_spec.rb +181 -0
  175. data/spec/notifier/prowl_spec.rb +117 -0
  176. data/spec/notifier/twitter_spec.rb +132 -0
  177. data/spec/package_spec.rb +61 -0
  178. data/spec/packager_spec.rb +225 -0
  179. data/spec/pipeline_spec.rb +257 -0
  180. data/spec/spec_helper.rb +59 -0
  181. data/spec/splitter_spec.rb +120 -0
  182. data/spec/storage/base_spec.rb +160 -0
  183. data/spec/storage/cloudfiles_spec.rb +230 -0
  184. data/spec/storage/cycler_spec.rb +239 -0
  185. data/spec/storage/dropbox_spec.rb +370 -0
  186. data/spec/storage/ftp_spec.rb +247 -0
  187. data/spec/storage/local_spec.rb +235 -0
  188. data/spec/storage/ninefold_spec.rb +319 -0
  189. data/spec/storage/rsync_spec.rb +345 -0
  190. data/spec/storage/s3_spec.rb +221 -0
  191. data/spec/storage/scp_spec.rb +209 -0
  192. data/spec/storage/sftp_spec.rb +220 -0
  193. data/spec/syncer/base_spec.rb +22 -0
  194. data/spec/syncer/cloud_files_spec.rb +192 -0
  195. data/spec/syncer/rsync/base_spec.rb +118 -0
  196. data/spec/syncer/rsync/local_spec.rb +121 -0
  197. data/spec/syncer/rsync/pull_spec.rb +90 -0
  198. data/spec/syncer/rsync/push_spec.rb +327 -0
  199. data/spec/syncer/s3_spec.rb +192 -0
  200. data/spec/version_spec.rb +21 -0
  201. data/templates/cli/utility/archive +25 -0
  202. data/templates/cli/utility/compressor/bzip2 +7 -0
  203. data/templates/cli/utility/compressor/gzip +7 -0
  204. data/templates/cli/utility/compressor/lzma +7 -0
  205. data/templates/cli/utility/compressor/pbzip2 +7 -0
  206. data/templates/cli/utility/config +31 -0
  207. data/templates/cli/utility/database/mongodb +18 -0
  208. data/templates/cli/utility/database/mysql +21 -0
  209. data/templates/cli/utility/database/postgresql +17 -0
  210. data/templates/cli/utility/database/redis +16 -0
  211. data/templates/cli/utility/database/riak +11 -0
  212. data/templates/cli/utility/encryptor/gpg +12 -0
  213. data/templates/cli/utility/encryptor/openssl +9 -0
  214. data/templates/cli/utility/model.erb +23 -0
  215. data/templates/cli/utility/notifier/campfire +12 -0
  216. data/templates/cli/utility/notifier/hipchat +15 -0
  217. data/templates/cli/utility/notifier/mail +22 -0
  218. data/templates/cli/utility/notifier/presently +13 -0
  219. data/templates/cli/utility/notifier/prowl +11 -0
  220. data/templates/cli/utility/notifier/twitter +13 -0
  221. data/templates/cli/utility/splitter +7 -0
  222. data/templates/cli/utility/storage/cloud_files +22 -0
  223. data/templates/cli/utility/storage/dropbox +20 -0
  224. data/templates/cli/utility/storage/ftp +12 -0
  225. data/templates/cli/utility/storage/local +7 -0
  226. data/templates/cli/utility/storage/ninefold +9 -0
  227. data/templates/cli/utility/storage/rsync +11 -0
  228. data/templates/cli/utility/storage/s3 +19 -0
  229. data/templates/cli/utility/storage/scp +11 -0
  230. data/templates/cli/utility/storage/sftp +11 -0
  231. data/templates/cli/utility/syncer/cloud_files +48 -0
  232. data/templates/cli/utility/syncer/rsync_local +12 -0
  233. data/templates/cli/utility/syncer/rsync_pull +17 -0
  234. data/templates/cli/utility/syncer/rsync_push +17 -0
  235. data/templates/cli/utility/syncer/s3 +45 -0
  236. data/templates/general/links +11 -0
  237. data/templates/general/version.erb +2 -0
  238. data/templates/notifier/mail/failure.erb +9 -0
  239. data/templates/notifier/mail/success.erb +7 -0
  240. data/templates/notifier/mail/warning.erb +9 -0
  241. data/templates/storage/dropbox/authorization_url.erb +6 -0
  242. data/templates/storage/dropbox/authorized.erb +4 -0
  243. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  244. metadata +311 -0
@@ -0,0 +1,114 @@
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 => '>= 0.11.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.1.4',
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.7.4',
63
+ :for => 'Sending Http Updates'
64
+ },
65
+
66
+ 'json' => {
67
+ :require => 'json',
68
+ :version => '~> 1.5.1',
69
+ :for => 'Parsing JSON for HTTParty'
70
+ },
71
+
72
+ 'prowler' => {
73
+ :require => 'prowler',
74
+ :version => '>= 1.3.1',
75
+ :for => 'Sending iOS push notifications (Prowl Notifier)'
76
+ },
77
+
78
+ 'hipchat' => {
79
+ :require => 'hipchat',
80
+ :version => '~> 0.4.1',
81
+ :for => 'Sending notifications to Hipchat'
82
+ },
83
+
84
+ 'parallel' => {
85
+ :require => 'parallel',
86
+ :version => '~> 0.5.12',
87
+ :for => 'Adding concurrency to Cloud-based syncers.'
88
+ }
89
+ }
90
+ end
91
+
92
+ ##
93
+ # Attempts to load the specified gem (by name and version).
94
+ # If the gem with the correct version cannot be found, it'll display a message
95
+ # to the user with instructions on how to install the required gem
96
+ def self.load(name)
97
+ begin
98
+ gem(name, all[name][:version])
99
+ require(all[name][:require])
100
+ rescue LoadError
101
+ Logger.error Errors::Dependency::LoadError.new(<<-EOS)
102
+ Dependency missing
103
+ Dependency required for:
104
+ #{all[name][:for]}
105
+ To install the gem, issue the following command:
106
+ > gem install #{name} -v '#{all[name][:version]}'
107
+ Please try again after installing the missing dependency.
108
+ EOS
109
+ exit 1
110
+ end
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Encryptor
5
+ class Base
6
+ include Backup::CLI::Helpers
7
+ include Backup::Configuration::Helpers
8
+
9
+ def initialize
10
+ load_defaults!
11
+ end
12
+
13
+ private
14
+
15
+ ##
16
+ # Return the encryptor name, with Backup namespace removed
17
+ def encryptor_name
18
+ self.class.to_s.sub('Backup::', '')
19
+ end
20
+
21
+ ##
22
+ # Logs a message to the console and log file to inform
23
+ # the client that Backup is encrypting the archive
24
+ def log!
25
+ Logger.message "Using #{ encryptor_name } to encrypt the archive."
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Encryptor
5
+ class GPG < Base
6
+
7
+ ##
8
+ # The GPG Public key that'll be used to encrypt the backup
9
+ attr_accessor :key
10
+
11
+ ##
12
+ # Creates a new instance of Backup::Encryptor::GPG and
13
+ # sets the key to the provided GPG key. To enhance the DSL
14
+ # the user may use tabs and spaces to indent the multi-line key string
15
+ # since we gsub() every preceding 'space' and 'tab' on each line
16
+ def initialize(&block)
17
+ super
18
+
19
+ instance_eval(&block) if block_given?
20
+ end
21
+
22
+ ##
23
+ # This is called as part of the procedure run by the Packager.
24
+ # It sets up the needed encryption_key_email to pass to the gpg command,
25
+ # then yields the command to use as part of the packaging procedure.
26
+ # Once the packaging procedure is complete, it will return
27
+ # so that any clean-up may be performed after the yield.
28
+ def encrypt_with
29
+ log!
30
+ extract_encryption_key_email!
31
+
32
+ yield "#{ utility(:gpg) } #{ options }", '.gpg'
33
+ end
34
+
35
+ private
36
+
37
+ ##
38
+ # Imports the given encryption key to ensure it's available for use,
39
+ # and extracts the email address used to create the key.
40
+ # This is stored in '@encryption_key_email', to be used to specify
41
+ # the --recipient when performing encryption so this key is used.
42
+ def extract_encryption_key_email!
43
+ if @encryption_key_email.to_s.empty?
44
+ with_tmp_key_file do |tmp_file|
45
+ @encryption_key_email = run(
46
+ "#{ utility(:gpg) } --import '#{tmp_file}' 2>&1"
47
+ ).match(/<(.+)>/)[1]
48
+ end
49
+ end
50
+ end
51
+
52
+ ##
53
+ # GPG options
54
+ # Sets the gpg mode to 'encrypt' and passes in the encryption_key_email
55
+ def options
56
+ "-e --trust-model always -r '#{ @encryption_key_email }'"
57
+ end
58
+
59
+ ##
60
+ # Writes the provided public gpg key to a temp file,
61
+ # yields the path, then deletes the file when the block returns.
62
+ def with_tmp_key_file
63
+ tmp_file = Tempfile.new('backup.pub')
64
+ FileUtils.chown(Config.user, nil, tmp_file.path)
65
+ FileUtils.chmod(0600, tmp_file.path)
66
+ tmp_file.write(encryption_key)
67
+ tmp_file.close
68
+ yield tmp_file.path
69
+ tmp_file.delete
70
+ end
71
+
72
+ ##
73
+ # Returns the encryption key with preceding spaces and tabs removed
74
+ def encryption_key
75
+ key.gsub(/^[[:blank:]]+/, '')
76
+ end
77
+
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,72 @@
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
+ # The password file to use to encrypt the backup.
14
+ attr_accessor :password_file
15
+
16
+ ##
17
+ # Determines whether the 'base64' should be used or not
18
+ attr_accessor :base64
19
+
20
+ ##
21
+ # Determines whether the 'salt' flag should be used
22
+ attr_accessor :salt
23
+
24
+ ##
25
+ # Creates a new instance of Backup::Encryptor::OpenSSL and
26
+ # sets the password attribute to what was provided
27
+ def initialize(&block)
28
+ super
29
+
30
+ @base64 ||= false
31
+ @salt ||= true
32
+ @password_file ||= nil
33
+
34
+ instance_eval(&block) if block_given?
35
+ end
36
+
37
+ ##
38
+ # This is called as part of the procedure run by the Packager.
39
+ # It sets up the needed options to pass to the openssl command,
40
+ # then yields the command to use as part of the packaging procedure.
41
+ # Once the packaging procedure is complete, it will return
42
+ # so that any clean-up may be performed after the yield.
43
+ def encrypt_with
44
+ log!
45
+ yield "#{ utility(:openssl) } #{ options }", '.enc'
46
+ end
47
+
48
+ private
49
+
50
+ ##
51
+ # Uses the 256bit AES encryption cipher, which is what the
52
+ # US Government uses to encrypt information at the "Top Secret" level.
53
+ #
54
+ # The -base64 option will make the encrypted output base64 encoded,
55
+ # this makes the encrypted file readable using text editors
56
+ #
57
+ # The -salt option adds strength to the encryption
58
+ #
59
+ # Always sets a password option, if even no password is given,
60
+ # but will prefer the password_file option if both are given.
61
+ def options
62
+ opts = ['aes-256-cbc']
63
+ opts << '-base64' if @base64
64
+ opts << '-salt' if @salt
65
+ opts << ( @password_file.to_s.empty? ?
66
+ "-k '#{@password}'" : "-pass file:#{@password_file}" )
67
+ opts.join(' ')
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,124 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ ##
5
+ # - automatically defines module namespaces referenced under Backup::Errors
6
+ # - any constant name referenced that ends with 'Error' will be created
7
+ # as a subclass of Backup::Errors::Error
8
+ # e.g.
9
+ # err = Backup::Errors::Foo::Bar::FooError.new('error message')
10
+ # err.message => "Foo::Bar::FooError: error message"
11
+ #
12
+ module ErrorsHelper
13
+ def const_missing(const)
14
+ if const.to_s.end_with?('Error')
15
+ module_eval("class #{const} < Backup::Errors::Error; end")
16
+ else
17
+ module_eval("module #{const}; extend Backup::ErrorsHelper; end")
18
+ end
19
+ const_get(const)
20
+ end
21
+ end
22
+
23
+ ##
24
+ # provides cascading errors with formatted messages
25
+ # see the specs for details
26
+ #
27
+ # e.g.
28
+ # module Backup
29
+ # begin
30
+ # begin
31
+ # begin
32
+ # raise Errors::ZoneAError, 'an error occurred in Zone A'
33
+ # rescue => err
34
+ # raise Errors::ZoneBError.wrap(err, <<-EOS)
35
+ # an error occurred in Zone B
36
+ #
37
+ # the following error should give a reason
38
+ # EOS
39
+ # end
40
+ # rescue => err
41
+ # raise Errors::ZoneCError.wrap(err)
42
+ # end
43
+ # rescue => err
44
+ # puts Errors::ZoneDError.wrap(err, 'an error occurred in Zone D')
45
+ # end
46
+ # end
47
+ #
48
+ # Outputs:
49
+ # ZoneDError: an error occurred in Zone D
50
+ # Reason: ZoneCError
51
+ # ZoneBError: an error occurred in Zone B
52
+ #
53
+ # the following error should give a reason
54
+ # Reason: ZoneAError
55
+ # an error occurred in Zone A
56
+ #
57
+ module Errors
58
+ extend ErrorsHelper
59
+
60
+ class Error < StandardError
61
+
62
+ def self.wrap(orig_err, msg = nil)
63
+ new(msg, orig_err)
64
+ end
65
+
66
+ def initialize(msg = nil, orig_err = nil)
67
+ super(msg)
68
+ set_backtrace(orig_err.backtrace) if @orig_err = orig_err
69
+ end
70
+
71
+ def to_s
72
+ return @to_s if @to_s
73
+ orig_to_s = super()
74
+
75
+ if orig_to_s == self.class.to_s
76
+ msg = orig_err_msg ?
77
+ "#{orig_err_class}: #{orig_err_msg}" : orig_err_class
78
+ else
79
+ msg = format_msg(orig_to_s)
80
+ msg << "\n Reason: #{orig_err_class}" + (orig_err_msg ?
81
+ "\n #{orig_err_msg}" : ' (no message given)') if @orig_err
82
+ end
83
+
84
+ @to_s = msg ? msg_prefix + msg : class_name
85
+ end
86
+
87
+ private
88
+
89
+ def msg_prefix
90
+ @msg_prefix ||= class_name + ': '
91
+ end
92
+
93
+ def orig_msg
94
+ @orig_msg ||= to_s.sub(msg_prefix, '')
95
+ end
96
+
97
+ def class_name
98
+ @class_name ||= self.class.to_s.sub('Backup::Errors::', '')
99
+ end
100
+
101
+ def orig_err_class
102
+ return unless @orig_err
103
+
104
+ @orig_err_class ||= @orig_err.is_a?(Errors::Error) ?
105
+ @orig_err.send(:class_name) : @orig_err.class.to_s
106
+ end
107
+
108
+ def orig_err_msg
109
+ return unless @orig_err
110
+ return @orig_err_msg unless @orig_err_msg.nil?
111
+
112
+ msg = @orig_err.is_a?(Errors::Error) ?
113
+ @orig_err.send(:orig_msg) : @orig_err.to_s
114
+ @orig_err_msg = (msg == orig_err_class) ?
115
+ false : format_msg(msg)
116
+ end
117
+
118
+ def format_msg(msg)
119
+ msg.gsub(/^ */, ' ').strip
120
+ end
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+
3
+ module Backup
4
+ module Logger
5
+ class << self
6
+
7
+ attr_accessor :quiet
8
+
9
+ ##
10
+ # Outputs a messages to the console and writes it to the backup.log
11
+ def message(string)
12
+ to_console loggify(string, :message, :green)
13
+ to_file loggify(string, :message)
14
+ end
15
+
16
+ ##
17
+ # Outputs an error to the console and writes it to the backup.log
18
+ # Called when an Exception has caused the backup process to abort.
19
+ def error(string)
20
+ to_console loggify(string, :error, :red), true
21
+ to_file loggify(string, :error)
22
+ end
23
+
24
+ ##
25
+ # Outputs a notice to the console and writes it to the backup.log
26
+ # Sets #has_warnings? true so :on_warning notifications will be sent
27
+ def warn(string)
28
+ @has_warnings = true
29
+ to_console loggify(string, :warning, :yellow), true
30
+ to_file loggify(string, :warning)
31
+ end
32
+
33
+ # Outputs the data as if it were a regular 'puts' command,
34
+ # but also logs it to the backup.log
35
+ def normal(string)
36
+ to_console loggify(string)
37
+ to_file loggify(string)
38
+ end
39
+
40
+ ##
41
+ # Silently logs data to the log file
42
+ def silent(string)
43
+ to_file loggify(string, :silent)
44
+ end
45
+
46
+ ##
47
+ # Returns an Array of all messages written to the log file for this session
48
+ def messages
49
+ @messages ||= []
50
+ end
51
+
52
+ ##
53
+ # Returns true if any warnings have been issued
54
+ def has_warnings?
55
+ @has_warnings ||= false
56
+ end
57
+
58
+ def clear!
59
+ messages.clear
60
+ @has_warnings = false
61
+ end
62
+
63
+ def truncate!(max_bytes = 500_000)
64
+ log_file = File.join(Config.log_path, 'backup.log')
65
+ return unless File.exist?(log_file)
66
+
67
+ if File.stat(log_file).size > max_bytes
68
+ FileUtils.mv(log_file, log_file + '~')
69
+ File.open(log_file + '~', 'r') do |io_in|
70
+ File.open(log_file, 'w') do |io_out|
71
+ io_in.seek(-max_bytes, IO::SEEK_END) && io_in.gets
72
+ while line = io_in.gets
73
+ io_out.puts line
74
+ end
75
+ end
76
+ end
77
+ FileUtils.rm_f(log_file + '~')
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ ##
84
+ # Returns the time in [YYYY/MM/DD HH:MM:SS] format
85
+ def time
86
+ Time.now.strftime("%Y/%m/%d %H:%M:%S")
87
+ end
88
+
89
+ ##
90
+ # Receives a String, or an Object that responds to #to_s (e.g. an
91
+ # Exception), from one of the messaging methods and converts it into an
92
+ # Array of Strings, split on newline separators. Each line is then
93
+ # formatted into a log format based on the given options, and the Array
94
+ # returned to be passed to to_console() and/or to_file().
95
+ def loggify(string, type = false, color = false)
96
+ lines = string.to_s.split("\n")
97
+ if type
98
+ type = send(color, type) if color
99
+ time_now = time
100
+ lines.map {|line| "[#{time_now}][#{type}] #{line}" }
101
+ else
102
+ lines
103
+ end
104
+ end
105
+
106
+ ##
107
+ # Receives an Array of Strings to be written to the console.
108
+ def to_console(lines, stderr = false)
109
+ return if quiet
110
+ lines.each {|line| stderr ? Kernel.warn(line) : puts(line) }
111
+ end
112
+
113
+ ##
114
+ # Receives an Array of Strings to be written to the log file.
115
+ def to_file(lines)
116
+ File.open(File.join(Config.log_path, 'backup.log'), 'a') do |file|
117
+ lines.each {|line| file.puts line }
118
+ end
119
+ messages.push(*lines)
120
+ end
121
+
122
+ ##
123
+ # Invokes the #colorize method with the provided string
124
+ # and the color code "32" (for green)
125
+ def green(string)
126
+ colorize(string, 32)
127
+ end
128
+
129
+ ##
130
+ # Invokes the #colorize method with the provided string
131
+ # and the color code "33" (for yellow)
132
+ def yellow(string)
133
+ colorize(string, 33)
134
+ end
135
+
136
+ ##
137
+ # Invokes the #colorize method the with provided string
138
+ # and the color code "31" (for red)
139
+ def red(string)
140
+ colorize(string, 31)
141
+ end
142
+
143
+ ##
144
+ # Wraps the provided string in colorizing tags to provide
145
+ # easier to view output to the client
146
+ def colorize(string, code)
147
+ "\e[#{code}m#{string}\e[0m"
148
+ end
149
+
150
+ end
151
+ end
152
+ end