backup 3.0.6 → 3.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/backup.gemspec +9 -6
- data/bin/backup +53 -21
- data/lib/backup.rb +4 -1
- data/lib/backup/configuration/storage/dropbox.rb +4 -0
- data/lib/backup/configuration/syncer/s3.rb +29 -0
- data/lib/backup/storage/dropbox.rb +6 -1
- data/lib/backup/syncer/base.rb +10 -0
- data/lib/backup/syncer/rsync.rb +6 -8
- data/lib/backup/syncer/s3.rb +111 -0
- data/lib/backup/version.rb +1 -1
- data/lib/templates/storage/dropbox +1 -0
- data/lib/templates/syncer/s3 +12 -0
- data/spec/configuration/storage/dropbox_spec.rb +3 -0
- data/spec/storage/dropbox_spec.rb +17 -1
- data/spec/syncer/rsync_spec.rb +5 -5
- data/spec/syncer/s3_spec.rb +131 -0
- metadata +55 -9
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Backup 3
|
2
2
|
========
|
3
3
|
|
4
|
-
Backup is a RubyGem (for UNIX-like operating systems: Linux, Mac OSX) that allows you to configure and perform backups in a simple manner using an elegant Ruby DSL. It supports various databases (MySQL, PostgreSQL, MongoDB and Redis), it supports various storage locations (Amazon S3, Rackspace Cloud Files, Dropbox, any remote server through FTP, SFTP, SCP and RSync), it can archive files and directories, it can cycle backups, it can do incremental backups, it can compress backups, it can encrypt backups (OpenSSL or GPG), it can notify you about successful and/or failed backups (Email or Twitter). It is very extensible and easy to add new functionality to. It's easy to use.
|
4
|
+
Backup is a RubyGem (for UNIX-like operating systems: Linux, Mac OSX) that allows you to configure and perform backups in a simple manner using an elegant Ruby DSL. It supports various databases (MySQL, PostgreSQL, MongoDB and Redis), it supports various storage locations (Amazon S3, Rackspace Cloud Files, Dropbox, any remote server through FTP, SFTP, SCP and RSync), it provide Syncers (RSync, S3) for efficient backups, it can archive files and directories, it can cycle backups, it can do incremental backups, it can compress backups, it can encrypt backups (OpenSSL or GPG), it can notify you about successful and/or failed backups (Email or Twitter). It is very extensible and easy to add new functionality to. It's easy to use.
|
5
5
|
|
6
6
|
Author
|
7
7
|
------
|
@@ -248,7 +248,7 @@ Contributors
|
|
248
248
|
</tr>
|
249
249
|
<tr>
|
250
250
|
<td><a href="https://github.com/asanghi" target="_blank">Aditya Sanghi ( asanghi )</a></td>
|
251
|
-
<td>Twitter Notifier</td>
|
251
|
+
<td>Twitter Notifier, Dropbox Timeout Configuration</td>
|
252
252
|
</tr>
|
253
253
|
<tr>
|
254
254
|
<td><a href="https://github.com/phlipper" target="_blank">Phil Cohen ( phlipper )</a></td>
|
data/backup.gemspec
CHANGED
@@ -12,12 +12,15 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.authors = 'Michael van Rooijen'
|
13
13
|
gem.email = 'meskyanichi@gmail.com'
|
14
14
|
gem.homepage = 'http://rubygems.org/gems/backup'
|
15
|
-
gem.summary = 'Backup is a RubyGem (for UNIX-like operating systems: Linux, Mac OSX)
|
16
|
-
|
17
|
-
It supports various databases (MySQL, PostgreSQL, MongoDB and Redis),
|
18
|
-
(Amazon S3, Rackspace Cloud Files, Dropbox, any remote
|
19
|
-
|
20
|
-
it can
|
15
|
+
gem.summary = 'Backup is a RubyGem (for UNIX-like operating systems: Linux, Mac OSX)
|
16
|
+
that allows you to configure and perform backups in a simple manner using
|
17
|
+
an elegant Ruby DSL. It supports various databases (MySQL, PostgreSQL, MongoDB and Redis),
|
18
|
+
it supports various storage locations (Amazon S3, Rackspace Cloud Files, Dropbox, any remote
|
19
|
+
server through FTP, SFTP, SCP and RSync), it provide Syncers (RSync, S3) for efficient backups,
|
20
|
+
it can archive files and directories, it can cycle backups, it can do incremental backups, it
|
21
|
+
can compress backups, it can encrypt backups (OpenSSL or GPG), it can notify you about
|
22
|
+
successful and/or failed backups (Email or Twitter). It is very extensible and easy to add new
|
23
|
+
functionality to. It\'s easy to use.'
|
21
24
|
|
22
25
|
##
|
23
26
|
# Files and folder that need to be compiled in to the Ruby Gem
|
data/bin/backup
CHANGED
@@ -31,19 +31,17 @@ class BackupCLI < Thor
|
|
31
31
|
# Performs the backup process. The only required option is the --trigger [-t].
|
32
32
|
# If the other options (--config_file, --data_path, --tmp_path) aren't specified
|
33
33
|
# it'll fallback to the (good) defaults
|
34
|
-
method_option :trigger, :type => :string, :aliases => '-t', :required => true
|
34
|
+
method_option :trigger, :type => :string, :aliases => ['-t', '--triggers'], :required => true
|
35
35
|
method_option :config_file, :type => :string, :aliases => '-c'
|
36
36
|
method_option :data_path, :type => :string, :aliases => '-d'
|
37
37
|
method_option :log_path, :type => :string, :aliases => '-l'
|
38
38
|
method_option :tmp_path, :type => :string
|
39
|
-
desc 'perform',
|
39
|
+
desc 'perform', "Performs the backup for the specified trigger.\n" +
|
40
|
+
"You may perform multiple backups by providing multiple triggers, separated by commas.\n\n" +
|
41
|
+
"Example:\n\s\s$ backup perform --triggers backup1,backup2,backup3,backup4\n\n" +
|
42
|
+
"This will invoke 4 backups, and they will run in the order specified (not asynchronous)."
|
40
43
|
def perform
|
41
44
|
|
42
|
-
##
|
43
|
-
# Defines the TRIGGER and TIME constants
|
44
|
-
Backup.send(:const_set, :TRIGGER, options[:trigger])
|
45
|
-
Backup.send(:const_set, :TIME, Time.now.strftime("%Y.%m.%d.%H.%M.%S"))
|
46
|
-
|
47
45
|
##
|
48
46
|
# Overwrites the CONFIG_FILE location, if --config-file was specified
|
49
47
|
if options[:config_file]
|
@@ -73,24 +71,58 @@ class BackupCLI < Thor
|
|
73
71
|
end
|
74
72
|
|
75
73
|
##
|
76
|
-
# Ensure the TMP_PATH
|
77
|
-
|
78
|
-
Array.new([
|
79
|
-
Backup::TMP_PATH,
|
80
|
-
Backup::LOG_PATH,
|
81
|
-
File.join(Backup::DATA_PATH, Backup::TRIGGER)
|
82
|
-
]).each do |path|
|
74
|
+
# Ensure the TMP_PATH and LOG_PATH are created if they do not yet exist
|
75
|
+
Array.new([Backup::TMP_PATH, Backup::LOG_PATH]).each do |path|
|
83
76
|
FileUtils.mkdir_p(path)
|
84
77
|
end
|
85
78
|
|
86
79
|
##
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
80
|
+
# Process each trigger
|
81
|
+
options[:trigger].split(",").map(&:strip).each do |trigger|
|
82
|
+
|
83
|
+
##
|
84
|
+
# Defines the TRIGGER constant
|
85
|
+
Backup.send(:const_set, :TRIGGER, trigger)
|
86
|
+
|
87
|
+
##
|
88
|
+
# Define the TIME constants
|
89
|
+
Backup.send(:const_set, :TIME, Time.now.strftime("%Y.%m.%d.%H.%M.%S"))
|
90
|
+
|
91
|
+
##
|
92
|
+
# Ensure DATA_PATH and DATA_PATH/TRIGGER are created if they do not yet exist
|
93
|
+
FileUtils.mkdir_p(File.join(Backup::DATA_PATH, Backup::TRIGGER))
|
94
|
+
|
95
|
+
##
|
96
|
+
# Parses the backup configuration file and returns the model instance by trigger
|
97
|
+
model = Backup::Finder.new(trigger, Backup::CONFIG_FILE).find
|
98
|
+
|
99
|
+
##
|
100
|
+
# Runs the returned model
|
101
|
+
Backup::Logger.message "Performing backup for #{model.label}!"
|
102
|
+
model.perform!
|
103
|
+
|
104
|
+
##
|
105
|
+
# Removes the TRIGGER constant
|
106
|
+
Backup.send(:remove_const, :TRIGGER) if defined? Backup::TRIGGER
|
107
|
+
|
108
|
+
##
|
109
|
+
# Removes the TIME constant
|
110
|
+
Backup.send(:remove_const, :TIME) if defined? Backup::TIME
|
111
|
+
|
112
|
+
##
|
113
|
+
# Reset the Backup::Model.current to nil for the next potential run
|
114
|
+
Backup::Model.current = nil
|
115
|
+
|
116
|
+
##
|
117
|
+
# Reset the Backup::Model.all to an empty array since this will be
|
118
|
+
# re-filled during the next Backup::Finder.new(arg1, arg2).find
|
119
|
+
Backup::Model.all = Array.new
|
120
|
+
|
121
|
+
##
|
122
|
+
# Reset the Backup::Model.extension to 'tar' so it's at it's
|
123
|
+
# initial state when the next Backup::Model initializes
|
124
|
+
Backup::Model.extension = 'tar'
|
125
|
+
end
|
94
126
|
end
|
95
127
|
|
96
128
|
##
|
data/lib/backup.rb
CHANGED
@@ -20,7 +20,7 @@ module Backup
|
|
20
20
|
STORAGES = ['S3', 'CloudFiles', 'Dropbox', 'FTP', 'SFTP', 'SCP', 'RSync']
|
21
21
|
COMPRESSORS = ['Gzip']
|
22
22
|
ENCRYPTORS = ['OpenSSL', 'GPG']
|
23
|
-
SYNCERS = ['RSync']
|
23
|
+
SYNCERS = ['RSync', 'S3']
|
24
24
|
NOTIFIERS = ['Mail', 'Twitter']
|
25
25
|
|
26
26
|
##
|
@@ -87,6 +87,7 @@ module Backup
|
|
87
87
|
|
88
88
|
module Syncer
|
89
89
|
autoload :RSync, File.join(CONFIGURATION_PATH, 'syncer', 'rsync')
|
90
|
+
autoload :S3, File.join(CONFIGURATION_PATH, 'syncer', 's3')
|
90
91
|
end
|
91
92
|
|
92
93
|
module Database
|
@@ -115,7 +116,9 @@ module Backup
|
|
115
116
|
##
|
116
117
|
# Autoload Backup syncer files
|
117
118
|
module Syncer
|
119
|
+
autoload :Base, File.join(SYNCER_PATH, 'base')
|
118
120
|
autoload :RSync, File.join(SYNCER_PATH, 'rsync')
|
121
|
+
autoload :S3, File.join(SYNCER_PATH, 's3')
|
119
122
|
end
|
120
123
|
|
121
124
|
##
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Backup
|
4
|
+
module Configuration
|
5
|
+
module Syncer
|
6
|
+
class S3 < Base
|
7
|
+
class << self
|
8
|
+
|
9
|
+
##
|
10
|
+
# Amazon Simple Storage Service (S3) Credentials
|
11
|
+
attr_accessor :access_key_id, :secret_access_key
|
12
|
+
|
13
|
+
##
|
14
|
+
# Amazon S3 bucket name and path to sync to
|
15
|
+
attr_accessor :bucket, :path
|
16
|
+
|
17
|
+
##
|
18
|
+
# Directories to sync
|
19
|
+
attr_accessor :directories
|
20
|
+
|
21
|
+
##
|
22
|
+
# Flag to enable mirroring
|
23
|
+
attr_accessor :mirror
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -20,6 +20,10 @@ module Backup
|
|
20
20
|
# Path to where the backups will be stored
|
21
21
|
attr_accessor :path
|
22
22
|
|
23
|
+
##
|
24
|
+
# Dropbox connection timeout
|
25
|
+
attr_accessor :timeout
|
26
|
+
|
23
27
|
##
|
24
28
|
# Creates a new instance of the Dropbox storage object
|
25
29
|
# First it sets the defaults (if any exist) and then evaluates
|
@@ -31,6 +35,7 @@ module Backup
|
|
31
35
|
|
32
36
|
instance_eval(&block) if block_given?
|
33
37
|
|
38
|
+
@timeout ||= 300
|
34
39
|
@time = TIME
|
35
40
|
end
|
36
41
|
|
@@ -68,7 +73,7 @@ module Backup
|
|
68
73
|
# Transfers the archived file to the specified Dropbox folder
|
69
74
|
def transfer!
|
70
75
|
Logger.message("#{ self.class } started transferring \"#{ remote_file }\".")
|
71
|
-
connection.upload(File.join(local_path, local_file), remote_path, :timeout =>
|
76
|
+
connection.upload(File.join(local_path, local_file), remote_path, :timeout => timeout)
|
72
77
|
end
|
73
78
|
|
74
79
|
##
|
data/lib/backup/syncer/rsync.rb
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
module Backup
|
4
4
|
module Syncer
|
5
|
-
class RSync
|
6
|
-
include Backup::CLI
|
7
|
-
include Backup::Configuration::Helpers
|
5
|
+
class RSync < Base
|
8
6
|
|
9
7
|
##
|
10
8
|
# Server credentials
|
@@ -73,25 +71,25 @@ module Backup
|
|
73
71
|
end
|
74
72
|
|
75
73
|
##
|
76
|
-
# Returns Rsync syntax for
|
74
|
+
# Returns Rsync syntax for enabling mirroring
|
77
75
|
def mirror
|
78
76
|
'--delete' if @mirror
|
79
77
|
end
|
80
78
|
|
81
79
|
##
|
82
|
-
# Returns Rsync syntax for
|
80
|
+
# Returns Rsync syntax for compressing the file transfers
|
83
81
|
def compress
|
84
|
-
'
|
82
|
+
'--compress' if @compress
|
85
83
|
end
|
86
84
|
|
87
85
|
##
|
88
|
-
# Returns Rsync syntax for
|
86
|
+
# Returns Rsync syntax for invoking "archive" mode
|
89
87
|
def archive
|
90
88
|
'--archive'
|
91
89
|
end
|
92
90
|
|
93
91
|
##
|
94
|
-
# Returns Rsync syntax for
|
92
|
+
# Returns Rsync syntax for defining a port to connect to
|
95
93
|
def port
|
96
94
|
"--port='#{@port}'"
|
97
95
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Backup
|
4
|
+
module Syncer
|
5
|
+
class S3 < Base
|
6
|
+
|
7
|
+
##
|
8
|
+
# Amazon Simple Storage Service (S3) Credentials
|
9
|
+
attr_accessor :access_key_id, :secret_access_key
|
10
|
+
|
11
|
+
##
|
12
|
+
# Amazon S3 bucket name and path to sync to
|
13
|
+
attr_accessor :bucket, :path
|
14
|
+
|
15
|
+
##
|
16
|
+
# Directories to sync
|
17
|
+
attr_accessor :directories
|
18
|
+
|
19
|
+
##
|
20
|
+
# Flag to enable mirroring
|
21
|
+
attr_accessor :mirror
|
22
|
+
|
23
|
+
##
|
24
|
+
# Instantiates a new S3 Syncer object and sets the default configuration
|
25
|
+
# specified in the Backup::Configuration::Syncer::S3. Then it sets the object
|
26
|
+
# defaults if particular properties weren't set. Finally it'll evaluate the users
|
27
|
+
# configuration file and overwrite anything that's been defined
|
28
|
+
def initialize(&block)
|
29
|
+
load_defaults!
|
30
|
+
|
31
|
+
@path ||= 'backups'
|
32
|
+
@directories ||= Array.new
|
33
|
+
@mirror ||= false
|
34
|
+
|
35
|
+
instance_eval(&block) if block_given?
|
36
|
+
|
37
|
+
@path = path.sub(/^\//, '')
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Performs the S3Sync operation
|
42
|
+
# First it'll set the Amazon S3 credentials for S3Sync before invoking it,
|
43
|
+
# and once it's finished syncing the files and directories to Amazon S3, it'll
|
44
|
+
# unset these credentials (back to nil values)
|
45
|
+
def perform!
|
46
|
+
set_s3sync_credentials!
|
47
|
+
|
48
|
+
directories.each do |directory|
|
49
|
+
Logger.message("#{ self.class } started syncing '#{ directory }'.")
|
50
|
+
Logger.silent( run("#{ utility(:s3sync) } #{ options } '#{ directory }' '#{ bucket }:#{ path }'") )
|
51
|
+
end
|
52
|
+
|
53
|
+
unset_s3sync_credentials!
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Returns all the specified S3Sync options, concatenated, ready for the CLI
|
58
|
+
def options
|
59
|
+
[verbose, recursive, mirror].compact.join("\s")
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Returns S3Sync syntax for enabling mirroring
|
64
|
+
def mirror
|
65
|
+
'--delete' if @mirror
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Returns S3Sync syntax for syncing recursively
|
70
|
+
def recursive
|
71
|
+
'--recursive'
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Returns S3Sync syntax for making output verbose
|
76
|
+
def verbose
|
77
|
+
'--verbose'
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Syntactical suger for the DSL for adding directories
|
82
|
+
def directories(&block)
|
83
|
+
return @directories unless block_given?
|
84
|
+
instance_eval(&block)
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Adds a path to the @directories array
|
89
|
+
def add(path)
|
90
|
+
@directories << path
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# In order for S3Sync to know what credentials to use, we have to set the
|
95
|
+
# AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, these
|
96
|
+
# evironment variables will be used by S3Sync
|
97
|
+
def set_s3sync_credentials!
|
98
|
+
ENV['AWS_ACCESS_KEY_ID'] = access_key_id
|
99
|
+
ENV['AWS_SECRET_ACCESS_KEY'] = secret_access_key
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Sets the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY back to nil
|
104
|
+
def unset_s3sync_credentials!
|
105
|
+
ENV['AWS_ACCESS_KEY_ID'] = nil
|
106
|
+
ENV['AWS_SECRET_ACCESS_KEY'] = nil
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/backup/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
sync_with S3 do |s3|
|
2
|
+
s3.access_key_id = "my_access_key_id"
|
3
|
+
s3.secret_access_key = "my_secret_access_key"
|
4
|
+
s3.bucket = "my-bucket"
|
5
|
+
s3.path = "/backups"
|
6
|
+
s3.mirror = true
|
7
|
+
|
8
|
+
s3.directories do |directory|
|
9
|
+
directory.add "/path/to/directory/to/sync"
|
10
|
+
directory.add "/path/to/other/directory/to/sync"
|
11
|
+
end
|
12
|
+
end
|
@@ -11,6 +11,7 @@ describe Backup::Configuration::Storage::Dropbox do
|
|
11
11
|
db.api_secret = 'my_secret'
|
12
12
|
db.path = 'my_backups'
|
13
13
|
db.keep = 20
|
14
|
+
db.timeout = 500
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -22,6 +23,7 @@ describe Backup::Configuration::Storage::Dropbox do
|
|
22
23
|
db.api_secret.should == 'my_secret'
|
23
24
|
db.path.should == 'my_backups'
|
24
25
|
db.keep.should == 20
|
26
|
+
db.timeout.should == 500
|
25
27
|
end
|
26
28
|
|
27
29
|
describe '#clear_defaults!' do
|
@@ -35,6 +37,7 @@ describe Backup::Configuration::Storage::Dropbox do
|
|
35
37
|
db.api_secret.should == nil
|
36
38
|
db.path.should == nil
|
37
39
|
db.keep.should == nil
|
40
|
+
db.timeout.should == nil
|
38
41
|
end
|
39
42
|
end
|
40
43
|
end
|
@@ -11,6 +11,7 @@ describe Backup::Storage::Dropbox do
|
|
11
11
|
db.api_key = 'my_api_key'
|
12
12
|
db.api_secret = 'my_secret'
|
13
13
|
db.keep = 20
|
14
|
+
db.timeout = 500
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -30,6 +31,21 @@ describe Backup::Storage::Dropbox do
|
|
30
31
|
db.api_secret.should == 'my_secret'
|
31
32
|
db.path.should == 'backups'
|
32
33
|
db.keep.should == 20
|
34
|
+
db.timeout.should == 500
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should overwrite the default timeout' do
|
38
|
+
db = Backup::Storage::Dropbox.new do |db|
|
39
|
+
db.timeout = 500
|
40
|
+
end
|
41
|
+
|
42
|
+
db.timeout.should == 500
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should provide a default timeout' do
|
46
|
+
db = Backup::Storage::Dropbox.new
|
47
|
+
|
48
|
+
db.timeout.should == 300
|
33
49
|
end
|
34
50
|
|
35
51
|
it 'should overwrite the default path' do
|
@@ -69,7 +85,7 @@ describe Backup::Storage::Dropbox do
|
|
69
85
|
connection.expects(:upload).with(
|
70
86
|
File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar"),
|
71
87
|
File.join('backups', Backup::TRIGGER),
|
72
|
-
:timeout =>
|
88
|
+
:timeout => db.timeout
|
73
89
|
)
|
74
90
|
|
75
91
|
db.send(:transfer!)
|
data/spec/syncer/rsync_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe Backup::Syncer::RSync do
|
|
33
33
|
rsync.port.should == "--port='22'"
|
34
34
|
rsync.path.should == 'backups/'
|
35
35
|
rsync.mirror.should == "--delete"
|
36
|
-
rsync.compress.should == "
|
36
|
+
rsync.compress.should == "--compress"
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'should use the defaults if a particular attribute has not been defined' do
|
@@ -93,7 +93,7 @@ describe Backup::Syncer::RSync do
|
|
93
93
|
context 'when true' do
|
94
94
|
it do
|
95
95
|
rsync.compress = true
|
96
|
-
rsync.compress.should == '
|
96
|
+
rsync.compress.should == '--compress'
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -140,15 +140,15 @@ describe Backup::Syncer::RSync do
|
|
140
140
|
|
141
141
|
describe '#options' do
|
142
142
|
it do
|
143
|
-
rsync.options.should == "--archive --delete
|
143
|
+
rsync.options.should == "--archive --delete --compress --port='22'"
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
147
|
describe '#perform' do
|
148
|
-
it 'should invoke transfer
|
148
|
+
it 'should invoke the rsync command to transfer the files and directories' do
|
149
149
|
Backup::Logger.expects(:message).with("Backup::Syncer::RSync started syncing '/some/random/directory' '/another/random/directory'.")
|
150
150
|
rsync.expects(:utility).with(:rsync).returns(:rsync)
|
151
|
-
rsync.expects(:run).with("rsync -vhP --archive --delete
|
151
|
+
rsync.expects(:run).with("rsync -vhP --archive --delete --compress --port='22' '/some/random/directory' '/another/random/directory' 'my_username@123.45.678.90:backups/'")
|
152
152
|
rsync.perform!
|
153
153
|
end
|
154
154
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
4
|
+
|
5
|
+
describe Backup::Syncer::S3 do
|
6
|
+
|
7
|
+
let(:s3) do
|
8
|
+
Backup::Syncer::S3.new do |s3|
|
9
|
+
s3.access_key_id = 'my_access_key_id'
|
10
|
+
s3.secret_access_key = 'my_secret_access_key'
|
11
|
+
s3.bucket = 'my-bucket'
|
12
|
+
s3.path = "/backups"
|
13
|
+
s3.mirror = true
|
14
|
+
|
15
|
+
s3.directories do |directory|
|
16
|
+
directory.add "/some/random/directory"
|
17
|
+
directory.add "/another/random/directory"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
before do
|
23
|
+
Backup::Configuration::Syncer::S3.clear_defaults!
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have defined the configuration properly' do
|
27
|
+
s3.access_key_id.should == 'my_access_key_id'
|
28
|
+
s3.secret_access_key.should == 'my_secret_access_key'
|
29
|
+
s3.bucket.should == 'my-bucket'
|
30
|
+
s3.path.should == 'backups'
|
31
|
+
s3.mirror.should == '--delete'
|
32
|
+
s3.directories.should == ["/some/random/directory", "/another/random/directory"]
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should use the defaults if a particular attribute has not been defined' do
|
36
|
+
Backup::Configuration::Syncer::S3.defaults do |s3|
|
37
|
+
s3.access_key_id = 'my_access_key_id'
|
38
|
+
s3.bucket = 'my-bucket'
|
39
|
+
s3.path = "/backups"
|
40
|
+
s3.mirror = true
|
41
|
+
end
|
42
|
+
|
43
|
+
s3 = Backup::Syncer::S3.new do |s3|
|
44
|
+
s3.secret_access_key = 'some_secret_access_key'
|
45
|
+
s3.mirror = false
|
46
|
+
end
|
47
|
+
|
48
|
+
s3.access_key_id = 'my_access_key_id'
|
49
|
+
s3.secret_access_key = 'some_secret_access_key'
|
50
|
+
s3.bucket = 'my-bucket'
|
51
|
+
s3.path = "/backups"
|
52
|
+
s3.mirror = false
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should have its own defaults' do
|
56
|
+
s3 = Backup::Syncer::S3.new
|
57
|
+
s3.path.should == 'backups'
|
58
|
+
s3.directories.should == Array.new
|
59
|
+
s3.mirror.should == nil
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#mirror' do
|
63
|
+
context 'when true' do
|
64
|
+
it do
|
65
|
+
s3.mirror = true
|
66
|
+
s3.mirror.should == '--delete'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when nil/false' do
|
71
|
+
it do
|
72
|
+
s3.mirror = nil
|
73
|
+
s3.mirror.should == nil
|
74
|
+
end
|
75
|
+
|
76
|
+
it do
|
77
|
+
s3.mirror = false
|
78
|
+
s3.mirror.should == nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#recursive' do
|
84
|
+
it do
|
85
|
+
s3.recursive.should == '--recursive'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#verbose' do
|
90
|
+
it do
|
91
|
+
s3.verbose.should == '--verbose'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#directories' do
|
96
|
+
context 'when its empty' do
|
97
|
+
it do
|
98
|
+
s3.directories = []
|
99
|
+
s3.directories.should == []
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when it has items' do
|
104
|
+
it do
|
105
|
+
s3.directories = ['directory1', 'directory1/directory2', 'directory1/directory2/directory3']
|
106
|
+
s3.directories.should == ['directory1', 'directory1/directory2', 'directory1/directory2/directory3']
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#options' do
|
112
|
+
it do
|
113
|
+
s3.options.should == "--verbose --recursive --delete"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#perform' do
|
118
|
+
it 'should sync two directories' do
|
119
|
+
s3.expects(:utility).with(:s3sync).returns(:s3sync).twice
|
120
|
+
|
121
|
+
Backup::Logger.expects(:message).with("Backup::Syncer::S3 started syncing '/some/random/directory'.")
|
122
|
+
s3.expects(:run).with("s3sync --verbose --recursive --delete '/some/random/directory' 'my-bucket:backups'")
|
123
|
+
|
124
|
+
Backup::Logger.expects(:message).with("Backup::Syncer::S3 started syncing '/another/random/directory'.")
|
125
|
+
s3.expects(:run).with("s3sync --verbose --recursive --delete '/another/random/directory' 'my-bucket:backups'")
|
126
|
+
|
127
|
+
s3.perform!
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
- 7
|
10
|
+
version: 3.0.7
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Michael van Rooijen
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-16 00:00:00 +01:00
|
14
19
|
default_executable:
|
15
20
|
dependencies:
|
16
21
|
- !ruby/object:Gem::Dependency
|
@@ -21,6 +26,11 @@ dependencies:
|
|
21
26
|
requirements:
|
22
27
|
- - ~>
|
23
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 43
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 14
|
33
|
+
- 6
|
24
34
|
version: 0.14.6
|
25
35
|
type: :runtime
|
26
36
|
version_requirements: *id001
|
@@ -32,6 +42,11 @@ dependencies:
|
|
32
42
|
requirements:
|
33
43
|
- - ~>
|
34
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 13
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 5
|
49
|
+
- 3
|
35
50
|
version: 0.5.3
|
36
51
|
type: :runtime
|
37
52
|
version_requirements: *id002
|
@@ -43,6 +58,11 @@ dependencies:
|
|
43
58
|
requirements:
|
44
59
|
- - ~>
|
45
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 25
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 2
|
65
|
+
- 3
|
46
66
|
version: 1.2.3
|
47
67
|
type: :runtime
|
48
68
|
version_requirements: *id003
|
@@ -54,6 +74,11 @@ dependencies:
|
|
54
74
|
requirements:
|
55
75
|
- - ~>
|
56
76
|
- !ruby/object:Gem::Version
|
77
|
+
hash: 25
|
78
|
+
segments:
|
79
|
+
- 2
|
80
|
+
- 2
|
81
|
+
- 15
|
57
82
|
version: 2.2.15
|
58
83
|
type: :runtime
|
59
84
|
version_requirements: *id004
|
@@ -65,6 +90,11 @@ dependencies:
|
|
65
90
|
requirements:
|
66
91
|
- - ~>
|
67
92
|
- !ruby/object:Gem::Version
|
93
|
+
hash: 5
|
94
|
+
segments:
|
95
|
+
- 2
|
96
|
+
- 0
|
97
|
+
- 5
|
68
98
|
version: 2.0.5
|
69
99
|
type: :runtime
|
70
100
|
version_requirements: *id005
|
@@ -76,6 +106,11 @@ dependencies:
|
|
76
106
|
requirements:
|
77
107
|
- - ~>
|
78
108
|
- !ruby/object:Gem::Version
|
109
|
+
hash: 31
|
110
|
+
segments:
|
111
|
+
- 1
|
112
|
+
- 0
|
113
|
+
- 4
|
79
114
|
version: 1.0.4
|
80
115
|
type: :runtime
|
81
116
|
version_requirements: *id006
|
@@ -87,15 +122,15 @@ dependencies:
|
|
87
122
|
requirements:
|
88
123
|
- - ~>
|
89
124
|
- !ruby/object:Gem::Version
|
125
|
+
hash: 23
|
126
|
+
segments:
|
127
|
+
- 1
|
128
|
+
- 1
|
129
|
+
- 2
|
90
130
|
version: 1.1.2
|
91
131
|
type: :runtime
|
92
132
|
version_requirements: *id007
|
93
|
-
description:
|
94
|
-
Backup is a RubyGem (for UNIX-like operating systems: Linux, Mac OSX) that allows you to configure and perform backups in a simple manner using an elegant Ruby DSL.
|
95
|
-
It supports various databases (MySQL, PostgreSQL, MongoDB and Redis), it supports various storage locations
|
96
|
-
(Amazon S3, Rackspace Cloud Files, Dropbox, any remote server through FTP, SFTP, SCP and RSync), it can archive files and directories,
|
97
|
-
it can cycle backups, it can do incremental backups, it can compress backups, it can encrypt backups (OpenSSL or GPG),
|
98
|
-
it can notify you about successful and/or failed backups (Email, Twitter). It is very extensible and easy to add new functionality to. It's easy to use.
|
133
|
+
description:
|
99
134
|
email: meskyanichi@gmail.com
|
100
135
|
executables:
|
101
136
|
- backup
|
@@ -142,6 +177,7 @@ files:
|
|
142
177
|
- lib/backup/configuration/storage/scp.rb
|
143
178
|
- lib/backup/configuration/storage/sftp.rb
|
144
179
|
- lib/backup/configuration/syncer/rsync.rb
|
180
|
+
- lib/backup/configuration/syncer/s3.rb
|
145
181
|
- lib/backup/database/base.rb
|
146
182
|
- lib/backup/database/mongodb.rb
|
147
183
|
- lib/backup/database/mysql.rb
|
@@ -168,7 +204,9 @@ files:
|
|
168
204
|
- lib/backup/storage/s3.rb
|
169
205
|
- lib/backup/storage/scp.rb
|
170
206
|
- lib/backup/storage/sftp.rb
|
207
|
+
- lib/backup/syncer/base.rb
|
171
208
|
- lib/backup/syncer/rsync.rb
|
209
|
+
- lib/backup/syncer/s3.rb
|
172
210
|
- lib/backup/version.rb
|
173
211
|
- lib/templates/archive
|
174
212
|
- lib/templates/compressor/gzip
|
@@ -189,6 +227,7 @@ files:
|
|
189
227
|
- lib/templates/storage/scp
|
190
228
|
- lib/templates/storage/sftp
|
191
229
|
- lib/templates/syncer/rsync
|
230
|
+
- lib/templates/syncer/s3
|
192
231
|
- spec/archive_spec.rb
|
193
232
|
- spec/backup_spec.rb
|
194
233
|
- spec/compressor/gzip_spec.rb
|
@@ -232,6 +271,7 @@ files:
|
|
232
271
|
- spec/storage/scp_spec.rb
|
233
272
|
- spec/storage/sftp_spec.rb
|
234
273
|
- spec/syncer/rsync_spec.rb
|
274
|
+
- spec/syncer/s3_spec.rb
|
235
275
|
- spec/version_spec.rb
|
236
276
|
has_rdoc: true
|
237
277
|
homepage: http://rubygems.org/gems/backup
|
@@ -247,12 +287,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
247
287
|
requirements:
|
248
288
|
- - ">="
|
249
289
|
- !ruby/object:Gem::Version
|
290
|
+
hash: 3
|
291
|
+
segments:
|
292
|
+
- 0
|
250
293
|
version: "0"
|
251
294
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
252
295
|
none: false
|
253
296
|
requirements:
|
254
297
|
- - ">="
|
255
298
|
- !ruby/object:Gem::Version
|
299
|
+
hash: 3
|
300
|
+
segments:
|
301
|
+
- 0
|
256
302
|
version: "0"
|
257
303
|
requirements: []
|
258
304
|
|
@@ -260,6 +306,6 @@ rubyforge_project:
|
|
260
306
|
rubygems_version: 1.6.1
|
261
307
|
signing_key:
|
262
308
|
specification_version: 3
|
263
|
-
summary: "Backup is a RubyGem (for UNIX-like operating systems: Linux, Mac OSX) that allows you to configure and perform backups in a simple manner using an elegant Ruby DSL."
|
309
|
+
summary: "Backup is a RubyGem (for UNIX-like operating systems: Linux, Mac OSX) that allows you to configure and perform backups in a simple manner using an elegant Ruby DSL. It supports various databases (MySQL, PostgreSQL, MongoDB and Redis), it supports various storage locations (Amazon S3, Rackspace Cloud Files, Dropbox, any remote server through FTP, SFTP, SCP and RSync), it provide Syncers (RSync, S3) for efficient backups, it can archive files and directories, it can cycle backups, it can do incremental backups, it can compress backups, it can encrypt backups (OpenSSL or GPG), it can notify you about successful and/or failed backups (Email or Twitter). It is very extensible and easy to add new functionality to. It's easy to use."
|
264
310
|
test_files: []
|
265
311
|
|