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
data/lib/backup/storage/ftp.rb
CHANGED
|
@@ -25,47 +25,30 @@ module Backup
|
|
|
25
25
|
attr_accessor :passive_mode
|
|
26
26
|
|
|
27
27
|
##
|
|
28
|
-
#
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
##
|
|
34
|
-
# Performs the backup transfer
|
|
35
|
-
def perform!
|
|
36
|
-
super
|
|
37
|
-
transfer!
|
|
38
|
-
cycle!
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private
|
|
28
|
+
# Creates a new instance of the storage object
|
|
29
|
+
def initialize(model, storage_id = nil, &block)
|
|
30
|
+
super(model, storage_id)
|
|
42
31
|
|
|
43
|
-
##
|
|
44
|
-
# Set configuration defaults before evaluating configuration block,
|
|
45
|
-
# after setting defaults from Storage::Base
|
|
46
|
-
def pre_configure
|
|
47
|
-
super
|
|
48
32
|
@port ||= 21
|
|
49
33
|
@path ||= 'backups'
|
|
50
34
|
@passive_mode ||= false
|
|
51
|
-
end
|
|
52
35
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# after adjustments from Storage::Base
|
|
56
|
-
def post_configure
|
|
57
|
-
super
|
|
36
|
+
instance_eval(&block) if block_given?
|
|
37
|
+
|
|
58
38
|
@path = path.sub(/^\~\//, '')
|
|
59
39
|
end
|
|
60
40
|
|
|
41
|
+
private
|
|
42
|
+
|
|
61
43
|
##
|
|
62
|
-
# Establishes a connection to the remote server
|
|
44
|
+
# Establishes a connection to the remote server
|
|
63
45
|
#
|
|
64
|
-
# Note
|
|
65
|
-
# Since the FTP port is defined as a constant in the Net::FTP class, and
|
|
66
|
-
# to change by the user, we dynamically remove and
|
|
46
|
+
# Note:
|
|
47
|
+
# Since the FTP port is defined as a constant in the Net::FTP class, and
|
|
48
|
+
# might be required to change by the user, we dynamically remove and
|
|
49
|
+
# re-add the constant with the provided port value
|
|
67
50
|
def connection
|
|
68
|
-
if
|
|
51
|
+
if Net::FTP.const_defined?(:FTP_PORT)
|
|
69
52
|
Net::FTP.send(:remove_const, :FTP_PORT)
|
|
70
53
|
end; Net::FTP.send(:const_set, :FTP_PORT, port)
|
|
71
54
|
|
|
@@ -78,10 +61,12 @@ module Backup
|
|
|
78
61
|
##
|
|
79
62
|
# Transfers the archived file to the specified remote server
|
|
80
63
|
def transfer!
|
|
64
|
+
remote_path = remote_path_for(@package)
|
|
65
|
+
|
|
81
66
|
connection do |ftp|
|
|
82
|
-
|
|
67
|
+
create_remote_path(remote_path, ftp)
|
|
83
68
|
|
|
84
|
-
|
|
69
|
+
files_to_transfer_for(@package) do |local_file, remote_file|
|
|
85
70
|
Logger.message "#{storage_name} started transferring " +
|
|
86
71
|
"'#{ local_file }' to '#{ ip }'."
|
|
87
72
|
ftp.put(
|
|
@@ -93,10 +78,14 @@ module Backup
|
|
|
93
78
|
end
|
|
94
79
|
|
|
95
80
|
##
|
|
96
|
-
# Removes the transferred archive file from the
|
|
97
|
-
|
|
81
|
+
# Removes the transferred archive file(s) from the storage location.
|
|
82
|
+
# Any error raised will be rescued during Cycling
|
|
83
|
+
# and a warning will be logged, containing the error message.
|
|
84
|
+
def remove!(package)
|
|
85
|
+
remote_path = remote_path_for(package)
|
|
86
|
+
|
|
98
87
|
connection do |ftp|
|
|
99
|
-
|
|
88
|
+
transferred_files_for(package) do |local_file, remote_file|
|
|
100
89
|
Logger.message "#{storage_name} started removing " +
|
|
101
90
|
"'#{ local_file }' from '#{ ip }'."
|
|
102
91
|
|
|
@@ -110,11 +99,12 @@ module Backup
|
|
|
110
99
|
##
|
|
111
100
|
# Creates (if they don't exist yet) all the directories on the remote
|
|
112
101
|
# server in order to upload the backup file. Net::FTP does not support
|
|
113
|
-
# paths to directories that don't yet exist when creating new
|
|
114
|
-
# Instead, we split the parts up in to an array (for each
|
|
115
|
-
# that to create the directories one by one.
|
|
116
|
-
# the directory it's trying to create
|
|
117
|
-
|
|
102
|
+
# paths to directories that don't yet exist when creating new
|
|
103
|
+
# directories. Instead, we split the parts up in to an array (for each
|
|
104
|
+
# '/') and loop through that to create the directories one by one.
|
|
105
|
+
# Net::FTP raises an exception when the directory it's trying to create
|
|
106
|
+
# already exists, so we have rescue it
|
|
107
|
+
def create_remote_path(remote_path, ftp)
|
|
118
108
|
path_parts = Array.new
|
|
119
109
|
remote_path.split('/').each do |path_part|
|
|
120
110
|
path_parts << path_part
|
data/lib/backup/storage/local.rb
CHANGED
|
@@ -1,70 +1,54 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
# Load the Ruby FileUtils library
|
|
5
|
-
require 'fileutils'
|
|
6
|
-
|
|
7
3
|
module Backup
|
|
8
4
|
module Storage
|
|
9
5
|
class Local < Base
|
|
10
6
|
|
|
11
7
|
##
|
|
12
|
-
# Path
|
|
8
|
+
# Path where the backup will be stored.
|
|
13
9
|
attr_accessor :path
|
|
14
10
|
|
|
15
11
|
##
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def remote_path
|
|
20
|
-
File.join(path, TRIGGER, @time)
|
|
21
|
-
end
|
|
12
|
+
# Creates a new instance of the storage object
|
|
13
|
+
def initialize(model, storage_id = nil, &block)
|
|
14
|
+
super(model, storage_id)
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
transfer!
|
|
28
|
-
cycle!
|
|
29
|
-
end
|
|
16
|
+
@path ||= File.join(
|
|
17
|
+
File.expand_path(ENV['HOME'] || ''),
|
|
18
|
+
'backups'
|
|
19
|
+
)
|
|
30
20
|
|
|
31
|
-
|
|
21
|
+
instance_eval(&block) if block_given?
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
# Set configuration defaults before evaluating configuration block,
|
|
35
|
-
# after setting defaults from Storage::Base
|
|
36
|
-
def pre_configure
|
|
37
|
-
super
|
|
38
|
-
@path ||= "#{ENV['HOME']}/backups"
|
|
23
|
+
@path = File.expand_path(@path)
|
|
39
24
|
end
|
|
40
25
|
|
|
41
|
-
|
|
42
|
-
# Adjust configuration after evaluating configuration block,
|
|
43
|
-
# after adjustments from Storage::Base
|
|
44
|
-
def post_configure
|
|
45
|
-
super
|
|
46
|
-
@path = File.expand_path(path)
|
|
47
|
-
end
|
|
26
|
+
private
|
|
48
27
|
|
|
49
28
|
##
|
|
50
|
-
# Transfers the archived file to the specified
|
|
29
|
+
# Transfers the archived file to the specified path
|
|
51
30
|
def transfer!
|
|
52
|
-
|
|
31
|
+
remote_path = remote_path_for(@package)
|
|
32
|
+
FileUtils.mkdir_p(remote_path)
|
|
53
33
|
|
|
54
|
-
|
|
34
|
+
files_to_transfer_for(@package) do |local_file, remote_file|
|
|
55
35
|
Logger.message "#{storage_name} started transferring '#{ local_file }'."
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
36
|
+
|
|
37
|
+
src_path = File.join(local_path, local_file)
|
|
38
|
+
dst_path = File.join(remote_path, remote_file)
|
|
39
|
+
FileUtils.send(transfer_method, src_path, dst_path)
|
|
60
40
|
end
|
|
61
41
|
end
|
|
62
42
|
|
|
63
43
|
##
|
|
64
|
-
# Removes the transferred archive file from the
|
|
65
|
-
|
|
44
|
+
# Removes the transferred archive file(s) from the storage location.
|
|
45
|
+
# Any error raised will be rescued during Cycling
|
|
46
|
+
# and a warning will be logged, containing the error message.
|
|
47
|
+
def remove!(package)
|
|
48
|
+
remote_path = remote_path_for(package)
|
|
49
|
+
|
|
66
50
|
messages = []
|
|
67
|
-
|
|
51
|
+
transferred_files_for(package) do |local_file, remote_file|
|
|
68
52
|
messages << "#{storage_name} started removing '#{ local_file }'."
|
|
69
53
|
end
|
|
70
54
|
Logger.message messages.join("\n")
|
|
@@ -73,9 +57,24 @@ module Backup
|
|
|
73
57
|
end
|
|
74
58
|
|
|
75
59
|
##
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
|
|
60
|
+
# Set and return the transfer method.
|
|
61
|
+
# If this Local Storage is not the last Storage for the Model,
|
|
62
|
+
# force the transfer to use a *copy* operation and issue a warning.
|
|
63
|
+
def transfer_method
|
|
64
|
+
return @transfer_method if @transfer_method
|
|
65
|
+
|
|
66
|
+
if self == @model.storages.last
|
|
67
|
+
@transfer_method = :mv
|
|
68
|
+
else
|
|
69
|
+
Logger.warn Errors::Storage::Local::TransferError.new(<<-EOS)
|
|
70
|
+
Local File Copy Warning!
|
|
71
|
+
The final backup file(s) for '#{@model.label}' (#{@model.trigger})
|
|
72
|
+
will be *copied* to '#{remote_path_for(@package)}'
|
|
73
|
+
To avoid this, when using more than one Storage, the 'Local' Storage
|
|
74
|
+
should be added *last* so the files may be *moved* to their destination.
|
|
75
|
+
EOS
|
|
76
|
+
@transfer_method = :cp
|
|
77
|
+
end
|
|
79
78
|
end
|
|
80
79
|
|
|
81
80
|
end
|
|
@@ -17,48 +17,26 @@ module Backup
|
|
|
17
17
|
attr_accessor :path
|
|
18
18
|
|
|
19
19
|
##
|
|
20
|
-
#
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
end
|
|
20
|
+
# Creates a new instance of the storage object
|
|
21
|
+
def initialize(model, storage_id = nil, &block)
|
|
22
|
+
super(model, storage_id)
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
# This is the provider that Fog uses for the Ninefold storage
|
|
27
|
-
def provider
|
|
28
|
-
'Ninefold'
|
|
29
|
-
end
|
|
24
|
+
@path ||= 'backups'
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
# Performs the backup transfer
|
|
33
|
-
def perform!
|
|
34
|
-
super
|
|
35
|
-
transfer!
|
|
36
|
-
cycle!
|
|
26
|
+
instance_eval(&block) if block_given?
|
|
37
27
|
end
|
|
38
28
|
|
|
39
|
-
private
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
# Set configuration defaults before evaluating configuration block,
|
|
43
|
-
# after setting defaults from Storage::Base
|
|
44
|
-
def pre_configure
|
|
45
|
-
super
|
|
46
|
-
@path ||= 'backups'
|
|
47
|
-
end
|
|
30
|
+
private
|
|
48
31
|
|
|
49
32
|
##
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
super
|
|
33
|
+
# This is the provider that Fog uses for the Ninefold storage
|
|
34
|
+
def provider
|
|
35
|
+
'Ninefold'
|
|
54
36
|
end
|
|
55
37
|
|
|
56
38
|
##
|
|
57
|
-
# Establishes a connection to Amazon S3
|
|
58
|
-
# Not doing any instance variable caching because this object gets persisted in YAML
|
|
59
|
-
# format to a file and will issues. This, however has no impact on performance since it only
|
|
60
|
-
# gets invoked once per object for a #transfer! and once for a remove! Backups run in the
|
|
61
|
-
# background anyway so even if it were a bit slower it shouldn't matter.
|
|
39
|
+
# Establishes a connection to Amazon S3
|
|
62
40
|
def connection
|
|
63
41
|
@connection ||= Fog::Storage.new(
|
|
64
42
|
:provider => provider,
|
|
@@ -67,41 +45,69 @@ module Backup
|
|
|
67
45
|
)
|
|
68
46
|
end
|
|
69
47
|
|
|
48
|
+
##
|
|
49
|
+
# Queries the connection for the directory for the given +remote_path+
|
|
50
|
+
# Returns nil if not found, or creates the directory if +create+ is true.
|
|
51
|
+
def directory_for(remote_path, create = false)
|
|
52
|
+
directory = connection.directories.get(remote_path)
|
|
53
|
+
if directory.nil? && create
|
|
54
|
+
directory = connection.directories.create(:key => remote_path)
|
|
55
|
+
end
|
|
56
|
+
directory
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def remote_path_for(package)
|
|
60
|
+
super(package).sub(/^\//, '')
|
|
61
|
+
end
|
|
62
|
+
|
|
70
63
|
##
|
|
71
64
|
# Transfers the archived file to the specified directory
|
|
72
65
|
def transfer!
|
|
73
|
-
|
|
66
|
+
remote_path = remote_path_for(@package)
|
|
67
|
+
|
|
68
|
+
directory = directory_for(remote_path, true)
|
|
69
|
+
|
|
70
|
+
files_to_transfer_for(@package) do |local_file, remote_file|
|
|
74
71
|
Logger.message "#{storage_name} started transferring '#{ local_file }'."
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
:body => File.open(File.join(local_path, local_file))
|
|
80
|
-
)
|
|
72
|
+
|
|
73
|
+
File.open(File.join(local_path, local_file), 'r') do |file|
|
|
74
|
+
directory.files.create(:key => remote_file, :body => file)
|
|
75
|
+
end
|
|
81
76
|
end
|
|
82
77
|
end
|
|
83
78
|
|
|
84
79
|
##
|
|
85
|
-
# Removes the transferred archive file from the
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
# Removes the transferred archive file(s) from the storage location.
|
|
81
|
+
# Any error raised will be rescued during Cycling
|
|
82
|
+
# and a warning will be logged, containing the error message.
|
|
83
|
+
def remove!(package)
|
|
84
|
+
remote_path = remote_path_for(package)
|
|
85
|
+
|
|
86
|
+
if directory = directory_for(remote_path)
|
|
87
|
+
not_found = []
|
|
88
|
+
|
|
89
|
+
transferred_files_for(package) do |local_file, remote_file|
|
|
89
90
|
Logger.message "#{storage_name} started removing " +
|
|
90
|
-
"'#{ local_file }' from Ninefold.
|
|
91
|
+
"'#{ local_file }' from Ninefold."
|
|
91
92
|
|
|
92
93
|
if file = directory.files.get(remote_file)
|
|
93
94
|
file.destroy
|
|
94
95
|
else
|
|
95
|
-
|
|
96
|
-
raise Errors::Storage::Ninefold::NotFoundError,
|
|
97
|
-
"'#{remote_file}' not found in '#{remote_path}'", caller(1)
|
|
96
|
+
not_found << remote_file
|
|
98
97
|
end
|
|
99
98
|
end
|
|
99
|
+
|
|
100
100
|
directory.destroy
|
|
101
|
+
|
|
102
|
+
unless not_found.empty?
|
|
103
|
+
raise Errors::Storage::Ninefold::NotFoundError, <<-EOS
|
|
104
|
+
The following file(s) were not found in '#{ remote_path }'
|
|
105
|
+
#{ not_found.join("\n") }
|
|
106
|
+
EOS
|
|
107
|
+
end
|
|
101
108
|
else
|
|
102
|
-
# Note: Fog-0.11.0 will return nil if remote_path is not found
|
|
103
109
|
raise Errors::Storage::Ninefold::NotFoundError,
|
|
104
|
-
"Directory at '#{remote_path}' not found"
|
|
110
|
+
"Directory at '#{remote_path}' not found"
|
|
105
111
|
end
|
|
106
112
|
end
|
|
107
113
|
|
data/lib/backup/storage/rsync.rb
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
# Require the tempfile Ruby library when Backup::Storage::RSync is loaded
|
|
5
|
-
require 'tempfile'
|
|
6
|
-
|
|
7
3
|
##
|
|
8
4
|
# Only load the Net::SSH library when the Backup::Storage::RSync class is loaded
|
|
9
5
|
Backup::Dependency.load('net-ssh')
|
|
@@ -30,83 +26,79 @@ module Backup
|
|
|
30
26
|
attr_accessor :local
|
|
31
27
|
|
|
32
28
|
##
|
|
33
|
-
#
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
##
|
|
39
|
-
# Performs the backup transfer
|
|
40
|
-
def perform!
|
|
41
|
-
super
|
|
42
|
-
write_password_file!
|
|
43
|
-
transfer!
|
|
44
|
-
ensure
|
|
45
|
-
remove_password_file!
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
private
|
|
29
|
+
# Creates a new instance of the storage object
|
|
30
|
+
def initialize(model, storage_id = nil, &block)
|
|
31
|
+
super(model, storage_id)
|
|
49
32
|
|
|
50
|
-
##
|
|
51
|
-
# Set configuration defaults before evaluating configuration block,
|
|
52
|
-
# after setting defaults from Storage::Base
|
|
53
|
-
def pre_configure
|
|
54
|
-
super
|
|
55
33
|
@port ||= 22
|
|
56
34
|
@path ||= 'backups'
|
|
57
35
|
@local ||= false
|
|
36
|
+
|
|
37
|
+
instance_eval(&block) if block_given?
|
|
38
|
+
|
|
39
|
+
@path = path.sub(/^\~\//, '')
|
|
58
40
|
end
|
|
59
41
|
|
|
42
|
+
private
|
|
43
|
+
|
|
60
44
|
##
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
45
|
+
# This is the remote path to where the backup files will be stored
|
|
46
|
+
#
|
|
47
|
+
# Note: This overrides the superclass' method
|
|
48
|
+
def remote_path_for(package)
|
|
49
|
+
File.join(path, package.trigger)
|
|
66
50
|
end
|
|
67
51
|
|
|
68
52
|
##
|
|
69
|
-
# Establishes a connection to the remote server
|
|
53
|
+
# Establishes a connection to the remote server
|
|
70
54
|
def connection
|
|
71
|
-
Net::SSH.start(
|
|
72
|
-
|
|
73
|
-
|
|
55
|
+
Net::SSH.start(
|
|
56
|
+
ip, username, :password => password, :port => port
|
|
57
|
+
) {|ssh| yield ssh }
|
|
74
58
|
end
|
|
75
59
|
|
|
76
60
|
##
|
|
77
61
|
# Transfers the archived file to the specified remote server
|
|
78
62
|
def transfer!
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
63
|
+
write_password_file! unless local
|
|
64
|
+
|
|
65
|
+
remote_path = remote_path_for(@package)
|
|
66
|
+
|
|
67
|
+
create_remote_path!(remote_path)
|
|
68
|
+
|
|
69
|
+
files_to_transfer_for(@package) do |local_file, remote_file|
|
|
70
|
+
if local
|
|
71
|
+
Logger.message "#{storage_name} started transferring " +
|
|
72
|
+
"'#{ local_file }' to '#{ remote_path }'."
|
|
73
|
+
run(
|
|
74
|
+
"#{ utility(:rsync) } '#{ File.join(local_path, local_file) }' " +
|
|
75
|
+
"'#{ File.join(remote_path, remote_file) }'"
|
|
76
|
+
)
|
|
77
|
+
else
|
|
78
|
+
Logger.message "#{storage_name} started transferring " +
|
|
79
|
+
"'#{ local_file }' to '#{ ip }'."
|
|
80
|
+
run(
|
|
81
|
+
"#{ utility(:rsync) } #{ rsync_options } #{ rsync_port } " +
|
|
82
|
+
"#{ rsync_password_file } '#{ File.join(local_path, local_file) }' " +
|
|
83
|
+
"'#{ username }@#{ ip }:#{ File.join(remote_path, remote_file) }'"
|
|
84
|
+
)
|
|
85
|
+
end
|
|
95
86
|
end
|
|
87
|
+
|
|
88
|
+
ensure
|
|
89
|
+
remove_password_file! unless local
|
|
96
90
|
end
|
|
97
91
|
|
|
98
92
|
##
|
|
99
|
-
# Note: RSync
|
|
100
|
-
def remove
|
|
101
|
-
nil
|
|
102
|
-
end
|
|
93
|
+
# Note: Storage::RSync doesn't cycle
|
|
94
|
+
def remove!; end
|
|
103
95
|
|
|
104
96
|
##
|
|
105
97
|
# Creates (if they don't exist yet) all the directories on the remote
|
|
106
98
|
# server in order to upload the backup file.
|
|
107
|
-
def
|
|
99
|
+
def create_remote_path!(remote_path)
|
|
108
100
|
if @local
|
|
109
|
-
|
|
101
|
+
FileUtils.mkdir_p(remote_path)
|
|
110
102
|
else
|
|
111
103
|
connection do |ssh|
|
|
112
104
|
ssh.exec!("mkdir -p '#{ remote_path }'")
|
|
@@ -130,6 +122,7 @@ module Backup
|
|
|
130
122
|
# (temporary file containing the password)
|
|
131
123
|
def remove_password_file!
|
|
132
124
|
@password_file.delete if @password_file
|
|
125
|
+
@password_file = nil
|
|
133
126
|
end
|
|
134
127
|
|
|
135
128
|
##
|