backup 3.0.27 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.md +1 -1
- data/README.md +139 -386
- data/bin/backup +1 -7
- data/lib/backup.rb +3 -9
- data/lib/backup/archive.rb +26 -20
- data/lib/backup/cleaner.rb +2 -2
- data/lib/backup/cli.rb +366 -0
- data/lib/backup/compressor/base.rb +2 -2
- data/lib/backup/compressor/gzip.rb +35 -1
- data/lib/backup/config.rb +1 -2
- data/lib/backup/database/base.rb +2 -2
- data/lib/backup/database/mongodb.rb +3 -3
- data/lib/backup/database/mysql.rb +3 -2
- data/lib/backup/database/postgresql.rb +3 -2
- data/lib/backup/database/riak.rb +18 -5
- data/lib/backup/dependency.rb +144 -93
- data/lib/backup/encryptor/base.rb +2 -2
- data/lib/backup/logger.rb +108 -110
- data/lib/backup/logger/console.rb +51 -0
- data/lib/backup/logger/logfile.rb +113 -0
- data/lib/backup/logger/syslog.rb +116 -0
- data/lib/backup/model.rb +67 -65
- data/lib/backup/notifier/base.rb +1 -1
- data/lib/backup/notifier/hipchat.rb +1 -1
- data/lib/backup/notifier/mail.rb +1 -1
- data/lib/backup/notifier/pushover.rb +6 -3
- data/lib/backup/packager.rb +4 -4
- data/lib/backup/pipeline.rb +17 -3
- data/lib/backup/splitter.rb +2 -2
- data/lib/backup/storage/base.rb +2 -2
- data/lib/backup/storage/cloudfiles.rb +2 -2
- data/lib/backup/storage/dropbox.rb +4 -4
- data/lib/backup/storage/ftp.rb +2 -2
- data/lib/backup/storage/local.rb +2 -2
- data/lib/backup/storage/ninefold.rb +2 -2
- data/lib/backup/storage/rsync.rb +3 -3
- data/lib/backup/storage/s3.rb +2 -2
- data/lib/backup/storage/scp.rb +2 -6
- data/lib/backup/storage/sftp.rb +2 -5
- data/lib/backup/syncer/base.rb +1 -1
- data/lib/backup/syncer/cloud/base.rb +15 -8
- data/lib/backup/syncer/rsync/local.rb +1 -1
- data/lib/backup/syncer/rsync/pull.rb +1 -1
- data/lib/backup/syncer/rsync/push.rb +1 -1
- data/lib/backup/utilities.rb +211 -0
- data/lib/backup/version.rb +1 -1
- data/templates/cli/{utility/archive → archive} +4 -8
- data/templates/cli/{utility/compressor → compressor}/bzip2 +0 -0
- data/templates/cli/{utility/compressor → compressor}/custom +0 -0
- data/templates/cli/{utility/compressor → compressor}/gzip +0 -0
- data/templates/cli/{utility/compressor → compressor}/lzma +0 -0
- data/templates/cli/{utility/compressor → compressor}/pbzip2 +0 -0
- data/templates/cli/config +68 -0
- data/templates/cli/{utility/database → database}/mongodb +1 -1
- data/templates/cli/{utility/database → database}/mysql +1 -1
- data/templates/cli/{utility/database → database}/postgresql +1 -1
- data/templates/cli/{utility/database → database}/redis +0 -0
- data/templates/cli/database/riak +20 -0
- data/templates/cli/{utility/encryptor → encryptor}/gpg +0 -0
- data/templates/cli/{utility/encryptor → encryptor}/openssl +0 -0
- data/templates/cli/{utility/model.erb → model.erb} +4 -4
- data/templates/cli/{utility/notifier → notifier}/campfire +0 -0
- data/templates/cli/{utility/notifier → notifier}/hipchat +0 -0
- data/templates/cli/{utility/notifier → notifier}/mail +0 -0
- data/templates/cli/{utility/notifier → notifier}/prowl +0 -0
- data/templates/cli/{utility/notifier → notifier}/pushover +0 -0
- data/templates/cli/{utility/notifier → notifier}/twitter +0 -0
- data/templates/cli/{utility/splitter → splitter} +0 -0
- data/templates/cli/{utility/storage → storage}/cloud_files +0 -0
- data/templates/cli/{utility/storage → storage}/dropbox +0 -0
- data/templates/cli/{utility/storage → storage}/ftp +0 -0
- data/templates/cli/{utility/storage → storage}/local +0 -0
- data/templates/cli/{utility/storage → storage}/ninefold +0 -0
- data/templates/cli/{utility/storage → storage}/rsync +0 -0
- data/templates/cli/{utility/storage → storage}/s3 +0 -0
- data/templates/cli/{utility/storage → storage}/scp +0 -0
- data/templates/cli/{utility/storage → storage}/sftp +0 -0
- data/templates/cli/{utility/syncer → syncer}/cloud_files +0 -0
- data/templates/cli/{utility/syncer → syncer}/rsync_local +0 -0
- data/templates/cli/{utility/syncer → syncer}/rsync_pull +0 -0
- data/templates/cli/{utility/syncer → syncer}/rsync_push +0 -0
- data/templates/cli/{utility/syncer → syncer}/s3 +0 -0
- metadata +55 -131
- data/.gitignore +0 -8
- data/.travis.yml +0 -10
- data/Gemfile +0 -28
- data/Guardfile +0 -23
- data/backup.gemspec +0 -32
- data/lib/backup/cli/helpers.rb +0 -93
- data/lib/backup/cli/utility.rb +0 -255
- data/spec-live/.gitignore +0 -6
- data/spec-live/README +0 -7
- data/spec-live/backups/config.rb +0 -83
- data/spec-live/backups/config.yml.template +0 -46
- data/spec-live/backups/models.rb +0 -184
- data/spec-live/compressor/custom_spec.rb +0 -30
- data/spec-live/compressor/gzip_spec.rb +0 -30
- data/spec-live/encryptor/gpg_keys.rb +0 -239
- data/spec-live/encryptor/gpg_spec.rb +0 -287
- data/spec-live/notifier/mail_spec.rb +0 -121
- data/spec-live/spec_helper.rb +0 -151
- data/spec-live/storage/dropbox_spec.rb +0 -151
- data/spec-live/storage/local_spec.rb +0 -83
- data/spec-live/storage/scp_spec.rb +0 -193
- data/spec-live/syncer/cloud/s3_spec.rb +0 -124
- data/spec/archive_spec.rb +0 -335
- data/spec/cleaner_spec.rb +0 -312
- data/spec/cli/helpers_spec.rb +0 -301
- data/spec/cli/utility_spec.rb +0 -411
- data/spec/compressor/base_spec.rb +0 -52
- data/spec/compressor/bzip2_spec.rb +0 -217
- data/spec/compressor/custom_spec.rb +0 -106
- data/spec/compressor/gzip_spec.rb +0 -217
- data/spec/compressor/lzma_spec.rb +0 -123
- data/spec/compressor/pbzip2_spec.rb +0 -165
- data/spec/config_spec.rb +0 -321
- data/spec/configuration/helpers_spec.rb +0 -247
- data/spec/configuration/store_spec.rb +0 -39
- data/spec/configuration_spec.rb +0 -62
- data/spec/database/base_spec.rb +0 -63
- data/spec/database/mongodb_spec.rb +0 -510
- data/spec/database/mysql_spec.rb +0 -411
- data/spec/database/postgresql_spec.rb +0 -353
- data/spec/database/redis_spec.rb +0 -334
- data/spec/database/riak_spec.rb +0 -176
- data/spec/dependency_spec.rb +0 -51
- data/spec/encryptor/base_spec.rb +0 -40
- data/spec/encryptor/gpg_spec.rb +0 -909
- data/spec/encryptor/open_ssl_spec.rb +0 -148
- data/spec/errors_spec.rb +0 -306
- data/spec/logger_spec.rb +0 -367
- data/spec/model_spec.rb +0 -666
- data/spec/notifier/base_spec.rb +0 -104
- data/spec/notifier/campfire_spec.rb +0 -217
- data/spec/notifier/hipchat_spec.rb +0 -211
- data/spec/notifier/mail_spec.rb +0 -316
- data/spec/notifier/prowl_spec.rb +0 -138
- data/spec/notifier/pushover_spec.rb +0 -123
- data/spec/notifier/twitter_spec.rb +0 -153
- data/spec/package_spec.rb +0 -61
- data/spec/packager_spec.rb +0 -213
- data/spec/pipeline_spec.rb +0 -259
- data/spec/spec_helper.rb +0 -60
- data/spec/splitter_spec.rb +0 -120
- data/spec/storage/base_spec.rb +0 -166
- data/spec/storage/cloudfiles_spec.rb +0 -254
- data/spec/storage/cycler_spec.rb +0 -247
- data/spec/storage/dropbox_spec.rb +0 -480
- data/spec/storage/ftp_spec.rb +0 -271
- data/spec/storage/local_spec.rb +0 -259
- data/spec/storage/ninefold_spec.rb +0 -343
- data/spec/storage/rsync_spec.rb +0 -362
- data/spec/storage/s3_spec.rb +0 -245
- data/spec/storage/scp_spec.rb +0 -233
- data/spec/storage/sftp_spec.rb +0 -244
- data/spec/syncer/base_spec.rb +0 -109
- data/spec/syncer/cloud/base_spec.rb +0 -515
- data/spec/syncer/cloud/cloud_files_spec.rb +0 -181
- data/spec/syncer/cloud/s3_spec.rb +0 -174
- data/spec/syncer/rsync/base_spec.rb +0 -98
- data/spec/syncer/rsync/local_spec.rb +0 -149
- data/spec/syncer/rsync/pull_spec.rb +0 -98
- data/spec/syncer/rsync/push_spec.rb +0 -333
- data/spec/version_spec.rb +0 -21
- data/templates/cli/utility/config +0 -32
- data/templates/cli/utility/database/riak +0 -11
@@ -3,7 +3,7 @@
|
|
3
3
|
module Backup
|
4
4
|
module Compressor
|
5
5
|
class Base
|
6
|
-
include Backup::
|
6
|
+
include Backup::Utilities::Helpers
|
7
7
|
include Backup::Configuration::Helpers
|
8
8
|
|
9
9
|
##
|
@@ -25,7 +25,7 @@ module Backup
|
|
25
25
|
# Logs a message to the console and log file to inform
|
26
26
|
# the client that Backup is using the compressor
|
27
27
|
def log!
|
28
|
-
Logger.
|
28
|
+
Logger.info "Using #{ compressor_name } for compression.\n" +
|
29
29
|
" Command: '#{ @cmd }'\n" +
|
30
30
|
" Ext: '#{ @ext }'"
|
31
31
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module Backup
|
4
4
|
module Compressor
|
5
5
|
class Gzip < Base
|
6
|
+
extend Utilities::Helpers
|
6
7
|
|
7
8
|
##
|
8
9
|
# Specify the level of compression to use.
|
@@ -26,12 +27,35 @@ module Backup
|
|
26
27
|
klass.level = 9 if val
|
27
28
|
}
|
28
29
|
|
30
|
+
##
|
31
|
+
# Use the `--rsyncable` option with `gzip`.
|
32
|
+
#
|
33
|
+
# This option directs `gzip` to compress data using an algorithm that
|
34
|
+
# allows `rsync` to efficiently detect changes. This is especially useful
|
35
|
+
# when used to compress `Archive` or `Database` backups that will be
|
36
|
+
# stored using Backup's `RSync` Storage option.
|
37
|
+
#
|
38
|
+
# The `--rsyncable` option is only available on patched versions of `gzip`.
|
39
|
+
# While most distributions apply this patch, this option may not be
|
40
|
+
# available on your system. If it's not available, Backup will log a
|
41
|
+
# warning and continue to use the compressor without this option.
|
42
|
+
attr_accessor :rsyncable
|
43
|
+
|
44
|
+
##
|
45
|
+
# Determine if +--rsyncable+ is supported and cache the result.
|
46
|
+
def self.has_rsyncable?
|
47
|
+
return @has_rsyncable unless @has_rsyncable.nil?
|
48
|
+
cmd = "#{ utility(:gzip) } --rsyncable --version >/dev/null 2>&1; echo $?"
|
49
|
+
@has_rsyncable = %x[#{ cmd }].chomp == '0'
|
50
|
+
end
|
51
|
+
|
29
52
|
##
|
30
53
|
# Creates a new instance of Backup::Compressor::Gzip
|
31
54
|
def initialize(&block)
|
32
55
|
load_defaults!
|
33
56
|
|
34
57
|
@level ||= false
|
58
|
+
@rsyncable ||= false
|
35
59
|
|
36
60
|
instance_eval(&block) if block_given?
|
37
61
|
|
@@ -42,7 +66,17 @@ module Backup
|
|
42
66
|
private
|
43
67
|
|
44
68
|
def options
|
45
|
-
|
69
|
+
opts = ''
|
70
|
+
opts << " -#{ @level }" if @level
|
71
|
+
if self.class.has_rsyncable?
|
72
|
+
opts << ' --rsyncable'
|
73
|
+
else
|
74
|
+
Logger.warn Errors::Compressor::Gzip::RsyncableError.new(<<-EOS)
|
75
|
+
'rsyncable' option ignored.
|
76
|
+
Your system's 'gzip' does not support the `--rsyncable` option.
|
77
|
+
EOS
|
78
|
+
end if @rsyncable
|
79
|
+
opts
|
46
80
|
end
|
47
81
|
|
48
82
|
end
|
data/lib/backup/config.rb
CHANGED
@@ -5,14 +5,13 @@ module Backup
|
|
5
5
|
DEFAULTS = {
|
6
6
|
:config_file => 'config.rb',
|
7
7
|
:data_path => 'data',
|
8
|
-
:log_path => 'log',
|
9
8
|
:cache_path => '.cache',
|
10
9
|
:tmp_path => '.tmp'
|
11
10
|
}
|
12
11
|
|
13
12
|
class << self
|
14
13
|
attr_reader :user, :root_path, :config_file,
|
15
|
-
:data_path, :
|
14
|
+
:data_path, :cache_path, :tmp_path
|
16
15
|
|
17
16
|
##
|
18
17
|
# Setup required paths based on the given options
|
data/lib/backup/database/base.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Backup
|
4
4
|
module Database
|
5
5
|
class Base
|
6
|
-
include Backup::
|
6
|
+
include Backup::Utilities::Helpers
|
7
7
|
include Backup::Configuration::Helpers
|
8
8
|
|
9
9
|
##
|
@@ -46,7 +46,7 @@ module Backup
|
|
46
46
|
# Logs a message to the console and log file to inform
|
47
47
|
# the client that Backup is dumping the database
|
48
48
|
def log!
|
49
|
-
Logger.
|
49
|
+
Logger.info "#{ database_name } started dumping and archiving '#{ name }'."
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -121,7 +121,7 @@ module Backup
|
|
121
121
|
timestamp = Time.now.to_i.to_s[-5, 5]
|
122
122
|
outfile = @dump_path + '-' + timestamp + '.tar'
|
123
123
|
|
124
|
-
Logger.
|
124
|
+
Logger.info(
|
125
125
|
"#{ database_name } started compressing and packaging:\n" +
|
126
126
|
" '#{ @dump_path }'"
|
127
127
|
)
|
@@ -131,11 +131,11 @@ module Backup
|
|
131
131
|
pipeline << command
|
132
132
|
outfile << ext
|
133
133
|
end
|
134
|
-
pipeline << "cat > #{ outfile }"
|
135
134
|
|
135
|
+
pipeline << "#{ utility(:cat) } > #{ outfile }"
|
136
136
|
pipeline.run
|
137
137
|
if pipeline.success?
|
138
|
-
Logger.
|
138
|
+
Logger.info(
|
139
139
|
"#{ database_name } completed compressing and packaging:\n" +
|
140
140
|
" '#{ outfile }'"
|
141
141
|
)
|
@@ -68,11 +68,12 @@ module Backup
|
|
68
68
|
dump_ext << ext
|
69
69
|
end
|
70
70
|
end
|
71
|
-
pipeline << "cat > '#{ File.join(@dump_path, dump_filename) }.#{ dump_ext }'"
|
72
71
|
|
72
|
+
pipeline << "#{ utility(:cat) } > " +
|
73
|
+
"'#{ File.join(@dump_path, dump_filename) }.#{ dump_ext }'"
|
73
74
|
pipeline.run
|
74
75
|
if pipeline.success?
|
75
|
-
Logger.
|
76
|
+
Logger.info "#{ database_name } Complete!"
|
76
77
|
else
|
77
78
|
raise Errors::Database::PipelineError,
|
78
79
|
"#{ database_name } Dump Failed!\n" +
|
@@ -68,11 +68,12 @@ module Backup
|
|
68
68
|
dump_ext << ext
|
69
69
|
end
|
70
70
|
end
|
71
|
-
pipeline << "cat > '#{ File.join(@dump_path, name) }.#{ dump_ext }'"
|
72
71
|
|
72
|
+
pipeline << "#{ utility(:cat) } > " +
|
73
|
+
"'#{ File.join(@dump_path, name) }.#{ dump_ext }'"
|
73
74
|
pipeline.run
|
74
75
|
if pipeline.success?
|
75
|
-
Logger.
|
76
|
+
Logger.info "#{ database_name } Complete!"
|
76
77
|
else
|
77
78
|
raise Errors::Database::PipelineError,
|
78
79
|
"#{ database_name } Dump Failed!\n" +
|
data/lib/backup/database/riak.rb
CHANGED
@@ -20,6 +20,14 @@ module Backup
|
|
20
20
|
# Path to riak-admin utility (optional)
|
21
21
|
attr_accessor :riak_admin_utility
|
22
22
|
|
23
|
+
##
|
24
|
+
# Username for the riak instance (optional)
|
25
|
+
attr_accessor :user
|
26
|
+
|
27
|
+
##
|
28
|
+
# Group for the riak instance (optional)
|
29
|
+
attr_accessor :group
|
30
|
+
|
23
31
|
attr_deprecate :utility_path, :version => '3.0.21',
|
24
32
|
:message => 'Use Riak#riak_admin_utility instead.',
|
25
33
|
:action => lambda {|klass, val| klass.riak_admin_utility = val }
|
@@ -32,22 +40,27 @@ module Backup
|
|
32
40
|
instance_eval(&block) if block_given?
|
33
41
|
|
34
42
|
@riak_admin_utility ||= utility('riak-admin')
|
43
|
+
@user ||= 'riak'
|
44
|
+
@group ||= 'riak'
|
35
45
|
end
|
36
46
|
|
37
47
|
##
|
38
|
-
# Performs the riak-admin command
|
39
|
-
#
|
48
|
+
# Performs the `riak-admin` command which creates a single dump file in
|
49
|
+
# @dump_path based on the `name` and `node`.
|
50
|
+
#
|
51
|
+
# `riak-admin` will append the `node` to the filename.
|
52
|
+
# i.e. <tmp_path>/<trigger>/databases/Riak/<name>-<node>
|
40
53
|
def perform!
|
41
54
|
super
|
42
|
-
#
|
43
|
-
|
44
|
-
FileUtils.chown_R('riak', 'riak', @dump_path)
|
55
|
+
# ensure riak-admin user has permissions to write backup file
|
56
|
+
FileUtils.chown_R(@user, @group, @dump_path)
|
45
57
|
|
46
58
|
backup_file = File.join(@dump_path, name)
|
47
59
|
run("#{ riakadmin } #{ backup_file } node")
|
48
60
|
|
49
61
|
if @model.compressor
|
50
62
|
@model.compressor.compress_with do |command, ext|
|
63
|
+
backup_file << "-#{ node }"
|
51
64
|
run("#{ command } -c #{ backup_file } > #{ backup_file + ext }")
|
52
65
|
FileUtils.rm_f(backup_file)
|
53
66
|
end
|
data/lib/backup/dependency.rb
CHANGED
@@ -1,108 +1,159 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Backup
|
4
|
-
|
5
4
|
##
|
6
5
|
# A little self-contained gem manager for Backup.
|
7
|
-
# Rather than specifying hard dependencies in the gemspec, forcing users
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
6
|
+
# Rather than specifying hard dependencies in the gemspec, forcing users to
|
7
|
+
# install gems they do not want/need, Backup will notify them when a gem has
|
8
|
+
# not been installed, or version is incorrect, and provide the command to
|
9
|
+
# install the gem. These dependencies are dynamically loaded in the Gemfile.
|
11
10
|
class Dependency
|
11
|
+
DEPENDENCIES = {
|
12
|
+
'fog' => {
|
13
|
+
:require => 'fog',
|
14
|
+
:version => '~> 1.4',
|
15
|
+
:for => 'Amazon S3, Rackspace Cloud Files (S3, CloudFiles Storages)',
|
16
|
+
:dependencies => ['net-ssh', 'net-scp']
|
17
|
+
},
|
18
|
+
|
19
|
+
'dropbox-sdk' => {
|
20
|
+
:require => 'dropbox_sdk',
|
21
|
+
:version => '~> 1.5.0',
|
22
|
+
:for => 'Dropbox Web Service (Dropbox Storage)'
|
23
|
+
},
|
24
|
+
|
25
|
+
'net-sftp' => {
|
26
|
+
:require => 'net/sftp',
|
27
|
+
:version => ['>= 2.0.0', '<= 2.0.5'],
|
28
|
+
:for => 'SFTP Protocol (SFTP Storage)',
|
29
|
+
:dependencies => 'net-ssh'
|
30
|
+
},
|
31
|
+
|
32
|
+
'net-scp' => {
|
33
|
+
:require => 'net/scp',
|
34
|
+
:version => ['>= 1.0.0', '<= 1.0.4'],
|
35
|
+
:for => 'SCP Protocol (SCP Storage)',
|
36
|
+
:dependencies => 'net-ssh'
|
37
|
+
},
|
38
|
+
|
39
|
+
'net-ssh' => {
|
40
|
+
:require => 'net/ssh',
|
41
|
+
:version => ['>= 2.3.0', '<= 2.5.2'],
|
42
|
+
:for => 'SSH Protocol (SSH Storage)'
|
43
|
+
},
|
44
|
+
|
45
|
+
'mail' => {
|
46
|
+
:require => 'mail',
|
47
|
+
:version => '~> 2.5.0',
|
48
|
+
:for => 'Sending Emails (Mail Notifier)'
|
49
|
+
},
|
50
|
+
|
51
|
+
'twitter' => {
|
52
|
+
:require => 'twitter',
|
53
|
+
:version => '~> 4.0',
|
54
|
+
:for => 'Sending Twitter Updates (Twitter Notifier)'
|
55
|
+
},
|
12
56
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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.3.0',
|
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.8.1',
|
63
|
-
:for => 'Sending Http Updates'
|
64
|
-
},
|
65
|
-
|
66
|
-
'prowler' => {
|
67
|
-
:require => 'prowler',
|
68
|
-
:version => '>= 1.3.1',
|
69
|
-
:for => 'Sending iOS push notifications (Prowl Notifier)'
|
70
|
-
},
|
71
|
-
|
72
|
-
'hipchat' => {
|
73
|
-
:require => 'hipchat',
|
74
|
-
:version => '~> 0.4.1',
|
75
|
-
:for => 'Sending notifications to Hipchat'
|
76
|
-
},
|
77
|
-
|
78
|
-
'parallel' => {
|
79
|
-
:require => 'parallel',
|
80
|
-
:version => '~> 0.5.12',
|
81
|
-
:for => 'Adding concurrency to Cloud-based syncers.'
|
82
|
-
}
|
57
|
+
'httparty' => {
|
58
|
+
:require => 'httparty',
|
59
|
+
:version => '~> 0.10.2',
|
60
|
+
:for => 'Sending Http Updates (Campfire Notifier)'
|
61
|
+
},
|
62
|
+
|
63
|
+
'prowler' => {
|
64
|
+
:require => 'prowler',
|
65
|
+
:version => '~> 1.3.1',
|
66
|
+
:for => 'Sending iOS push notifications (Prowl Notifier)'
|
67
|
+
},
|
68
|
+
|
69
|
+
'hipchat' => {
|
70
|
+
:require => 'hipchat',
|
71
|
+
:version => '~> 0.7.0',
|
72
|
+
:for => 'Sending notifications to Hipchat'
|
73
|
+
},
|
74
|
+
|
75
|
+
'parallel' => {
|
76
|
+
:require => 'parallel',
|
77
|
+
:version => '~> 0.6.0',
|
78
|
+
:for => 'Adding concurrency to Cloud-based syncers.'
|
83
79
|
}
|
80
|
+
}
|
81
|
+
|
82
|
+
class << self
|
83
|
+
def all
|
84
|
+
@all ||= []
|
85
|
+
end
|
86
|
+
|
87
|
+
def find(name)
|
88
|
+
all.select {|dep| dep.name == name }.first
|
89
|
+
end
|
90
|
+
|
91
|
+
def load(name)
|
92
|
+
find(name).load!
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
attr_reader :name, :require_as, :used_for, :requirements
|
97
|
+
|
98
|
+
def initialize(name, options = {})
|
99
|
+
@name = name
|
100
|
+
@require_as = options[:require]
|
101
|
+
@requirements = Array(options[:version])
|
102
|
+
@dependencies = Array(options[:dependencies])
|
103
|
+
@used_for = options[:for]
|
104
|
+
end
|
105
|
+
|
106
|
+
# dependencies should be defined in the order
|
107
|
+
# they should be installed or loaded.
|
108
|
+
def dependencies
|
109
|
+
@dependencies.map {|name| self.class.find(name) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def load!
|
113
|
+
dependencies.each(&:load!)
|
114
|
+
|
115
|
+
gem(name, *requirements)
|
116
|
+
require require_as
|
117
|
+
rescue LoadError
|
118
|
+
raise Errors::Dependency::LoadError, <<-EOS
|
119
|
+
Dependency Missing
|
120
|
+
Gem Name: #{ name }
|
121
|
+
Used for: #{ used_for }
|
122
|
+
|
123
|
+
To install the gem, issue the following command:
|
124
|
+
> backup dependencies --install #{ name }
|
125
|
+
Please try again after installing the missing dependency.
|
126
|
+
EOS
|
127
|
+
end
|
128
|
+
|
129
|
+
def installed?
|
130
|
+
Gem::Specification.find_by_name(name, *requirements)
|
131
|
+
true
|
132
|
+
rescue LoadError
|
133
|
+
false
|
84
134
|
end
|
85
135
|
|
86
|
-
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
def
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
> gem install #{name} -v '#{all[name][:version]}'
|
101
|
-
Please try again after installing the missing dependency.
|
102
|
-
EOS
|
103
|
-
exit 1
|
136
|
+
# If multiple version requirements are defined, this tries to find the
|
137
|
+
# version that matches them all. Otherwise, it will fallback to installing
|
138
|
+
# based on the last requirement. This should only be called from the CLI
|
139
|
+
# for `backup dependencies --install <name>`.
|
140
|
+
def install!
|
141
|
+
version = nil
|
142
|
+
if requirements.count > 1
|
143
|
+
begin
|
144
|
+
require 'rubygems/dependency_installer'
|
145
|
+
inst = Gem::DependencyInstaller.new
|
146
|
+
spec, _ = inst.find_spec_by_name_and_version(name, *requirements).first
|
147
|
+
version = spec.version
|
148
|
+
rescue
|
149
|
+
end
|
104
150
|
end
|
151
|
+
version ||= requirements.last
|
152
|
+
command = "gem install --no-ri --no-rdoc #{ name } -v '#{ version }'"
|
153
|
+
puts "\nLaunching `#{ command }`"
|
154
|
+
exec command
|
105
155
|
end
|
106
156
|
|
157
|
+
DEPENDENCIES.each {|name, options| all << new(name, options) }
|
107
158
|
end
|
108
159
|
end
|