synco 1.0.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/.rspec +4 -0
- data/.simplecov +9 -0
- data/.travis.yml +14 -0
- data/Gemfile +11 -0
- data/README.md +246 -0
- data/Rakefile +8 -0
- data/bin/synco +30 -0
- data/lib/synco.rb +51 -0
- data/lib/synco/command.rb +71 -0
- data/lib/synco/command/disk.rb +55 -0
- data/lib/synco/command/prune.rb +166 -0
- data/lib/synco/command/rotate.rb +86 -0
- data/lib/synco/command/spawn.rb +39 -0
- data/lib/synco/compact_formatter.rb +115 -0
- data/lib/synco/controller.rb +119 -0
- data/lib/synco/directory.rb +60 -0
- data/lib/synco/disk.rb +68 -0
- data/lib/synco/method.rb +56 -0
- data/lib/synco/methods/rsync.rb +162 -0
- data/lib/synco/methods/scp.rb +44 -0
- data/lib/synco/methods/zfs.rb +60 -0
- data/lib/synco/scope.rb +247 -0
- data/lib/synco/script.rb +128 -0
- data/lib/synco/server.rb +90 -0
- data/lib/synco/shell.rb +44 -0
- data/lib/synco/shells/ssh.rb +52 -0
- data/lib/synco/version.rb +23 -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/synco/backup_script.rb +63 -0
- data/spec/synco/directory_spec.rb +33 -0
- data/spec/synco/local_backup.rb +56 -0
- data/spec/synco/local_sync.rb +91 -0
- data/spec/synco/method_spec.rb +62 -0
- data/spec/synco/rsync_spec.rb +89 -0
- data/spec/synco/scp_spec.rb +58 -0
- data/spec/synco/script_spec.rb +51 -0
- data/spec/synco/shell_spec.rb +42 -0
- data/spec/synco/usb_spec.rb +76 -0
- data/spec/synco/zfs_spec.rb +50 -0
- data/synco.gemspec +35 -0
- metadata +254 -0
data/lib/synco/server.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'controller'
|
22
|
+
require_relative 'directory'
|
23
|
+
require_relative 'shells/ssh'
|
24
|
+
|
25
|
+
require 'shellwords'
|
26
|
+
|
27
|
+
module Synco
|
28
|
+
class Server < Controller
|
29
|
+
def initialize(name, root: '/', shell: nil, **options)
|
30
|
+
super()
|
31
|
+
|
32
|
+
@name = name
|
33
|
+
|
34
|
+
case @name
|
35
|
+
when Symbol
|
36
|
+
@host = "localhost"
|
37
|
+
else
|
38
|
+
@host = name.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
@root = root
|
42
|
+
@shell = shell || Shells::SSH.new
|
43
|
+
|
44
|
+
@options = options
|
45
|
+
end
|
46
|
+
|
47
|
+
# The name of the server in the configuration (might be the same as the host).
|
48
|
+
attr :name
|
49
|
+
|
50
|
+
# The host name (e.g. DNS entry) for the given server.
|
51
|
+
attr_accessor :host
|
52
|
+
|
53
|
+
# The root path on the server in which all other directories will be relative to.
|
54
|
+
attr_accessor :root
|
55
|
+
|
56
|
+
# The shell to use to connect to the server.
|
57
|
+
attr_accessor :shell
|
58
|
+
|
59
|
+
attr_accessor :mountpoint
|
60
|
+
|
61
|
+
# Give the full path for a particular subdirectory.
|
62
|
+
def full_path(directory = "")
|
63
|
+
path = File.expand_path(directory.to_s, @root)
|
64
|
+
|
65
|
+
Directory.normalize(path)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Give a general connection string (e.g +"host:/directory"+ or +"/directory"+ if local).
|
69
|
+
def connection_string(directory, on: nil)
|
70
|
+
if self.host == on.host
|
71
|
+
return full_path(directory).to_s
|
72
|
+
else
|
73
|
+
return @host + ":" + Shellwords.escape(full_path(directory))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def connection_command
|
78
|
+
@shell.connection_command(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
def same_host?(other)
|
82
|
+
@host == other.host
|
83
|
+
end
|
84
|
+
|
85
|
+
# String representation of the server for logging.
|
86
|
+
def to_s
|
87
|
+
"#{@host}:#{full_path}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/synco/shell.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'pathname'
|
22
|
+
|
23
|
+
module Synco
|
24
|
+
# A shell provides access to a server, typically to run commands.
|
25
|
+
class Shell
|
26
|
+
def initialize(*command, arguments: [], **options)
|
27
|
+
@command = command.empty? ? default_command : command
|
28
|
+
|
29
|
+
@arguments = arguments
|
30
|
+
@options = options
|
31
|
+
end
|
32
|
+
|
33
|
+
attr :arguments
|
34
|
+
|
35
|
+
# The command required to connect to the remote machine.
|
36
|
+
def connection_command(server, *arguments)
|
37
|
+
[*@command, *@arguments, *arguments, server.host]
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"<#{self.class} #{@command} #{@options.inspect}>"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative '../shell'
|
22
|
+
|
23
|
+
module Synco
|
24
|
+
module Shells
|
25
|
+
# SSH shell provides access to a remote server using SSH.
|
26
|
+
class SSH < Shell
|
27
|
+
def default_command
|
28
|
+
['ssh']
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(*command, arguments: [], port: nil, key: nil, user: nil, batch_mode: nil, **options)
|
32
|
+
if port
|
33
|
+
arguments << '-p' << port
|
34
|
+
end
|
35
|
+
|
36
|
+
if key
|
37
|
+
arguments << '-i' << value
|
38
|
+
end
|
39
|
+
|
40
|
+
if user
|
41
|
+
arguments << '-l' << value
|
42
|
+
end
|
43
|
+
|
44
|
+
unless batch_mode.nil?
|
45
|
+
arguments << '-o' << "BatchMode=#{batch_mode ? 'yes' : 'no'}"
|
46
|
+
end
|
47
|
+
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Synco
|
22
|
+
VERSION = "1.0.0"
|
23
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,63 @@
|
|
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 'process/group'
|
25
|
+
require 'fileutils'
|
26
|
+
require 'digest'
|
27
|
+
|
28
|
+
require 'synco/scope'
|
29
|
+
require 'synco/script'
|
30
|
+
|
31
|
+
SYNCO_PATH = File.expand_path("../../bin/synco", __dir__)
|
32
|
+
|
33
|
+
RSpec.shared_context "backup script" do
|
34
|
+
def create_files(master_path, target_path)
|
35
|
+
FileUtils.rm_rf master_path
|
36
|
+
FileUtils.rm_rf target_path
|
37
|
+
|
38
|
+
FileUtils.mkdir_p master_path
|
39
|
+
FileUtils.mkdir_p target_path
|
40
|
+
|
41
|
+
(1...10).each do |i|
|
42
|
+
path = File.join(master_path, 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
|
+
let(:tmp_path) {File.join(__dir__, 'tmp')}
|
53
|
+
let(:master_path) {File.join(__dir__, 'tmp/master')}
|
54
|
+
let(:target_path) {File.join(__dir__, 'tmp/target')}
|
55
|
+
|
56
|
+
before(:each) do
|
57
|
+
create_files(master_path, target_path)
|
58
|
+
end
|
59
|
+
|
60
|
+
after(:each) do
|
61
|
+
# FileUtils.rm_rf tmp_path
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
# Copyright, 2016, 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 'synco/directory'
|
24
|
+
|
25
|
+
describe Synco::Directory.new(".", arguments: ['--foo']) do
|
26
|
+
it "should have arguments" do
|
27
|
+
expect(subject.arguments).to include('--foo')
|
28
|
+
end
|
29
|
+
|
30
|
+
it "must be relative path" do
|
31
|
+
expect{Synco::Directory.new("/var")}.to raise_error(ArgumentError)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'synco'
|
4
|
+
require 'synco/shells/ssh'
|
5
|
+
require 'synco/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", "Synco", ["Backup Status"]
|
14
|
+
# $growl.register
|
15
|
+
|
16
|
+
$stdout.sync = true
|
17
|
+
$stderr.sync = true
|
18
|
+
|
19
|
+
Synco::run_script do |script|
|
20
|
+
self.method = Synco::Methods::RSyncSnapshot.new(:push, "--archive", "--compress", "--stats")
|
21
|
+
|
22
|
+
self.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
|
+
# Runs after all directories have been successfully backed up.
|
32
|
+
server.on(:success) do
|
33
|
+
target.run "synco", "rotate"
|
34
|
+
target.run "synco", "prune"
|
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
|
@@ -0,0 +1,91 @@
|
|
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 'synco'
|
7
|
+
require 'synco/shells/ssh'
|
8
|
+
require 'synco/methods/rsync'
|
9
|
+
require 'synco/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 = Synco::Script.new do |script|
|
20
|
+
script.method = Synco::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 = Synco::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
|
+
|
61
|
+
context = Synco::Context.new(script)
|
62
|
+
context.run!
|
63
|
+
|
64
|
+
if MONITOR
|
65
|
+
# Monitor directories for changes:
|
66
|
+
monitor = FSSM::Monitor.new(:directories => true)
|
67
|
+
|
68
|
+
# The event timer aggregates events into a single callback which will be called at most
|
69
|
+
# once every k seconds (where k = 10 in this case).
|
70
|
+
$event_timer = Synco::EventTimer.new(10) do
|
71
|
+
$script.run!
|
72
|
+
end
|
73
|
+
|
74
|
+
$script.directories.each do |directory|
|
75
|
+
full_path = $script[:src].full_path(directory)
|
76
|
+
puts "Monitoring path: #{full_path}"
|
77
|
+
|
78
|
+
monitor.path(full_path, "**/*") do
|
79
|
+
update { $event_timer.trigger! }
|
80
|
+
delete { $event_timer.trigger! }
|
81
|
+
create { $event_timer.trigger! }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
begin
|
86
|
+
monitor.run
|
87
|
+
ensure
|
88
|
+
# We should wait for the backup to complete nicely.
|
89
|
+
$event_timer.join
|
90
|
+
end
|
91
|
+
end
|