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
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module Backup
|
|
4
|
-
module Configuration
|
|
5
|
-
module Syncer
|
|
6
|
-
class RSync < Base
|
|
7
|
-
class << self
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
# Server credentials
|
|
11
|
-
attr_accessor :username, :password
|
|
12
|
-
|
|
13
|
-
##
|
|
14
|
-
# Server IP Address and SSH port
|
|
15
|
-
attr_accessor :ip
|
|
16
|
-
|
|
17
|
-
##
|
|
18
|
-
# The SSH port to connect to
|
|
19
|
-
attr_accessor :port
|
|
20
|
-
|
|
21
|
-
##
|
|
22
|
-
# Directories to sync
|
|
23
|
-
attr_accessor :directories
|
|
24
|
-
|
|
25
|
-
##
|
|
26
|
-
# Path to store the synced files/directories to
|
|
27
|
-
attr_accessor :path
|
|
28
|
-
|
|
29
|
-
##
|
|
30
|
-
# Flag for mirroring the files/directories
|
|
31
|
-
attr_accessor :mirror
|
|
32
|
-
|
|
33
|
-
##
|
|
34
|
-
# Flag for compressing (only compresses for the transfer)
|
|
35
|
-
attr_accessor :compress
|
|
36
|
-
|
|
37
|
-
##
|
|
38
|
-
# Additional options for the rsync cli
|
|
39
|
-
attr_accessor :additional_options
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
data/lib/backup/finder.rb
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module Backup
|
|
4
|
-
class Finder
|
|
5
|
-
attr_accessor :trigger, :config
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
# The wildcard character to match triggers
|
|
9
|
-
# Can be used alone or in mask (e.g. web_* )
|
|
10
|
-
WILDCARD = '*'
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
# Initializes a new Backup::Finder object
|
|
14
|
-
# and stores the path to the configuration file
|
|
15
|
-
def initialize(trigger, config = CONFIG_FILE)
|
|
16
|
-
@trigger = trigger.to_sym
|
|
17
|
-
@config = config
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
##
|
|
21
|
-
# Tries to find and return the proper
|
|
22
|
-
# backup model configuration (specified by the 'trigger')
|
|
23
|
-
def find
|
|
24
|
-
load_config!
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
# Iterates through all the instantiated backup models and returns
|
|
28
|
-
# the one that matches the specified 'trigger'
|
|
29
|
-
Backup::Model.all.each do |model|
|
|
30
|
-
if model.trigger.eql?(trigger)
|
|
31
|
-
return Backup::Model.current = model
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
raise Errors::Finder::MissingTriggerError,
|
|
36
|
-
"Could not find trigger '#{trigger}' in '#{config}'."
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
##
|
|
40
|
-
# Tries to find and return the all triggers
|
|
41
|
-
# matching wildcard (specified by the 'trigger')
|
|
42
|
-
def matching
|
|
43
|
-
##
|
|
44
|
-
# Define the TIME constants unless defined
|
|
45
|
-
::Backup.send(:const_set, :TIME, Time.now.strftime("%Y.%m.%d.%H.%M.%S")) unless defined? Backup::TIME
|
|
46
|
-
|
|
47
|
-
##
|
|
48
|
-
# Parses the backup configuration file
|
|
49
|
-
load_config!
|
|
50
|
-
|
|
51
|
-
triggers = Backup::Model.all.map{|model| model.trigger.to_s }
|
|
52
|
-
|
|
53
|
-
##
|
|
54
|
-
# Removes the TIME constant
|
|
55
|
-
::Backup.send(:remove_const, :TIME) if defined? Backup::TIME
|
|
56
|
-
|
|
57
|
-
##
|
|
58
|
-
# Make regexp replacing wildcard character by (.+)
|
|
59
|
-
wildcard = %r{^#{trigger.to_s.gsub(WILDCARD, '(.+)')}$}
|
|
60
|
-
|
|
61
|
-
##
|
|
62
|
-
# Returns all trigger names matching wildcard
|
|
63
|
-
triggers.select { |trigger| trigger =~ wildcard }
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
private
|
|
67
|
-
|
|
68
|
-
##
|
|
69
|
-
# Tries to find and load the configuration file
|
|
70
|
-
def load_config!
|
|
71
|
-
unless File.exist?(config)
|
|
72
|
-
raise Errors::Finder::MissingConfigError,
|
|
73
|
-
"Could not find configuration file: '#{config}'."
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
##
|
|
77
|
-
# Reset the Backup::Model.all to an empty array since this will be
|
|
78
|
-
# re-filled during the next Backup::Finder.new(arg1, arg2).find
|
|
79
|
-
# or Backup::Finder.new(arg).matching call
|
|
80
|
-
Backup::Model.all = Array.new
|
|
81
|
-
|
|
82
|
-
##
|
|
83
|
-
# Loads the backup configuration file
|
|
84
|
-
Backup.module_eval(File.read(config), config, 1)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module Backup
|
|
4
|
-
module Storage
|
|
5
|
-
class Object
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
# Holds the type attribute
|
|
9
|
-
attr_accessor :storage_file
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
# Instantiates a new Backup::Storage::Object and stores the
|
|
13
|
-
# full path to the storage file (yaml) in the @storage_file attribute
|
|
14
|
-
def initialize(type, storage_id)
|
|
15
|
-
suffix = storage_id.to_s.strip.gsub(/[\W\s]/, '_')
|
|
16
|
-
filename = suffix.empty? ? type : "#{type}-#{suffix}"
|
|
17
|
-
@storage_file = File.join(DATA_PATH, TRIGGER, "#{filename}.yml")
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
##
|
|
21
|
-
# Tries to load an existing YAML file and returns an
|
|
22
|
-
# array of storage objects. If no file exists, an empty
|
|
23
|
-
# array gets returned
|
|
24
|
-
#
|
|
25
|
-
# If a file is loaded it'll sort the array of objects by @time
|
|
26
|
-
# descending. The newest backup storage object comes in Backup::Storage::Object.load[0]
|
|
27
|
-
# and the oldest in Backup::Storage::Object.load[-1]
|
|
28
|
-
def load
|
|
29
|
-
objects = []
|
|
30
|
-
if File.exist?(storage_file) and not File.zero?(storage_file)
|
|
31
|
-
objects = YAML.load_file(storage_file).sort { |a,b| b.time <=> a.time }
|
|
32
|
-
end
|
|
33
|
-
objects
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
##
|
|
37
|
-
# Takes the provided objects and converts it to YAML format.
|
|
38
|
-
# The YAML data gets written to the storage file
|
|
39
|
-
def write(objects)
|
|
40
|
-
File.open(storage_file, 'w') do |file|
|
|
41
|
-
file.write(objects.to_yaml)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
data/lib/backup/syncer/rsync.rb
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
# Require the tempfile Ruby library when Backup::Syncer::RSync is loaded
|
|
5
|
-
require 'tempfile'
|
|
6
|
-
|
|
7
|
-
module Backup
|
|
8
|
-
module Syncer
|
|
9
|
-
class RSync < Base
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
# Server credentials
|
|
13
|
-
attr_accessor :username, :password
|
|
14
|
-
|
|
15
|
-
##
|
|
16
|
-
# Server IP Address and SSH port
|
|
17
|
-
attr_accessor :ip
|
|
18
|
-
|
|
19
|
-
##
|
|
20
|
-
# The SSH port to connect to
|
|
21
|
-
attr_writer :port
|
|
22
|
-
|
|
23
|
-
##
|
|
24
|
-
# Directories to sync
|
|
25
|
-
attr_writer :directories
|
|
26
|
-
|
|
27
|
-
##
|
|
28
|
-
# Path to store the synced files/directories to
|
|
29
|
-
attr_accessor :path
|
|
30
|
-
|
|
31
|
-
##
|
|
32
|
-
# Flag for mirroring the files/directories
|
|
33
|
-
attr_writer :mirror
|
|
34
|
-
|
|
35
|
-
##
|
|
36
|
-
# Flag for compressing (only compresses for the transfer)
|
|
37
|
-
attr_writer :compress
|
|
38
|
-
|
|
39
|
-
##
|
|
40
|
-
# Additional options for the rsync cli
|
|
41
|
-
attr_accessor :additional_options
|
|
42
|
-
|
|
43
|
-
##
|
|
44
|
-
# Instantiates a new RSync Syncer object and sets the default configuration
|
|
45
|
-
# specified in the Backup::Configuration::Syncer::RSync. Then it sets the object
|
|
46
|
-
# defaults if particular properties weren't set. Finally it'll evaluate the users
|
|
47
|
-
# configuration file and overwrite anything that's been defined
|
|
48
|
-
def initialize(&block)
|
|
49
|
-
load_defaults!
|
|
50
|
-
|
|
51
|
-
@directories = Array.new
|
|
52
|
-
@additional_options ||= Array.new
|
|
53
|
-
@path ||= 'backups'
|
|
54
|
-
@port ||= 22
|
|
55
|
-
@mirror ||= false
|
|
56
|
-
@compress ||= false
|
|
57
|
-
|
|
58
|
-
instance_eval(&block) if block_given?
|
|
59
|
-
write_password_file!
|
|
60
|
-
|
|
61
|
-
@path = path.sub(/^\~\//, '')
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
##
|
|
65
|
-
# Performs the RSync operation
|
|
66
|
-
# debug options: -vhP
|
|
67
|
-
def perform!
|
|
68
|
-
Logger.message("#{ self.class } started syncing #{ directories }.")
|
|
69
|
-
Logger.silent(
|
|
70
|
-
run("#{ utility(:rsync) } #{ options } #{ directories } '#{ username }@#{ ip }:#{ path }'")
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
remove_password_file!
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
##
|
|
77
|
-
# Returns all the specified Rsync options, concatenated, ready for the CLI
|
|
78
|
-
def options
|
|
79
|
-
([archive, mirror, compress, port, password] + additional_options).compact.join("\s")
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
##
|
|
83
|
-
# Returns Rsync syntax for enabling mirroring
|
|
84
|
-
def mirror
|
|
85
|
-
'--delete' if @mirror
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
##
|
|
89
|
-
# Returns Rsync syntax for compressing the file transfers
|
|
90
|
-
def compress
|
|
91
|
-
'--compress' if @compress
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
##
|
|
95
|
-
# Returns Rsync syntax for invoking "archive" mode
|
|
96
|
-
def archive
|
|
97
|
-
'--archive'
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
##
|
|
101
|
-
# Returns Rsync syntax for defining a port to connect to
|
|
102
|
-
def port
|
|
103
|
-
"-e 'ssh -p #{@port}'"
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
##
|
|
107
|
-
# Returns Rsync syntax for setting a password (via a file)
|
|
108
|
-
def password
|
|
109
|
-
"--password-file='#{@password_file.path}'" unless @password.nil?
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
##
|
|
113
|
-
# If no block has been provided, it'll return the array of @directories.
|
|
114
|
-
# If a block has been provided, it'll evaluate it and add the defined paths to the @directories
|
|
115
|
-
def directories(&block)
|
|
116
|
-
unless block_given?
|
|
117
|
-
return @directories.map do |directory|
|
|
118
|
-
"'#{directory}'"
|
|
119
|
-
end.join("\s")
|
|
120
|
-
end
|
|
121
|
-
instance_eval(&block)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
##
|
|
125
|
-
# Adds a path to the @directories array
|
|
126
|
-
def add(path)
|
|
127
|
-
@directories << path
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
private
|
|
131
|
-
|
|
132
|
-
##
|
|
133
|
-
# Writes the provided password to a temporary file so that
|
|
134
|
-
# the rsync utility can read the password from this file
|
|
135
|
-
def write_password_file!
|
|
136
|
-
unless @password.nil?
|
|
137
|
-
@password_file = Tempfile.new('backup-rsync-password')
|
|
138
|
-
@password_file.write(@password)
|
|
139
|
-
@password_file.close
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
##
|
|
144
|
-
# Removes the previously created @password_file
|
|
145
|
-
# (temporary file containing the password)
|
|
146
|
-
def remove_password_file!
|
|
147
|
-
@password_file.unlink unless @password.nil?
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
end
|
data/spec/backup_spec.rb
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
-
|
|
5
|
-
describe Backup do
|
|
6
|
-
it do
|
|
7
|
-
Backup::TMP_PATH.should == File.join(ENV['HOME'], 'Backup', '.tmp')
|
|
8
|
-
Backup::DATA_PATH.should == File.join(ENV['HOME'], 'Backup', 'data')
|
|
9
|
-
Backup::CONFIG_FILE.should == File.join(ENV['HOME'], 'Backup', 'config.rb')
|
|
10
|
-
end
|
|
11
|
-
end
|
data/spec/finder_spec.rb
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
-
|
|
5
|
-
describe Backup::Finder do
|
|
6
|
-
|
|
7
|
-
describe '#find' do
|
|
8
|
-
let(:finder) { Backup::Finder.new('test_trigger', 'foo') }
|
|
9
|
-
|
|
10
|
-
before do
|
|
11
|
-
finder.stubs(:load_config!)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it 'should return the first model that matches the trigger' do
|
|
15
|
-
models = %w{ foo1 test_trigger foo2 test_trigger }.map do |trigger|
|
|
16
|
-
stub(:trigger => trigger.to_sym)
|
|
17
|
-
end
|
|
18
|
-
Backup::Model.expects(:all).returns(models)
|
|
19
|
-
Backup::Model.expects(:current=).with(models[1])
|
|
20
|
-
|
|
21
|
-
expect do
|
|
22
|
-
finder.find.should == models[1]
|
|
23
|
-
end.not_to raise_error
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it 'should raise an error when no models match the trigger' do
|
|
27
|
-
models = %w{ foo1 foo2 foo3 }.map do |trigger|
|
|
28
|
-
stub(:trigger => trigger.to_sym)
|
|
29
|
-
end
|
|
30
|
-
Backup::Model.expects(:all).returns(models)
|
|
31
|
-
Backup::Model.expects(:current=).never
|
|
32
|
-
|
|
33
|
-
expect do
|
|
34
|
-
finder.find
|
|
35
|
-
end.to raise_error(
|
|
36
|
-
Backup::Errors::Finder::MissingTriggerError,
|
|
37
|
-
"Finder::MissingTriggerError: Could not find trigger 'test_trigger' in 'foo'."
|
|
38
|
-
)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
end # describe '#find'
|
|
42
|
-
|
|
43
|
-
describe '#load_config!' do
|
|
44
|
-
let(:finder) { Backup::Finder.new('foo', 'config_file') }
|
|
45
|
-
|
|
46
|
-
context 'when given a valid config file' do
|
|
47
|
-
|
|
48
|
-
before do
|
|
49
|
-
File.expects(:exist?).with('config_file').returns(true)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it 'should load the config file' do
|
|
53
|
-
File.expects(:read).with('config_file').returns(:file_contents)
|
|
54
|
-
Backup.expects(:module_eval).with(:file_contents, 'config_file', 1)
|
|
55
|
-
|
|
56
|
-
finder.send(:load_config!)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it 'should reset Model.all' do
|
|
60
|
-
File.stubs(:read)
|
|
61
|
-
Backup.stubs(:module_eval)
|
|
62
|
-
Backup::Model.expects(:all=).with([])
|
|
63
|
-
|
|
64
|
-
finder.send(:load_config!)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
end # context 'when given a valid config file'
|
|
68
|
-
|
|
69
|
-
context 'when given a config file that does not exist' do
|
|
70
|
-
|
|
71
|
-
before do
|
|
72
|
-
File.expects(:exist?).with('config_file').returns(false)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'should raise an error' do
|
|
76
|
-
Backup::Model.expects(:all=).never
|
|
77
|
-
File.expects(:read).never
|
|
78
|
-
Backup.expects(:module_eval).never
|
|
79
|
-
|
|
80
|
-
expect do
|
|
81
|
-
finder.send(:load_config!)
|
|
82
|
-
end.to raise_error(
|
|
83
|
-
Backup::Errors::Finder::MissingConfigError,
|
|
84
|
-
"Finder::MissingConfigError: Could not find configuration file: 'config_file'."
|
|
85
|
-
)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
end # context 'when given a config file that does not exist'
|
|
89
|
-
|
|
90
|
-
end # describe '#find'
|
|
91
|
-
end
|
data/spec/storage/object_spec.rb
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
-
|
|
5
|
-
describe Backup::Storage::Object do
|
|
6
|
-
|
|
7
|
-
describe '#initialize' do
|
|
8
|
-
|
|
9
|
-
it 'uses storage type only as YAML filename if no storage_id' do
|
|
10
|
-
[nil, '', ' '].each do |storage_id|
|
|
11
|
-
object = Backup::Storage::Object.new(:s3, storage_id)
|
|
12
|
-
object.storage_file.should == File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'appends optional storage_id' do
|
|
17
|
-
object = Backup::Storage::Object.new(:s3, 'foo')
|
|
18
|
-
object.storage_file.should == File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3-foo.yml')
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it 'sanitizes user-defined storage_id for use as filename' do
|
|
22
|
-
[ ['Backup Server #1', 'Backup_Server__1'],
|
|
23
|
-
[' {Special} Storage ', '_Special__Storage'],
|
|
24
|
-
['Cloud (!@$%^&*) #9', 'Cloud____________9'] ].each do |input, sanitized|
|
|
25
|
-
object = Backup::Storage::Object.new(:s3, input)
|
|
26
|
-
object.storage_file.should == File.join(Backup::DATA_PATH, Backup::TRIGGER, "s3-#{sanitized}.yml")
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
describe '#load' do
|
|
33
|
-
let(:storage_object) { Backup::Storage::Object.new(:s3, nil) }
|
|
34
|
-
|
|
35
|
-
it 'should return an array with objects' do
|
|
36
|
-
loaded_objects = YAML.load([Backup::Storage::S3.new, Backup::Storage::S3.new].to_yaml)
|
|
37
|
-
sorted_objects = loaded_objects.sort {|a,b| b.time <=> a.time }
|
|
38
|
-
|
|
39
|
-
File.expects(:exist?).returns(true)
|
|
40
|
-
YAML.expects(:load_file).with(
|
|
41
|
-
File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
|
|
42
|
-
).returns(loaded_objects)
|
|
43
|
-
|
|
44
|
-
objects = storage_object.load
|
|
45
|
-
objects.should be_an(Array)
|
|
46
|
-
objects.first.should be_an_instance_of(Backup::Storage::S3)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it 'should load them sorted by time descending (newest backup is first in the array)' do
|
|
50
|
-
obj_1 = Backup::Storage::S3.new; obj_1.time = '2007.00.00.00.00.00'
|
|
51
|
-
obj_2 = Backup::Storage::S3.new; obj_2.time = '2009.00.00.00.00.00'
|
|
52
|
-
obj_3 = Backup::Storage::S3.new; obj_3.time = '2011.00.00.00.00.00'
|
|
53
|
-
|
|
54
|
-
File.stubs(:exist?).returns(true)
|
|
55
|
-
File.stubs(:zero?).returns(false)
|
|
56
|
-
|
|
57
|
-
[obj_1, obj_2, obj_3].permutation.each do |perm|
|
|
58
|
-
loaded_objects = YAML.load(perm.to_yaml)
|
|
59
|
-
sorted_objects = loaded_objects.sort {|a,b| b.time <=> a.time }
|
|
60
|
-
|
|
61
|
-
YAML.expects(:load_file).with(
|
|
62
|
-
File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
|
|
63
|
-
).returns(loaded_objects)
|
|
64
|
-
|
|
65
|
-
objects = storage_object.load
|
|
66
|
-
objects[0].time.should == '2011.00.00.00.00.00'
|
|
67
|
-
objects[1].time.should == '2009.00.00.00.00.00'
|
|
68
|
-
objects[2].time.should == '2007.00.00.00.00.00'
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
end
|