lsync 2.3.3 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +5 -0
- data/Gemfile +11 -0
- data/README.md +61 -15
- data/Rakefile +8 -0
- data/bin/lsync-disk +0 -0
- data/examples/local_backup_growl.rb +58 -0
- data/examples/local_sync.rb +26 -0
- data/examples/remote_backup.rb +38 -0
- data/examples/roles.rb +41 -0
- data/examples/scripts/test.rb +3 -0
- data/lib/lsync/script.rb +6 -5
- data/lib/lsync/shell.rb +0 -1
- data/lib/lsync/version.rb +1 -7
- data/lsync.gemspec +29 -0
- data/media/LSync Logo.artx/Preview/preview.png +0 -0
- data/media/LSync Logo.artx/QuickLook/Preview.pdf +0 -0
- data/media/LSync Logo.artx/doc.thread +0 -0
- data/media/LSync Logo.png +0 -0
- data/spec/lsync/backup_spec.rb +97 -0
- data/spec/lsync/local_backup.rb +63 -0
- data/spec/lsync/local_sync.rb +89 -0
- metadata +121 -81
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f72b0bf9d68e4842067a58fe5a0b23d1113700f6
|
4
|
+
data.tar.gz: a778aae985208b4c8352d755febe0aa4981f76eb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 98a48e84cdb25cd70c446169470b9672bd414f4a2073bbb400f7811418b954505eb06e0fe0ce7cf4bcd3e2349602cce7492709b8abd4ac2b191d8a63e1ad8333
|
7
|
+
data.tar.gz: 3049bf427dc9aa815dbf424b7fb81793c8ed9bf78a5efb88859d8cfa605e7f54e57b1350a512316c9d80030672c8abdb690a8af05b432831e4714ad90ab01691
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
LSync
|
2
|
-
=====
|
3
|
-
|
4
|
-
* Author: Samuel G. D. Williams (<http://www.oriontransfer.co.nz>)
|
5
|
-
* Copyright (C) 2009, 2011 Samuel G. D. Williams.
|
6
|
-
* Released under the MIT license.
|
1
|
+
# LSync
|
7
2
|
|
8
3
|
LSync is a tool for scripted synchronization and backups. It provides a custom Ruby
|
9
4
|
DSL for describing complex backup and synchronization tasks. It is designed to give
|
10
5
|
maximum flexibility while reducing the complexity of describing complex multi-server
|
11
|
-
setups.
|
6
|
+
setups. For examples please see the main [project page][1].
|
7
|
+
|
8
|
+
[1]: http://www.codeotaku.com/projects/lsync/index
|
12
9
|
|
13
10
|
* Single and multi-server data synchronization.
|
14
11
|
* Incremental backups both locally and remotely.
|
@@ -16,21 +13,70 @@ setups.
|
|
16
13
|
* Backup verification using `Fingerprint`.
|
17
14
|
* Data backup redundancy controlled via DNS.
|
18
15
|
|
19
|
-
|
16
|
+
[![Build Status](https://secure.travis-ci.org/ioquatix/lsync.png)](http://travis-ci.org/ioquatix/lsync)
|
17
|
+
[![Code Climate](https://codeclimate.com/github/ioquatix/lsync.png)](https://codeclimate.com/github/ioquatix/lsync)
|
18
|
+
[![Coverage Status](https://coveralls.io/repos/ioquatix/lsync/badge.svg)](https://coveralls.io/r/ioquatix/lsync)
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
gem 'lsync'
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Or install it yourself as:
|
20
31
|
|
21
|
-
|
32
|
+
$ gem install lsync
|
22
33
|
|
23
|
-
|
24
|
-
--------
|
34
|
+
## Usage
|
25
35
|
|
26
36
|
LSync imposes a particular structure regarding the organisation of backup scripts:
|
27
37
|
Backup scripts involve a set of servers and directories. A server is a logical unit
|
28
38
|
where files are available or stored. Directories are specific places within servers.
|
29
39
|
|
30
|
-
|
31
|
-
|
40
|
+
A simple backup script might look something like this:
|
41
|
+
|
42
|
+
#!/usr/bin/env ruby
|
43
|
+
|
44
|
+
require 'lsync'
|
45
|
+
require 'lsync/shells/ssh'
|
46
|
+
require 'lsync/methods/rsync'
|
47
|
+
|
48
|
+
LSync::run_script do |script|
|
49
|
+
script.method = LSync::Methods::RSync.new(:push, :arguments => ["--archive", "--delete"])
|
50
|
+
|
51
|
+
# Set :src to be the master server
|
52
|
+
script.master = :src
|
53
|
+
|
54
|
+
server(:src) do |server|
|
55
|
+
server.host = "server.example.com"
|
56
|
+
server.root = "/"
|
57
|
+
end
|
58
|
+
|
59
|
+
server(:dst) do |server|
|
60
|
+
server.host = "backup.example.com"
|
61
|
+
server.root = "/"
|
62
|
+
end
|
63
|
+
|
64
|
+
backup('etc', 'var', 'srv', 'home')
|
65
|
+
end
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
|
69
|
+
1. Fork it
|
70
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
71
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
72
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
73
|
+
5. Create new Pull Request
|
74
|
+
|
75
|
+
## License
|
76
|
+
|
77
|
+
Released under the MIT license.
|
32
78
|
|
33
|
-
Copyright
|
79
|
+
Copyright, 2015, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
|
34
80
|
|
35
81
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
36
82
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -48,4 +94,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
48
94
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
49
95
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
50
96
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
51
|
-
THE SOFTWARE.
|
97
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
data/bin/lsync-disk
CHANGED
File without changes
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
require 'ruby-growl'
|
6
|
+
|
7
|
+
require 'lsync'
|
8
|
+
require 'lsync/shells/ssh'
|
9
|
+
require 'lsync/methods/rsync'
|
10
|
+
|
11
|
+
# Check we've got two paths for sync.
|
12
|
+
unless ARGV.size == 2
|
13
|
+
$stderr.puts "Usage: #{$0} [master] [copy]"
|
14
|
+
exit(255)
|
15
|
+
end
|
16
|
+
|
17
|
+
$growl = Growl.new "localhost", "LSync", ["Backup Status"]
|
18
|
+
$growl.register
|
19
|
+
|
20
|
+
$script = LSync::Script.new do |script|
|
21
|
+
script.method = LSync::Methods::RSyncSnapshot.new(:push, :arguments => ["--archive", "--compress", "--stats"])
|
22
|
+
|
23
|
+
script.master = :src
|
24
|
+
|
25
|
+
server(:src) do |server|
|
26
|
+
server.root = ARGV[0]
|
27
|
+
end
|
28
|
+
|
29
|
+
server(:dst) do |server|
|
30
|
+
server.root = ARGV[1]
|
31
|
+
|
32
|
+
server.on(:success) do |controller|
|
33
|
+
run :prune, "--default-policy"
|
34
|
+
run :rotate, script.method.inprogress_path
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# This event is fired before the backup starts
|
39
|
+
script.on(:prepare) do
|
40
|
+
$growl.notify "Backup Status", "Starting Backup", "Starting at #{Time.now.to_s}"
|
41
|
+
end
|
42
|
+
|
43
|
+
# This event occurs if the backup is successful
|
44
|
+
script.on(:success) do
|
45
|
+
$growl.notify "Backup Status", "Backup Successful", script.log.string
|
46
|
+
end
|
47
|
+
|
48
|
+
# This event occurs if any part of the backup fails and is not handled elsewhere.
|
49
|
+
script.on(:failure) do |failure|
|
50
|
+
$growl.notify "Backup Status", "Backup Failure", failure.to_s
|
51
|
+
|
52
|
+
raise failure
|
53
|
+
end
|
54
|
+
|
55
|
+
backup('./')
|
56
|
+
end
|
57
|
+
|
58
|
+
$script.run!
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
require 'lsync'
|
6
|
+
require 'lsync/methods/rsync'
|
7
|
+
|
8
|
+
LSync::run_script do |script|
|
9
|
+
script.method = LSync::Methods::RSync.new(:push, :arguments => ["--archive", "--delete"])
|
10
|
+
|
11
|
+
script.master = :src
|
12
|
+
|
13
|
+
server(:src) do |server|
|
14
|
+
server.root = Pathname.new("./Data-Master").realpath
|
15
|
+
end
|
16
|
+
|
17
|
+
server(:dst) do |server|
|
18
|
+
server.root = Pathname.new("./Data-Master-Sync").expand_path
|
19
|
+
|
20
|
+
server.on(:success) do
|
21
|
+
target.run_script "./scripts/test.rb"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
backup('./')
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
require 'lsync'
|
6
|
+
require 'lsync/shells/ssh'
|
7
|
+
require 'lsync/methods/rsync'
|
8
|
+
|
9
|
+
TEST_SCRIPT = <<EOF
|
10
|
+
#!/usr/bin/env ruby
|
11
|
+
|
12
|
+
puts "Hello World " + ARGV.inspect
|
13
|
+
|
14
|
+
EOF
|
15
|
+
|
16
|
+
$script = LSync::Script.new do |script|
|
17
|
+
script.method = LSync::Methods::RSyncSnapshot.new(:push, :arguments => ["--archive", "--compress", "--stats"])
|
18
|
+
|
19
|
+
server("localhost") do |server|
|
20
|
+
server.roles << :primary
|
21
|
+
server.root = Pathname.new(__FILE__).dirname + "Data-Master"
|
22
|
+
end
|
23
|
+
|
24
|
+
server("ayako.oriontransfer.org") do |server|
|
25
|
+
server.roles << :backup
|
26
|
+
server.root = "/tmp/"
|
27
|
+
|
28
|
+
server.on(:success) do
|
29
|
+
target.run [TEST_SCRIPT, "foo", "bar"], :script => true
|
30
|
+
target.run ["./scripts/test.rb", "foo", "bar", "baz"], :remote => true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
backup('./')
|
35
|
+
end
|
36
|
+
|
37
|
+
# We only run servers with the given role:
|
38
|
+
$script.run!(:role => :backup)
|
data/examples/roles.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
require 'lsync'
|
6
|
+
require 'lsync/shells/ssh'
|
7
|
+
require 'lsync/methods/rsync'
|
8
|
+
|
9
|
+
$script = LSync::Script.new do |script|
|
10
|
+
script.method = LSync::Methods::RSyncSnapshot.new(:pull, :arguments => ["--archive", "--compress", "--stats"])
|
11
|
+
script.actions_path << Pathname.new(__FILE__).dirname + "actions"
|
12
|
+
script.master = "server.example.com"
|
13
|
+
|
14
|
+
# These servers are all source servers, but only one of them will be selected to be the master.
|
15
|
+
server("server-a.example.com") do |server|
|
16
|
+
server.role = :primary
|
17
|
+
end
|
18
|
+
|
19
|
+
server("server-b.example.com") do |server|
|
20
|
+
server.role = :primary
|
21
|
+
end
|
22
|
+
|
23
|
+
server("server-b.example.com") do |server|
|
24
|
+
server.role = :primary
|
25
|
+
end
|
26
|
+
|
27
|
+
server("backup.example.com") do |server|
|
28
|
+
server.role = :backup
|
29
|
+
server.root = "/mnt/backups/server.example.com"
|
30
|
+
|
31
|
+
server.on(:success) do
|
32
|
+
target.run :rotate, script.method.inprogress_path
|
33
|
+
target.run :prune, "--default-policy"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
backup('./')
|
38
|
+
end
|
39
|
+
|
40
|
+
# We only run servers with the given role:
|
41
|
+
$script.run!(:role => :backup)
|
data/lib/lsync/script.rb
CHANGED
@@ -147,8 +147,6 @@ module LSync
|
|
147
147
|
# Log data (an +IO+) specific to the current script.
|
148
148
|
attr :log
|
149
149
|
|
150
|
-
public
|
151
|
-
|
152
150
|
# Run the backup process for all servers and directories specified.
|
153
151
|
def run!(options = {})
|
154
152
|
start_time = Time.now
|
@@ -174,10 +172,13 @@ module LSync
|
|
174
172
|
master_controller = ServerController.new(self, logger, master)
|
175
173
|
|
176
174
|
self.try(master_controller) do
|
177
|
-
|
178
|
-
|
175
|
+
# This allows events to run on the master server if specified, before running any backups.
|
176
|
+
master.try(master_controller) do
|
177
|
+
method.try(master_controller) do
|
178
|
+
logger.info "Running backups for server #{current}..."
|
179
179
|
|
180
|
-
|
180
|
+
run_backups!(master, current, logger, options)
|
181
|
+
end
|
181
182
|
end
|
182
183
|
end
|
183
184
|
|
data/lib/lsync/shell.rb
CHANGED
data/lib/lsync/version.rb
CHANGED
data/lsync.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'lsync/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "lsync"
|
8
|
+
spec.version = LSync::VERSION
|
9
|
+
spec.authors = ["Samuel Williams"]
|
10
|
+
spec.email = ["samuel.williams@oriontransfer.co.nz"]
|
11
|
+
spec.summary = %q{LSync is a tool for scripted synchronization and backups.}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency("fingerprint", ">= 1.2.4")
|
21
|
+
spec.add_dependency("rexec", ">= 1.4.1")
|
22
|
+
spec.add_dependency("lockfile")
|
23
|
+
|
24
|
+
spec.has_rdoc = "yard"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
# Copyright, 2015, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'fingerprint'
|
24
|
+
require 'rexec'
|
25
|
+
require 'fileutils'
|
26
|
+
require 'digest'
|
27
|
+
|
28
|
+
require 'lsync/script'
|
29
|
+
|
30
|
+
module LSync::BackupSpec
|
31
|
+
LOG_FILE = "backup-test.log"
|
32
|
+
|
33
|
+
describe LSync::Script do
|
34
|
+
def create_files(master, copy)
|
35
|
+
FileUtils.rm_rf master
|
36
|
+
FileUtils.rm_rf copy
|
37
|
+
|
38
|
+
FileUtils.mkdir_p master
|
39
|
+
FileUtils.mkdir_p copy
|
40
|
+
|
41
|
+
(1...10).each do |i|
|
42
|
+
path = File.join(master, i.to_s)
|
43
|
+
|
44
|
+
FileUtils.mkdir(path)
|
45
|
+
|
46
|
+
text = Digest::MD5.hexdigest(i.to_s)
|
47
|
+
|
48
|
+
File.open(File.join(path, i.to_s), "w") { |f| f.write(text) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
before(:each) do
|
53
|
+
@master = Pathname.new("tmp/master")
|
54
|
+
@copy = Pathname.new("tmp/copy")
|
55
|
+
|
56
|
+
create_files(@master, @copy)
|
57
|
+
end
|
58
|
+
|
59
|
+
after(:each) do
|
60
|
+
FileUtils.rm_rf @master
|
61
|
+
FileUtils.rm_rf @copy
|
62
|
+
end
|
63
|
+
|
64
|
+
LOCAL_SYNC_SCRIPT = File.join(__dir__, 'local_sync.rb')
|
65
|
+
|
66
|
+
it "should synchronize files" do
|
67
|
+
RExec::Task.open(['ruby', LOCAL_SYNC_SCRIPT, @master, @copy], :passthrough => :all) do |task|
|
68
|
+
task.wait
|
69
|
+
end
|
70
|
+
|
71
|
+
failures = 0
|
72
|
+
|
73
|
+
checker = Fingerprint::check_paths(@master, @copy) do |record, name, message|
|
74
|
+
failures += 1
|
75
|
+
$stderr.puts "Path #{record.path} different"
|
76
|
+
end
|
77
|
+
|
78
|
+
expect(failures).to be == 0
|
79
|
+
end
|
80
|
+
|
81
|
+
LOCAL_BACKUP_SCRIPT = File.join(__dir__, 'local_backup.rb')
|
82
|
+
|
83
|
+
it "should backup files" do
|
84
|
+
RExec::Task.open(['ruby', LOCAL_BACKUP_SCRIPT, @master, @copy], :passthrough => :all) do |task|
|
85
|
+
task.wait
|
86
|
+
end
|
87
|
+
|
88
|
+
failures = 0
|
89
|
+
checker = Fingerprint::check_paths(@master, @copy + "latest") do |record, name, message|
|
90
|
+
failures += 1
|
91
|
+
$stderr.puts "Path #{record.path} different"
|
92
|
+
end
|
93
|
+
|
94
|
+
expect(failures).to be == 0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'lsync'
|
4
|
+
require 'lsync/shells/ssh'
|
5
|
+
require 'lsync/methods/rsync'
|
6
|
+
|
7
|
+
# Check we've got two paths for sync.
|
8
|
+
unless ARGV.size == 2
|
9
|
+
$stderr.puts "Usage: #{$0} [master] [copy]"
|
10
|
+
exit(255)
|
11
|
+
end
|
12
|
+
|
13
|
+
# $growl = Growl.new "localhost", "LSync", ["Backup Status"]
|
14
|
+
# $growl.register
|
15
|
+
|
16
|
+
$stdout.sync = true
|
17
|
+
$stderr.sync = true
|
18
|
+
|
19
|
+
FAILURE_SCRIPT = <<EOF
|
20
|
+
#!/usr/bin/env ruby
|
21
|
+
|
22
|
+
exit 1
|
23
|
+
|
24
|
+
EOF
|
25
|
+
|
26
|
+
LSync::run_script do |script|
|
27
|
+
script.method = LSync::Methods::RSyncSnapshot.new(:push, :arguments => ["--archive", "--compress", "--stats"])
|
28
|
+
|
29
|
+
script.master = :src
|
30
|
+
|
31
|
+
server(:src) do |server|
|
32
|
+
server.root = ARGV[0]
|
33
|
+
end
|
34
|
+
|
35
|
+
server(:dst) do |server|
|
36
|
+
server.root = ARGV[1]
|
37
|
+
|
38
|
+
# Runs after all directories have been successfully backed up.
|
39
|
+
server.on(:success) do
|
40
|
+
target.run ["lsync-rotate", script.method.inprogress_path]
|
41
|
+
target.run ["lsync-prune", "--default-policy"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# This event is fired before the backup starts
|
46
|
+
#script.on(:prepare) do
|
47
|
+
# $growl.notify "Backup Status", "Starting Backup", "Starting at #{Time.now.to_s}"
|
48
|
+
#end
|
49
|
+
#
|
50
|
+
## This event occurs if the backup is successful
|
51
|
+
#script.on(:success) do
|
52
|
+
# $growl.notify "Backup Status", "Backup Successful", script.log.string
|
53
|
+
#end
|
54
|
+
#
|
55
|
+
## This event occurs if any part of the backup fails and is not handled elsewhere.
|
56
|
+
#script.on(:failure) do |failure|
|
57
|
+
# $growl.notify "Backup Status", "Backup Failure", failure.to_s
|
58
|
+
#
|
59
|
+
# raise failure
|
60
|
+
#end
|
61
|
+
|
62
|
+
backup('./')
|
63
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# You need to have the FSSM gem installed for this to work.
|
4
|
+
require 'fssm'
|
5
|
+
|
6
|
+
require 'lsync'
|
7
|
+
require 'lsync/shells/ssh'
|
8
|
+
require 'lsync/methods/rsync'
|
9
|
+
require 'lsync/event_timer'
|
10
|
+
|
11
|
+
MONITOR = ARGV.delete "-m"
|
12
|
+
|
13
|
+
# Check we've got two paths for sync.
|
14
|
+
unless ARGV.size == 2
|
15
|
+
$stderr.puts "Usage: #{$0} [master] [copy]"
|
16
|
+
exit(255)
|
17
|
+
end
|
18
|
+
|
19
|
+
$script = LSync::Script.new do |script|
|
20
|
+
script.method = LSync::Methods::RSync.new(:push, :arguments => ["--archive", "--delete"])
|
21
|
+
|
22
|
+
script.master = :src
|
23
|
+
|
24
|
+
server(:src) do |server|
|
25
|
+
server.root = ARGV[0]
|
26
|
+
end
|
27
|
+
|
28
|
+
server(:dst) do |server|
|
29
|
+
server.root = ARGV[1]
|
30
|
+
|
31
|
+
#server.on(:prepare) do
|
32
|
+
# logger.warn "Aborting backup!"
|
33
|
+
# server.abort!
|
34
|
+
#end
|
35
|
+
end
|
36
|
+
|
37
|
+
#server(:remote) do |server|
|
38
|
+
# server.host = "ayako.oriontransfer.org"
|
39
|
+
# server.shell = LSync::Shells::SSH.new(:user => "nobody")
|
40
|
+
# server.root = "/tmp/sync-test"
|
41
|
+
#end
|
42
|
+
|
43
|
+
#server(:remote2) do |server|
|
44
|
+
# server.host = "remote2.example.com"
|
45
|
+
# server.root = "/tmp/sync-test"
|
46
|
+
#
|
47
|
+
# server.on(:prepare) do |controller|
|
48
|
+
# controller.run! "mysqldump", "..."
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# server.on(:success) do |controller|
|
52
|
+
# controller.run! "uname", "-a"
|
53
|
+
# end
|
54
|
+
#end
|
55
|
+
|
56
|
+
backup('./')
|
57
|
+
end
|
58
|
+
|
59
|
+
# Initial sync:
|
60
|
+
$script.run!
|
61
|
+
|
62
|
+
if MONITOR
|
63
|
+
# Monitor directories for changes:
|
64
|
+
monitor = FSSM::Monitor.new(:directories => true)
|
65
|
+
|
66
|
+
# The event timer aggregates events into a single callback which will be called at most
|
67
|
+
# once every k seconds (where k = 10 in this case).
|
68
|
+
$event_timer = LSync::EventTimer.new(10) do
|
69
|
+
$script.run!
|
70
|
+
end
|
71
|
+
|
72
|
+
$script.directories.each do |directory|
|
73
|
+
full_path = $script[:src].full_path(directory)
|
74
|
+
puts "Monitoring path: #{full_path}"
|
75
|
+
|
76
|
+
monitor.path(full_path, "**/*") do
|
77
|
+
update { $event_timer.trigger! }
|
78
|
+
delete { $event_timer.trigger! }
|
79
|
+
create { $event_timer.trigger! }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
begin
|
84
|
+
monitor.run
|
85
|
+
ensure
|
86
|
+
# We should wait for the backup to complete nicely.
|
87
|
+
$event_timer.join
|
88
|
+
end
|
89
|
+
end
|
metadata
CHANGED
@@ -1,82 +1,123 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: lsync
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 3
|
9
|
-
- 3
|
10
|
-
version: 2.3.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.4.0
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Samuel Williams
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2015-04-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
21
14
|
name: fingerprint
|
22
|
-
|
23
|
-
|
24
|
-
none: false
|
25
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
26
17
|
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 23
|
29
|
-
segments:
|
30
|
-
- 1
|
31
|
-
- 2
|
32
|
-
- 4
|
18
|
+
- !ruby/object:Gem::Version
|
33
19
|
version: 1.2.4
|
34
20
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: rexec
|
38
21
|
prerelease: false
|
39
|
-
|
40
|
-
|
41
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.2.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rexec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
42
31
|
- - ">="
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
hash: 5
|
45
|
-
segments:
|
46
|
-
- 1
|
47
|
-
- 4
|
48
|
-
- 1
|
32
|
+
- !ruby/object:Gem::Version
|
49
33
|
version: 1.4.1
|
50
34
|
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: lockfile
|
54
35
|
prerelease: false
|
55
|
-
|
56
|
-
|
57
|
-
requirements:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
58
38
|
- - ">="
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.4.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: lockfile
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
64
48
|
type: :runtime
|
65
|
-
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
66
97
|
description:
|
67
|
-
email:
|
68
|
-
|
98
|
+
email:
|
99
|
+
- samuel.williams@oriontransfer.co.nz
|
100
|
+
executables:
|
69
101
|
- lsync-disk
|
70
102
|
- lsync-prune
|
71
103
|
- lsync-rotate
|
72
104
|
extensions: []
|
73
|
-
|
74
105
|
extra_rdoc_files: []
|
75
|
-
|
76
|
-
|
106
|
+
files:
|
107
|
+
- ".gitignore"
|
108
|
+
- ".travis.yml"
|
109
|
+
- Gemfile
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
77
112
|
- bin/lsync-disk
|
78
113
|
- bin/lsync-prune
|
79
114
|
- bin/lsync-rotate
|
115
|
+
- examples/local_backup_growl.rb
|
116
|
+
- examples/local_sync.rb
|
117
|
+
- examples/remote_backup.rb
|
118
|
+
- examples/roles.rb
|
119
|
+
- examples/scripts/test.rb
|
120
|
+
- lib/lsync.rb
|
80
121
|
- lib/lsync/client.rb
|
81
122
|
- lib/lsync/controller.rb
|
82
123
|
- lib/lsync/directory.rb
|
@@ -91,40 +132,39 @@ files:
|
|
91
132
|
- lib/lsync/shells/ssh.rb
|
92
133
|
- lib/lsync/tee_logger.rb
|
93
134
|
- lib/lsync/version.rb
|
94
|
-
-
|
95
|
-
-
|
96
|
-
|
97
|
-
|
98
|
-
|
135
|
+
- lsync.gemspec
|
136
|
+
- media/LSync Logo.artx/Preview/preview.png
|
137
|
+
- media/LSync Logo.artx/QuickLook/Preview.pdf
|
138
|
+
- media/LSync Logo.artx/doc.thread
|
139
|
+
- media/LSync Logo.png
|
140
|
+
- spec/lsync/backup_spec.rb
|
141
|
+
- spec/lsync/local_backup.rb
|
142
|
+
- spec/lsync/local_sync.rb
|
143
|
+
homepage: ''
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata: {}
|
99
147
|
post_install_message:
|
100
148
|
rdoc_options: []
|
101
|
-
|
102
|
-
require_paths:
|
149
|
+
require_paths:
|
103
150
|
- lib
|
104
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
-
|
106
|
-
requirements:
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
107
153
|
- - ">="
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
version: "0"
|
113
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
|
-
requirements:
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
116
158
|
- - ">="
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
|
119
|
-
segments:
|
120
|
-
- 0
|
121
|
-
version: "0"
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
122
161
|
requirements: []
|
123
|
-
|
124
162
|
rubyforge_project:
|
125
|
-
rubygems_version:
|
163
|
+
rubygems_version: 2.2.2
|
126
164
|
signing_key:
|
127
|
-
specification_version:
|
165
|
+
specification_version: 4
|
128
166
|
summary: LSync is a tool for scripted synchronization and backups.
|
129
|
-
test_files:
|
130
|
-
|
167
|
+
test_files:
|
168
|
+
- spec/lsync/backup_spec.rb
|
169
|
+
- spec/lsync/local_backup.rb
|
170
|
+
- spec/lsync/local_sync.rb
|