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.
- data/.gitignore +7 -0
- data/.travis.yml +10 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +130 -0
- data/Guardfile +21 -0
- data/LICENSE.md +24 -0
- data/README.md +476 -0
- data/backup_checksum.gemspec +32 -0
- data/bin/backup +11 -0
- data/lib/backup.rb +217 -0
- data/lib/backup/archive.rb +117 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/checksum/base.rb +44 -0
- data/lib/backup/checksum/shasum.rb +16 -0
- data/lib/backup/cleaner.rb +121 -0
- data/lib/backup/cli/helpers.rb +88 -0
- data/lib/backup/cli/utility.rb +247 -0
- data/lib/backup/compressor/base.rb +29 -0
- data/lib/backup/compressor/bzip2.rb +50 -0
- data/lib/backup/compressor/gzip.rb +47 -0
- data/lib/backup/compressor/lzma.rb +50 -0
- data/lib/backup/compressor/pbzip2.rb +56 -0
- data/lib/backup/config.rb +173 -0
- data/lib/backup/configuration/base.rb +15 -0
- data/lib/backup/configuration/checksum/base.rb +9 -0
- data/lib/backup/configuration/checksum/shasum.rb +9 -0
- data/lib/backup/configuration/compressor/base.rb +9 -0
- data/lib/backup/configuration/compressor/bzip2.rb +23 -0
- data/lib/backup/configuration/compressor/gzip.rb +23 -0
- data/lib/backup/configuration/compressor/lzma.rb +23 -0
- data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
- data/lib/backup/configuration/database/base.rb +19 -0
- data/lib/backup/configuration/database/mongodb.rb +49 -0
- data/lib/backup/configuration/database/mysql.rb +42 -0
- data/lib/backup/configuration/database/postgresql.rb +41 -0
- data/lib/backup/configuration/database/redis.rb +39 -0
- data/lib/backup/configuration/database/riak.rb +29 -0
- data/lib/backup/configuration/encryptor/base.rb +9 -0
- data/lib/backup/configuration/encryptor/gpg.rb +17 -0
- data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
- data/lib/backup/configuration/helpers.rb +52 -0
- data/lib/backup/configuration/notifier/base.rb +28 -0
- data/lib/backup/configuration/notifier/campfire.rb +25 -0
- data/lib/backup/configuration/notifier/hipchat.rb +41 -0
- data/lib/backup/configuration/notifier/mail.rb +112 -0
- data/lib/backup/configuration/notifier/presently.rb +25 -0
- data/lib/backup/configuration/notifier/prowl.rb +23 -0
- data/lib/backup/configuration/notifier/twitter.rb +21 -0
- data/lib/backup/configuration/storage/base.rb +18 -0
- data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
- data/lib/backup/configuration/storage/dropbox.rb +58 -0
- data/lib/backup/configuration/storage/ftp.rb +29 -0
- data/lib/backup/configuration/storage/local.rb +17 -0
- data/lib/backup/configuration/storage/ninefold.rb +20 -0
- data/lib/backup/configuration/storage/rsync.rb +29 -0
- data/lib/backup/configuration/storage/s3.rb +25 -0
- data/lib/backup/configuration/storage/scp.rb +25 -0
- data/lib/backup/configuration/storage/sftp.rb +25 -0
- data/lib/backup/configuration/syncer/base.rb +10 -0
- data/lib/backup/configuration/syncer/cloud.rb +23 -0
- data/lib/backup/configuration/syncer/cloud_files.rb +30 -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 +23 -0
- data/lib/backup/database/base.rb +59 -0
- data/lib/backup/database/mongodb.rb +232 -0
- data/lib/backup/database/mysql.rb +163 -0
- data/lib/backup/database/postgresql.rb +146 -0
- data/lib/backup/database/redis.rb +139 -0
- data/lib/backup/database/riak.rb +69 -0
- data/lib/backup/dependency.rb +114 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +80 -0
- data/lib/backup/encryptor/open_ssl.rb +72 -0
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/logger.rb +152 -0
- data/lib/backup/model.rb +386 -0
- data/lib/backup/notifier/base.rb +81 -0
- data/lib/backup/notifier/campfire.rb +168 -0
- data/lib/backup/notifier/hipchat.rb +99 -0
- data/lib/backup/notifier/mail.rb +206 -0
- data/lib/backup/notifier/presently.rb +88 -0
- data/lib/backup/notifier/prowl.rb +65 -0
- data/lib/backup/notifier/twitter.rb +70 -0
- data/lib/backup/package.rb +51 -0
- data/lib/backup/packager.rb +108 -0
- data/lib/backup/pipeline.rb +107 -0
- data/lib/backup/splitter.rb +75 -0
- data/lib/backup/storage/base.rb +119 -0
- data/lib/backup/storage/cloudfiles.rb +87 -0
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +181 -0
- data/lib/backup/storage/ftp.rb +119 -0
- data/lib/backup/storage/local.rb +82 -0
- data/lib/backup/storage/ninefold.rb +116 -0
- data/lib/backup/storage/rsync.rb +149 -0
- data/lib/backup/storage/s3.rb +94 -0
- data/lib/backup/storage/scp.rb +99 -0
- data/lib/backup/storage/sftp.rb +108 -0
- data/lib/backup/syncer/base.rb +42 -0
- data/lib/backup/syncer/cloud.rb +190 -0
- data/lib/backup/syncer/cloud_files.rb +56 -0
- data/lib/backup/syncer/rsync/base.rb +52 -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 +47 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +43 -0
- data/spec/archive_spec.rb +335 -0
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +176 -0
- data/spec/cli/utility_spec.rb +363 -0
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +83 -0
- data/spec/compressor/gzip_spec.rb +83 -0
- data/spec/compressor/lzma_spec.rb +83 -0
- data/spec/compressor/pbzip2_spec.rb +124 -0
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +35 -0
- data/spec/configuration/compressor/bzip2_spec.rb +29 -0
- data/spec/configuration/compressor/gzip_spec.rb +29 -0
- data/spec/configuration/compressor/lzma_spec.rb +29 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +17 -0
- data/spec/configuration/database/mongodb_spec.rb +56 -0
- data/spec/configuration/database/mysql_spec.rb +53 -0
- data/spec/configuration/database/postgresql_spec.rb +53 -0
- data/spec/configuration/database/redis_spec.rb +50 -0
- data/spec/configuration/database/riak_spec.rb +35 -0
- data/spec/configuration/encryptor/gpg_spec.rb +26 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +32 -0
- data/spec/configuration/notifier/hipchat_spec.rb +44 -0
- data/spec/configuration/notifier/mail_spec.rb +71 -0
- data/spec/configuration/notifier/presently_spec.rb +35 -0
- data/spec/configuration/notifier/prowl_spec.rb +29 -0
- data/spec/configuration/notifier/twitter_spec.rb +35 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
- data/spec/configuration/storage/dropbox_spec.rb +38 -0
- data/spec/configuration/storage/ftp_spec.rb +44 -0
- data/spec/configuration/storage/local_spec.rb +29 -0
- data/spec/configuration/storage/ninefold_spec.rb +32 -0
- data/spec/configuration/storage/rsync_spec.rb +41 -0
- data/spec/configuration/storage/s3_spec.rb +38 -0
- data/spec/configuration/storage/scp_spec.rb +41 -0
- data/spec/configuration/storage/sftp_spec.rb +41 -0
- data/spec/configuration/syncer/cloud_files_spec.rb +44 -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/push_spec.rb +43 -0
- data/spec/configuration/syncer/s3_spec.rb +38 -0
- data/spec/database/base_spec.rb +54 -0
- data/spec/database/mongodb_spec.rb +428 -0
- data/spec/database/mysql_spec.rb +335 -0
- data/spec/database/postgresql_spec.rb +278 -0
- data/spec/database/redis_spec.rb +260 -0
- data/spec/database/riak_spec.rb +108 -0
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +134 -0
- data/spec/encryptor/open_ssl_spec.rb +129 -0
- data/spec/errors_spec.rb +306 -0
- data/spec/logger_spec.rb +363 -0
- data/spec/model_spec.rb +649 -0
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +199 -0
- data/spec/notifier/hipchat_spec.rb +188 -0
- data/spec/notifier/mail_spec.rb +280 -0
- data/spec/notifier/presently_spec.rb +181 -0
- data/spec/notifier/prowl_spec.rb +117 -0
- data/spec/notifier/twitter_spec.rb +132 -0
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +225 -0
- data/spec/pipeline_spec.rb +257 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/splitter_spec.rb +120 -0
- data/spec/storage/base_spec.rb +160 -0
- data/spec/storage/cloudfiles_spec.rb +230 -0
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +370 -0
- data/spec/storage/ftp_spec.rb +247 -0
- data/spec/storage/local_spec.rb +235 -0
- data/spec/storage/ninefold_spec.rb +319 -0
- data/spec/storage/rsync_spec.rb +345 -0
- data/spec/storage/s3_spec.rb +221 -0
- data/spec/storage/scp_spec.rb +209 -0
- data/spec/storage/sftp_spec.rb +220 -0
- data/spec/syncer/base_spec.rb +22 -0
- data/spec/syncer/cloud_files_spec.rb +192 -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 +192 -0
- data/spec/version_spec.rb +21 -0
- data/templates/cli/utility/archive +25 -0
- data/templates/cli/utility/compressor/bzip2 +7 -0
- data/templates/cli/utility/compressor/gzip +7 -0
- data/templates/cli/utility/compressor/lzma +7 -0
- data/templates/cli/utility/compressor/pbzip2 +7 -0
- data/templates/cli/utility/config +31 -0
- data/templates/cli/utility/database/mongodb +18 -0
- data/templates/cli/utility/database/mysql +21 -0
- data/templates/cli/utility/database/postgresql +17 -0
- data/templates/cli/utility/database/redis +16 -0
- data/templates/cli/utility/database/riak +11 -0
- data/templates/cli/utility/encryptor/gpg +12 -0
- data/templates/cli/utility/encryptor/openssl +9 -0
- data/templates/cli/utility/model.erb +23 -0
- data/templates/cli/utility/notifier/campfire +12 -0
- data/templates/cli/utility/notifier/hipchat +15 -0
- data/templates/cli/utility/notifier/mail +22 -0
- data/templates/cli/utility/notifier/presently +13 -0
- data/templates/cli/utility/notifier/prowl +11 -0
- data/templates/cli/utility/notifier/twitter +13 -0
- data/templates/cli/utility/splitter +7 -0
- data/templates/cli/utility/storage/cloud_files +22 -0
- data/templates/cli/utility/storage/dropbox +20 -0
- data/templates/cli/utility/storage/ftp +12 -0
- data/templates/cli/utility/storage/local +7 -0
- data/templates/cli/utility/storage/ninefold +9 -0
- data/templates/cli/utility/storage/rsync +11 -0
- data/templates/cli/utility/storage/s3 +19 -0
- data/templates/cli/utility/storage/scp +11 -0
- data/templates/cli/utility/storage/sftp +11 -0
- data/templates/cli/utility/syncer/cloud_files +48 -0
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/rsync_pull +17 -0
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/cli/utility/syncer/s3 +45 -0
- data/templates/general/links +11 -0
- data/templates/general/version.erb +2 -0
- data/templates/notifier/mail/failure.erb +9 -0
- data/templates/notifier/mail/success.erb +7 -0
- data/templates/notifier/mail/warning.erb +9 -0
- data/templates/storage/dropbox/authorization_url.erb +6 -0
- data/templates/storage/dropbox/authorized.erb +4 -0
- data/templates/storage/dropbox/cache_file_written.erb +10 -0
- metadata +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
|