backup 3.0.20 → 3.0.21
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/Gemfile +1 -5
- data/Gemfile.lock +46 -50
- data/README.md +54 -27
- data/lib/backup.rb +16 -39
- data/lib/backup/archive.rb +42 -18
- data/lib/backup/cleaner.rb +110 -25
- data/lib/backup/cli/helpers.rb +17 -32
- data/lib/backup/cli/utility.rb +46 -107
- data/lib/backup/compressor/base.rb +14 -2
- data/lib/backup/compressor/bzip2.rb +10 -24
- data/lib/backup/compressor/gzip.rb +10 -24
- data/lib/backup/compressor/lzma.rb +10 -23
- data/lib/backup/compressor/pbzip2.rb +12 -32
- data/lib/backup/config.rb +171 -0
- data/lib/backup/configuration/compressor/base.rb +1 -2
- data/lib/backup/configuration/compressor/pbzip2.rb +4 -4
- data/lib/backup/configuration/database/base.rb +2 -1
- data/lib/backup/configuration/database/mongodb.rb +8 -0
- data/lib/backup/configuration/database/mysql.rb +4 -0
- data/lib/backup/configuration/database/postgresql.rb +4 -0
- data/lib/backup/configuration/database/redis.rb +4 -0
- data/lib/backup/configuration/database/riak.rb +5 -1
- data/lib/backup/configuration/encryptor/base.rb +1 -2
- data/lib/backup/configuration/encryptor/open_ssl.rb +1 -1
- data/lib/backup/configuration/helpers.rb +7 -2
- data/lib/backup/configuration/notifier/base.rb +4 -28
- data/lib/backup/configuration/storage/base.rb +1 -1
- data/lib/backup/configuration/storage/dropbox.rb +14 -4
- data/lib/backup/configuration/syncer/base.rb +10 -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 +0 -4
- data/lib/backup/database/base.rb +25 -7
- data/lib/backup/database/mongodb.rb +112 -75
- data/lib/backup/database/mysql.rb +54 -29
- data/lib/backup/database/postgresql.rb +60 -42
- data/lib/backup/database/redis.rb +61 -39
- data/lib/backup/database/riak.rb +35 -11
- data/lib/backup/dependency.rb +4 -5
- data/lib/backup/encryptor/base.rb +13 -1
- data/lib/backup/encryptor/gpg.rb +39 -39
- data/lib/backup/encryptor/open_ssl.rb +28 -38
- data/lib/backup/logger.rb +20 -11
- data/lib/backup/model.rb +206 -163
- data/lib/backup/notifier/base.rb +27 -25
- data/lib/backup/notifier/campfire.rb +7 -13
- data/lib/backup/notifier/hipchat.rb +28 -28
- data/lib/backup/notifier/mail.rb +24 -26
- data/lib/backup/notifier/presently.rb +10 -18
- data/lib/backup/notifier/prowl.rb +9 -17
- data/lib/backup/notifier/twitter.rb +11 -18
- data/lib/backup/package.rb +47 -0
- data/lib/backup/packager.rb +81 -16
- data/lib/backup/splitter.rb +48 -35
- data/lib/backup/storage/base.rb +44 -172
- data/lib/backup/storage/cloudfiles.rb +31 -46
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +92 -76
- data/lib/backup/storage/ftp.rb +30 -40
- data/lib/backup/storage/local.rb +44 -45
- data/lib/backup/storage/ninefold.rb +55 -49
- data/lib/backup/storage/rsync.rb +49 -56
- data/lib/backup/storage/s3.rb +33 -44
- data/lib/backup/storage/scp.rb +21 -48
- data/lib/backup/storage/sftp.rb +26 -40
- data/lib/backup/syncer/base.rb +7 -0
- data/lib/backup/syncer/rsync/base.rb +78 -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 +42 -32
- data/lib/backup/version.rb +1 -1
- data/spec/archive_spec.rb +235 -69
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +142 -1
- data/spec/cli/utility_spec.rb +338 -13
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +60 -35
- data/spec/compressor/gzip_spec.rb +60 -35
- data/spec/compressor/lzma_spec.rb +60 -35
- data/spec/compressor/pbzip2_spec.rb +98 -37
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +4 -4
- data/spec/configuration/compressor/bzip2_spec.rb +1 -0
- data/spec/configuration/compressor/gzip_spec.rb +1 -0
- data/spec/configuration/compressor/lzma_spec.rb +1 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +2 -1
- data/spec/configuration/database/mongodb_spec.rb +26 -16
- data/spec/configuration/database/mysql_spec.rb +4 -0
- data/spec/configuration/database/postgresql_spec.rb +4 -0
- data/spec/configuration/database/redis_spec.rb +4 -0
- data/spec/configuration/database/riak_spec.rb +4 -0
- data/spec/configuration/encryptor/gpg_spec.rb +1 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +1 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +1 -0
- data/spec/configuration/notifier/hipchat_spec.rb +1 -0
- data/spec/configuration/notifier/mail_spec.rb +1 -0
- data/spec/configuration/notifier/presently_spec.rb +1 -0
- data/spec/configuration/notifier/prowl_spec.rb +1 -0
- data/spec/configuration/notifier/twitter_spec.rb +1 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +1 -0
- data/spec/configuration/storage/dropbox_spec.rb +4 -3
- data/spec/configuration/storage/ftp_spec.rb +1 -0
- data/spec/configuration/storage/local_spec.rb +1 -0
- data/spec/configuration/storage/ninefold_spec.rb +1 -0
- data/spec/configuration/storage/rsync_spec.rb +3 -1
- data/spec/configuration/storage/s3_spec.rb +1 -0
- data/spec/configuration/storage/scp_spec.rb +1 -0
- data/spec/configuration/storage/sftp_spec.rb +1 -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_spec.rb → rsync/push_spec.rb} +12 -15
- data/spec/configuration/syncer/s3_spec.rb +2 -3
- data/spec/database/base_spec.rb +35 -20
- data/spec/database/mongodb_spec.rb +298 -119
- data/spec/database/mysql_spec.rb +147 -72
- data/spec/database/postgresql_spec.rb +155 -100
- data/spec/database/redis_spec.rb +200 -97
- data/spec/database/riak_spec.rb +82 -24
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +105 -28
- data/spec/encryptor/open_ssl_spec.rb +85 -114
- data/spec/logger_spec.rb +74 -8
- data/spec/model_spec.rb +528 -220
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +147 -119
- data/spec/notifier/hipchat_spec.rb +140 -145
- data/spec/notifier/mail_spec.rb +190 -248
- data/spec/notifier/presently_spec.rb +147 -282
- data/spec/notifier/prowl_spec.rb +79 -111
- data/spec/notifier/twitter_spec.rb +87 -106
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +154 -0
- data/spec/spec_helper.rb +36 -13
- data/spec/splitter_spec.rb +90 -41
- data/spec/storage/base_spec.rb +95 -239
- data/spec/storage/cloudfiles_spec.rb +185 -75
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +318 -87
- data/spec/storage/ftp_spec.rb +165 -152
- data/spec/storage/local_spec.rb +206 -54
- data/spec/storage/ninefold_spec.rb +264 -128
- data/spec/storage/rsync_spec.rb +244 -163
- data/spec/storage/s3_spec.rb +175 -64
- data/spec/storage/scp_spec.rb +156 -150
- data/spec/storage/sftp_spec.rb +153 -135
- data/spec/syncer/base_spec.rb +22 -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 +180 -91
- data/templates/cli/utility/config +1 -1
- data/templates/cli/utility/database/mongodb +4 -0
- data/templates/cli/utility/database/mysql +3 -0
- data/templates/cli/utility/database/postgresql +3 -0
- data/templates/cli/utility/database/redis +3 -0
- data/templates/cli/utility/database/riak +3 -0
- data/templates/cli/utility/storage/dropbox +4 -1
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/{rsync → rsync_pull} +2 -2
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/storage/dropbox/authorization_url.erb +1 -1
- metadata +42 -17
- data/lib/backup/configuration/syncer/rsync.rb +0 -45
- data/lib/backup/finder.rb +0 -87
- data/lib/backup/storage/object.rb +0 -47
- data/lib/backup/syncer/rsync.rb +0 -152
- data/spec/backup_spec.rb +0 -11
- data/spec/finder_spec.rb +0 -91
- data/spec/storage/object_spec.rb +0 -74
- data/spec/syncer/rsync_spec.rb +0 -195
|
@@ -13,7 +13,8 @@ module Backup
|
|
|
13
13
|
attr_accessor :username, :api_key, :auth_url
|
|
14
14
|
|
|
15
15
|
##
|
|
16
|
-
# Rackspace Service Net
|
|
16
|
+
# Rackspace Service Net
|
|
17
|
+
# (LAN-based transfers to avoid charges and improve performance)
|
|
17
18
|
attr_accessor :servicenet
|
|
18
19
|
|
|
19
20
|
##
|
|
@@ -21,49 +22,26 @@ module Backup
|
|
|
21
22
|
attr_accessor :container, :path
|
|
22
23
|
|
|
23
24
|
##
|
|
24
|
-
#
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
##
|
|
30
|
-
# This is the provider that Fog uses for the Cloud Files Storage
|
|
31
|
-
def provider
|
|
32
|
-
'Rackspace'
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
##
|
|
36
|
-
# Performs the backup transfer
|
|
37
|
-
def perform!
|
|
38
|
-
super
|
|
39
|
-
transfer!
|
|
40
|
-
cycle!
|
|
41
|
-
end
|
|
25
|
+
# Creates a new instance of the storage object
|
|
26
|
+
def initialize(model, storage_id = nil, &block)
|
|
27
|
+
super(model, storage_id)
|
|
42
28
|
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
##
|
|
46
|
-
# Set configuration defaults before evaluating configuration block,
|
|
47
|
-
# after setting defaults from Storage::Base
|
|
48
|
-
def pre_configure
|
|
49
|
-
super
|
|
50
29
|
@servicenet ||= false
|
|
51
30
|
@path ||= 'backups'
|
|
31
|
+
|
|
32
|
+
instance_eval(&block) if block_given?
|
|
52
33
|
end
|
|
53
34
|
|
|
35
|
+
private
|
|
36
|
+
|
|
54
37
|
##
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
super
|
|
38
|
+
# This is the provider that Fog uses for the Cloud Files Storage
|
|
39
|
+
def provider
|
|
40
|
+
'Rackspace'
|
|
59
41
|
end
|
|
60
42
|
|
|
61
43
|
##
|
|
62
|
-
# Establishes a connection to Rackspace Cloud Files
|
|
63
|
-
# Not doing any instance variable caching because this object gets persisted in YAML
|
|
64
|
-
# format to a file and will issues. This, however has no impact on performance since it only
|
|
65
|
-
# gets invoked once per object for a #transfer! and once for a remove! Backups run in the
|
|
66
|
-
# background anyway so even if it were a bit slower it shouldn't matter.
|
|
44
|
+
# Establishes a connection to Rackspace Cloud Files
|
|
67
45
|
def connection
|
|
68
46
|
@connection ||= Fog::Storage.new(
|
|
69
47
|
:provider => provider,
|
|
@@ -77,22 +55,29 @@ module Backup
|
|
|
77
55
|
##
|
|
78
56
|
# Transfers the archived file to the specified Cloud Files container
|
|
79
57
|
def transfer!
|
|
80
|
-
|
|
58
|
+
remote_path = remote_path_for(@package)
|
|
59
|
+
|
|
60
|
+
files_to_transfer_for(@package) do |local_file, remote_file|
|
|
81
61
|
Logger.message "#{storage_name} started transferring '#{ local_file }'."
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
62
|
+
|
|
63
|
+
File.open(File.join(local_path, local_file), 'r') do |file|
|
|
64
|
+
connection.put_object(
|
|
65
|
+
container, File.join(remote_path, remote_file), file
|
|
66
|
+
)
|
|
67
|
+
end
|
|
87
68
|
end
|
|
88
69
|
end
|
|
89
70
|
|
|
90
71
|
##
|
|
91
|
-
# Removes the transferred archive file from the
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
72
|
+
# Removes the transferred archive file(s) from the storage location.
|
|
73
|
+
# Any error raised will be rescued during Cycling
|
|
74
|
+
# and a warning will be logged, containing the error message.
|
|
75
|
+
def remove!(package)
|
|
76
|
+
remote_path = remote_path_for(package)
|
|
77
|
+
|
|
78
|
+
transferred_files_for(package) do |local_file, remote_file|
|
|
79
|
+
Logger.message "#{storage_name} started removing '#{ local_file }' " +
|
|
80
|
+
"from container '#{ container }'."
|
|
96
81
|
connection.delete_object(container, File.join(remote_path, remote_file))
|
|
97
82
|
end
|
|
98
83
|
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Backup
|
|
4
|
+
module Storage
|
|
5
|
+
module Cycler
|
|
6
|
+
class << self
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# Adds the given +package+ to the YAML storage file corresponding
|
|
10
|
+
# to the given +storage+ and Package#trigger (Model#trigger).
|
|
11
|
+
# Then, calls the +storage+ to remove the files for any older
|
|
12
|
+
# packages that were removed from the YAML storage file.
|
|
13
|
+
def cycle!(storage, package)
|
|
14
|
+
@storage, @package = storage, package
|
|
15
|
+
@storage_file = storage_file
|
|
16
|
+
|
|
17
|
+
update_storage_file!
|
|
18
|
+
remove_packages!
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Updates the YAML data file according to the #keep setting
|
|
25
|
+
# for the storage and sets the @packages_to_remove
|
|
26
|
+
def update_storage_file!
|
|
27
|
+
packages = yaml_load.unshift(@package)
|
|
28
|
+
excess = packages.count - @storage.keep
|
|
29
|
+
@packages_to_remove = (excess > 0) ? packages.pop(excess) : []
|
|
30
|
+
yaml_save(packages)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Calls the @storage to remove any old packages
|
|
35
|
+
# which were cycled out of the storage file.
|
|
36
|
+
def remove_packages!
|
|
37
|
+
@packages_to_remove.each do |pkg|
|
|
38
|
+
begin
|
|
39
|
+
@storage.send(:remove!, pkg)
|
|
40
|
+
rescue => err
|
|
41
|
+
Logger.warn Errors::Storage::CyclerError.wrap(err, <<-EOS)
|
|
42
|
+
There was a problem removing the following package:
|
|
43
|
+
Trigger: #{pkg.trigger} :: Dated: #{pkg.time}
|
|
44
|
+
Package included the following #{ pkg.filenames.count } file(s):
|
|
45
|
+
#{ pkg.filenames.join("\n") }
|
|
46
|
+
EOS
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Return full path to the YAML data file,
|
|
53
|
+
# based on the current values of @storage and @package
|
|
54
|
+
def storage_file
|
|
55
|
+
type = @storage.class.to_s.split('::').last
|
|
56
|
+
suffix = @storage.storage_id.to_s.strip.gsub(/[\W\s]/, '_')
|
|
57
|
+
filename = suffix.empty? ? type : "#{type}-#{suffix}"
|
|
58
|
+
File.join(Config.data_path, @package.trigger, "#{filename}.yml")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# Load Package objects from YAML file.
|
|
63
|
+
# Returns an Array, sorted by @time descending.
|
|
64
|
+
# i.e. most recent is objects[0]
|
|
65
|
+
def yaml_load
|
|
66
|
+
packages = []
|
|
67
|
+
if File.exist?(@storage_file) && !File.zero?(@storage_file)
|
|
68
|
+
packages = check_upgrade(
|
|
69
|
+
YAML.load_file(@storage_file).sort do |a, b|
|
|
70
|
+
b.instance_variable_get(:@time) <=> a.instance_variable_get(:@time)
|
|
71
|
+
end
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
packages
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
##
|
|
78
|
+
# Store the given package objects to the YAML data file.
|
|
79
|
+
def yaml_save(packages)
|
|
80
|
+
File.open(@storage_file, 'w') do |file|
|
|
81
|
+
file.write(packages.to_yaml)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# Upgrade the objects loaded from the YAML file, if needed.
|
|
87
|
+
def check_upgrade(objects)
|
|
88
|
+
if objects.any? {|obj| obj.class.to_s =~ /Backup::Storage/ }
|
|
89
|
+
# Version <= 3.0.20
|
|
90
|
+
model = @storage.instance_variable_get(:@model)
|
|
91
|
+
v3_0_20 = objects.any? {|obj| obj.instance_variable_defined?(:@version) }
|
|
92
|
+
objects.map! do |obj|
|
|
93
|
+
if v3_0_20 # Version == 3.0.20
|
|
94
|
+
filename = obj.instance_variable_get(:@filename)[20..-1]
|
|
95
|
+
chunk_suffixes = obj.instance_variable_get(:@chunk_suffixes)
|
|
96
|
+
else # Version <= 3.0.19
|
|
97
|
+
filename = obj.instance_variable_get(:@remote_file)[20..-1]
|
|
98
|
+
chunk_suffixes = []
|
|
99
|
+
end
|
|
100
|
+
time = obj.instance_variable_get(:@time)
|
|
101
|
+
extension = filename.match(/\.(tar.*)$/)[1]
|
|
102
|
+
|
|
103
|
+
package = Backup::Package.new(model)
|
|
104
|
+
package.instance_variable_set(:@time, time)
|
|
105
|
+
package.extension = extension
|
|
106
|
+
package.chunk_suffixes = chunk_suffixes
|
|
107
|
+
|
|
108
|
+
package
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
objects
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
##
|
|
4
4
|
# Only load the Dropbox gem when the Backup::Storage::Dropbox class is loaded
|
|
5
|
-
Backup::Dependency.load('dropbox')
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
# Only load the timeout library when the Backup::Storage::Dropbox class is loaded
|
|
9
|
-
require 'timeout'
|
|
5
|
+
Backup::Dependency.load('dropbox-sdk')
|
|
10
6
|
|
|
11
7
|
module Backup
|
|
12
8
|
module Storage
|
|
@@ -17,108 +13,115 @@ module Backup
|
|
|
17
13
|
attr_accessor :api_key, :api_secret
|
|
18
14
|
|
|
19
15
|
##
|
|
20
|
-
#
|
|
21
|
-
|
|
16
|
+
# Dropbox Access Type
|
|
17
|
+
# Valid values are:
|
|
18
|
+
# :app_folder (default)
|
|
19
|
+
# :dropbox (full access)
|
|
20
|
+
attr_accessor :access_type
|
|
22
21
|
|
|
23
22
|
##
|
|
24
|
-
#
|
|
25
|
-
attr_accessor :
|
|
23
|
+
# Path to where the backups will be stored
|
|
24
|
+
attr_accessor :path
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
# Deprecated as of v3.0.21 - for move to official 'dropbox-sdk' gem (v1.1)
|
|
27
|
+
def timeout=(value)
|
|
28
|
+
if value
|
|
29
|
+
Logger.warn "[DEPRECATED] Backup::Storage::Dropbox.timeout=\n" +
|
|
30
|
+
" is deprecated and will be removed at some point."
|
|
31
|
+
end
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
##
|
|
34
|
-
#
|
|
35
|
-
def
|
|
36
|
-
super
|
|
37
|
-
transfer!
|
|
38
|
-
cycle!
|
|
39
|
-
end
|
|
35
|
+
# Creates a new instance of the storage object
|
|
36
|
+
def initialize(model, storage_id = nil, &block)
|
|
37
|
+
super(model, storage_id)
|
|
40
38
|
|
|
41
|
-
private
|
|
42
|
-
|
|
43
|
-
##
|
|
44
|
-
# Set configuration defaults before evaluating configuration block,
|
|
45
|
-
# after setting defaults from Storage::Base
|
|
46
|
-
def pre_configure
|
|
47
|
-
super
|
|
48
39
|
@path ||= 'backups'
|
|
49
|
-
|
|
40
|
+
@access_type ||= :app_folder
|
|
50
41
|
|
|
51
|
-
|
|
52
|
-
# Adjust configuration after evaluating configuration block,
|
|
53
|
-
# after adjustments from Storage::Base
|
|
54
|
-
def post_configure
|
|
55
|
-
super
|
|
56
|
-
@timeout ||= 300
|
|
42
|
+
instance_eval(&block) if block_given?
|
|
57
43
|
end
|
|
58
44
|
|
|
45
|
+
private
|
|
46
|
+
|
|
59
47
|
##
|
|
60
|
-
# The initial connection to Dropbox will provide the user with an
|
|
61
|
-
# The user must open this URL and confirm that the
|
|
62
|
-
# If this is the case, then the
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
48
|
+
# The initial connection to Dropbox will provide the user with an
|
|
49
|
+
# authorization url. The user must open this URL and confirm that the
|
|
50
|
+
# authorization successfully took place. If this is the case, then the
|
|
51
|
+
# user hits 'enter' and the session will be properly established.
|
|
52
|
+
# Immediately after establishing the session, the session will be
|
|
53
|
+
# serialized and written to a cache file in Backup::Config.cache_path.
|
|
54
|
+
# The cached file will be used from that point on to re-establish a
|
|
55
|
+
# connection with Dropbox at a later time. This allows the user to avoid
|
|
56
|
+
# having to go to a new Dropbox URL to authorize over and over again.
|
|
66
57
|
def connection
|
|
67
58
|
return @connection if @connection
|
|
68
59
|
|
|
60
|
+
unless session = cached_session
|
|
61
|
+
Logger.message "Creating a new session!"
|
|
62
|
+
session = create_write_and_return_new_session!
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# will raise an error if session not authorized
|
|
66
|
+
@connection = DropboxClient.new(session, access_type)
|
|
67
|
+
|
|
68
|
+
rescue => err
|
|
69
|
+
raise Errors::Storage::Dropbox::ConnectionError.wrap(err)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
##
|
|
73
|
+
# Attempt to load a cached session
|
|
74
|
+
def cached_session
|
|
75
|
+
session = false
|
|
69
76
|
if cache_exists?
|
|
70
77
|
begin
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
rescue ArgumentError => err
|
|
77
|
-
Logger.warn Errors::Storage::Dropbox::ConnectionError.wrap(err, <<-EOS)
|
|
78
|
+
session = DropboxSession.deserialize(File.read(cached_file))
|
|
79
|
+
Logger.message "Session data loaded from cache!"
|
|
80
|
+
|
|
81
|
+
rescue => err
|
|
82
|
+
Logger.warn Errors::Storage::Dropbox::CacheError.wrap(err, <<-EOS)
|
|
78
83
|
Could not read session data from cache.
|
|
79
84
|
Cache data might be corrupt.
|
|
80
85
|
EOS
|
|
81
86
|
end
|
|
82
87
|
end
|
|
83
|
-
|
|
84
|
-
Logger.message "Creating a new session!"
|
|
85
|
-
create_write_and_return_new_session!
|
|
88
|
+
session
|
|
86
89
|
end
|
|
87
90
|
|
|
88
91
|
##
|
|
89
92
|
# Transfers the archived file to the specified Dropbox folder
|
|
90
93
|
def transfer!
|
|
91
|
-
|
|
94
|
+
remote_path = remote_path_for(@package)
|
|
95
|
+
|
|
96
|
+
files_to_transfer_for(@package) do |local_file, remote_file|
|
|
92
97
|
Logger.message "#{storage_name} started transferring '#{ local_file }'."
|
|
93
|
-
|
|
94
|
-
File.join(
|
|
95
|
-
|
|
96
|
-
:as => remote_file,
|
|
97
|
-
:timeout => timeout
|
|
98
|
-
)
|
|
98
|
+
File.open(File.join(local_path, local_file), 'r') do |file|
|
|
99
|
+
connection.put_file(File.join(remote_path, remote_file), file)
|
|
100
|
+
end
|
|
99
101
|
end
|
|
100
|
-
|
|
101
|
-
remove_instance_variable(:@connection) if instance_variable_defined?(:@connection)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
##
|
|
105
|
-
# Removes the transferred archive file from the
|
|
106
|
-
|
|
105
|
+
# Removes the transferred archive file(s) from the storage location.
|
|
106
|
+
# Any error raised will be rescued during Cycling
|
|
107
|
+
# and a warning will be logged, containing the error message.
|
|
108
|
+
def remove!(package)
|
|
109
|
+
remote_path = remote_path_for(package)
|
|
110
|
+
|
|
107
111
|
messages = []
|
|
108
|
-
|
|
109
|
-
messages << "#{storage_name} started removing
|
|
112
|
+
transferred_files_for(package) do |local_file, remote_file|
|
|
113
|
+
messages << "#{storage_name} started removing " +
|
|
114
|
+
"'#{ local_file }' from Dropbox."
|
|
110
115
|
end
|
|
111
116
|
Logger.message messages.join("\n")
|
|
112
117
|
|
|
113
|
-
connection.
|
|
114
|
-
ensure
|
|
115
|
-
remove_instance_variable(:@connection) if instance_variable_defined?(:@connection)
|
|
118
|
+
connection.file_delete(remote_path)
|
|
116
119
|
end
|
|
117
120
|
|
|
118
121
|
##
|
|
119
122
|
# Returns the path to the cached file
|
|
120
123
|
def cached_file
|
|
121
|
-
File.join(
|
|
124
|
+
File.join(Config.cache_path, api_key + api_secret)
|
|
122
125
|
end
|
|
123
126
|
|
|
124
127
|
##
|
|
@@ -139,25 +142,38 @@ module Backup
|
|
|
139
142
|
# Create a new session, write a serialized version of it to the
|
|
140
143
|
# .cache directory, and return the session object
|
|
141
144
|
def create_write_and_return_new_session!
|
|
142
|
-
|
|
143
|
-
|
|
145
|
+
require 'timeout'
|
|
146
|
+
|
|
147
|
+
session = DropboxSession.new(api_key, api_secret)
|
|
148
|
+
|
|
149
|
+
# grab the request token for session
|
|
150
|
+
session.get_request_token
|
|
144
151
|
|
|
145
|
-
template = Backup::Template.new(
|
|
152
|
+
template = Backup::Template.new(
|
|
153
|
+
{:session => session, :cached_file => cached_file}
|
|
154
|
+
)
|
|
146
155
|
template.render("storage/dropbox/authorization_url.erb")
|
|
147
156
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
# wait for user to hit 'return' to continue
|
|
158
|
+
Timeout::timeout(180) { STDIN.gets }
|
|
159
|
+
|
|
160
|
+
# this will raise an error if the user did not
|
|
161
|
+
# visit the authorization_url and grant access
|
|
162
|
+
#
|
|
163
|
+
# get the access token from the server
|
|
164
|
+
# this will be stored with the session in the cache file
|
|
165
|
+
session.get_access_token
|
|
155
166
|
|
|
156
167
|
template.render("storage/dropbox/authorized.erb")
|
|
157
168
|
write_cache!(session)
|
|
158
169
|
template.render("storage/dropbox/cache_file_written.erb")
|
|
159
170
|
|
|
160
171
|
session
|
|
172
|
+
|
|
173
|
+
rescue => err
|
|
174
|
+
raise Errors::Storage::Dropbox::AuthenticationError.wrap(
|
|
175
|
+
err, 'Could not create or authenticate a new session'
|
|
176
|
+
)
|
|
161
177
|
end
|
|
162
178
|
|
|
163
179
|
end
|