lsync 1.2.5 → 2.0.2
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/README.md +51 -0
- data/lib/lsync.rb +0 -23
- data/lib/lsync/action.rb +97 -92
- data/lib/lsync/actions/darwin/disk +5 -5
- data/lib/lsync/actions/generic/prune +29 -7
- data/lib/lsync/actions/generic/rotate +52 -40
- data/lib/lsync/actions/linux/disk +11 -11
- data/lib/lsync/actions/linux/terminal +2 -0
- data/lib/lsync/directory.rb +49 -35
- data/lib/lsync/error.rb +30 -30
- data/lib/lsync/event_handler.rb +72 -0
- data/lib/lsync/event_timer.rb +80 -0
- data/lib/lsync/method.rb +19 -185
- data/lib/lsync/methods/rsync.rb +132 -0
- data/lib/lsync/run.rb +30 -29
- data/lib/lsync/script.rb +212 -125
- data/lib/lsync/server.rb +77 -92
- data/lib/lsync/shell.rb +58 -97
- data/lib/lsync/shell_client.rb +65 -61
- data/lib/lsync/shells/ssh.rb +47 -0
- data/lib/lsync/tee_logger.rb +44 -31
- data/lib/lsync/version.rb +3 -3
- metadata +25 -58
- data/bin/lsync +0 -142
- data/lib/lsync/extensions.rb +0 -22
- data/lib/lsync/lb.py +0 -1304
- data/lib/lsync/password.rb +0 -35
- data/lib/lsync/plan.rb +0 -249
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
require 'lsync/shell'
|
3
|
+
|
4
|
+
module LSync
|
5
|
+
module Shells
|
6
|
+
# SSH shell provides access to a remote server using SSH.
|
7
|
+
class SSH < Shell
|
8
|
+
def initialize(options = {})
|
9
|
+
super(options[:command] || "ssh", options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# The connection options for ssh
|
13
|
+
# [`:port`] The remote port to use.
|
14
|
+
# [`:key`] A specific key file to use.
|
15
|
+
# [`:keys`] A specific array of key files to use.
|
16
|
+
# [`:timeout`] How long to wait until connection fails if no response is received.
|
17
|
+
# [`:compression`] Enable compression.
|
18
|
+
# [`:user`] Connect as a specific user.
|
19
|
+
def command_arguments
|
20
|
+
args = []
|
21
|
+
|
22
|
+
@options.each do |k,v|
|
23
|
+
case(k.to_sym)
|
24
|
+
when :port
|
25
|
+
args += ['-p', v.to_s]
|
26
|
+
when :key
|
27
|
+
args += ['-i', v]
|
28
|
+
when :keys
|
29
|
+
v.each { |key_path| args += ['-i', key_path] }
|
30
|
+
when :timeout
|
31
|
+
args += ['-o', "ConnectTimeout #{v.to_i}".to_cmd]
|
32
|
+
when :compression
|
33
|
+
args += ['-C'] if v
|
34
|
+
when :user
|
35
|
+
args += ['-l', v.to_s]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
return args
|
40
|
+
end
|
41
|
+
|
42
|
+
def connection_command(server, arguments = [])
|
43
|
+
super(server, arguments + command_arguments)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/lsync/tee_logger.rb
CHANGED
@@ -1,37 +1,50 @@
|
|
1
1
|
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
2
|
+
module LSync
|
3
|
+
# A helper to provide easy access to the TeeLogger functionality.
|
4
|
+
module TeeHelper
|
5
|
+
def tee(*loggers)
|
6
|
+
return TeeLogger.new(self, *loggers)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# The tee logger provides a simple split logging system where multiple logs may receive the same
|
11
|
+
# messages. These logs can route messages to different destinations using different formatting.
|
12
|
+
class TeeLogger
|
13
|
+
def initialize(*loggers)
|
14
|
+
@loggers = Set.new(loggers.flatten.compact)
|
15
|
+
end
|
16
|
+
|
17
|
+
attr :loggers
|
18
|
+
|
19
|
+
def self.logger_methods
|
20
|
+
Set.new(Logger.instance_methods) - Set.new(Object.instance_methods + %w(tee))
|
21
|
+
end
|
22
|
+
|
23
|
+
logger_methods.each do |method|
|
24
|
+
define_method(method) do |*args|
|
25
|
+
@loggers.each { |l| l.send(method, *args) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
include TeeHelper
|
30
|
+
end
|
31
|
+
|
32
|
+
# A minimal log format that keeps track of the start time, and prints the minimal amount of information.
|
33
|
+
class MinimalLogFormat
|
34
|
+
def initialize
|
35
|
+
@start_time = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(severity, time, progname, msg)
|
39
|
+
@start_time ||= time
|
40
|
+
diff = time - @start_time
|
41
|
+
|
42
|
+
"[T+#{sprintf('%0.1f', diff).ljust(5)} #{severity.rjust(5)}] #{msg}\n"
|
43
|
+
end
|
44
|
+
end
|
26
45
|
end
|
27
46
|
|
28
47
|
class Logger
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
class MinimalLogFormat
|
33
|
-
def call(severity, time, progname, msg)
|
34
|
-
"[#{severity.rjust(8)}] #{msg}\n"
|
35
|
-
end
|
48
|
+
include LSync::TeeHelper
|
36
49
|
end
|
37
50
|
|
data/lib/lsync/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lsync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 21
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
|
-
- 1
|
8
6
|
- 2
|
9
|
-
-
|
10
|
-
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 2.0.2
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Samuel Williams
|
@@ -15,75 +14,46 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
17
|
+
date: 2011-07-19 00:00:00 +12:00
|
18
|
+
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
21
|
+
name: fingerprint
|
23
22
|
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
25
|
- - ">="
|
28
26
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
27
|
segments:
|
31
|
-
-
|
32
|
-
|
28
|
+
- 1
|
29
|
+
- 1
|
30
|
+
- 3
|
31
|
+
version: 1.1.3
|
33
32
|
type: :runtime
|
34
33
|
version_requirements: *id001
|
35
34
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
35
|
+
name: rexec
|
37
36
|
prerelease: false
|
38
37
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
38
|
requirements:
|
41
39
|
- - ">="
|
42
40
|
- !ruby/object:Gem::Version
|
43
|
-
hash: 3
|
44
41
|
segments:
|
45
|
-
-
|
46
|
-
|
42
|
+
- 1
|
43
|
+
- 2
|
44
|
+
- 6
|
45
|
+
version: 1.2.6
|
47
46
|
type: :runtime
|
48
47
|
version_requirements: *id002
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: ruleby
|
51
|
-
prerelease: false
|
52
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
-
none: false
|
54
|
-
requirements:
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
hash: 3
|
58
|
-
segments:
|
59
|
-
- 0
|
60
|
-
version: "0"
|
61
|
-
type: :runtime
|
62
|
-
version_requirements: *id003
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: rexec
|
65
|
-
prerelease: false
|
66
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
|
-
requirements:
|
69
|
-
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
hash: 3
|
72
|
-
segments:
|
73
|
-
- 0
|
74
|
-
version: "0"
|
75
|
-
type: :runtime
|
76
|
-
version_requirements: *id004
|
77
48
|
description:
|
78
49
|
email: samuel.williams@oriontransfer.co.nz
|
79
|
-
executables:
|
80
|
-
|
50
|
+
executables: []
|
51
|
+
|
81
52
|
extensions: []
|
82
53
|
|
83
54
|
extra_rdoc_files: []
|
84
55
|
|
85
56
|
files:
|
86
|
-
- bin/lsync
|
87
57
|
- lib/lsync/action.rb
|
88
58
|
- lib/lsync/actions/darwin/disk
|
89
59
|
- lib/lsync/actions/darwin/terminal
|
@@ -93,21 +63,22 @@ files:
|
|
93
63
|
- lib/lsync/actions/linux/terminal
|
94
64
|
- lib/lsync/directory.rb
|
95
65
|
- lib/lsync/error.rb
|
96
|
-
- lib/lsync/
|
97
|
-
- lib/lsync/
|
66
|
+
- lib/lsync/event_handler.rb
|
67
|
+
- lib/lsync/event_timer.rb
|
98
68
|
- lib/lsync/method.rb
|
99
|
-
- lib/lsync/
|
100
|
-
- lib/lsync/plan.rb
|
69
|
+
- lib/lsync/methods/rsync.rb
|
101
70
|
- lib/lsync/run.rb
|
102
71
|
- lib/lsync/script.rb
|
103
72
|
- lib/lsync/server.rb
|
104
73
|
- lib/lsync/shell.rb
|
105
74
|
- lib/lsync/shell_client.rb
|
75
|
+
- lib/lsync/shells/ssh.rb
|
106
76
|
- lib/lsync/tee_logger.rb
|
107
77
|
- lib/lsync/version.rb
|
108
78
|
- lib/lsync.rb
|
109
|
-
|
110
|
-
|
79
|
+
- README.md
|
80
|
+
has_rdoc: yard
|
81
|
+
homepage: http://www.oriontransfer.co.nz/gems/lsync
|
111
82
|
licenses: []
|
112
83
|
|
113
84
|
post_install_message:
|
@@ -116,27 +87,23 @@ rdoc_options: []
|
|
116
87
|
require_paths:
|
117
88
|
- lib
|
118
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
-
none: false
|
120
90
|
requirements:
|
121
91
|
- - ">="
|
122
92
|
- !ruby/object:Gem::Version
|
123
|
-
hash: 3
|
124
93
|
segments:
|
125
94
|
- 0
|
126
95
|
version: "0"
|
127
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
-
none: false
|
129
97
|
requirements:
|
130
98
|
- - ">="
|
131
99
|
- !ruby/object:Gem::Version
|
132
|
-
hash: 3
|
133
100
|
segments:
|
134
101
|
- 0
|
135
102
|
version: "0"
|
136
103
|
requirements: []
|
137
104
|
|
138
105
|
rubyforge_project:
|
139
|
-
rubygems_version: 1.3.
|
106
|
+
rubygems_version: 1.3.6
|
140
107
|
signing_key:
|
141
108
|
specification_version: 3
|
142
109
|
summary: LSync is a tool for scripted synchronization and backups.
|
data/bin/lsync
DELETED
@@ -1,142 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'ftools'
|
4
|
-
require 'lsync'
|
5
|
-
require 'lsync/version'
|
6
|
-
require 'optparse'
|
7
|
-
|
8
|
-
OPTIONS = {
|
9
|
-
:ConfigFiles => [],
|
10
|
-
:LogPath => "/var/log/lsync/backup.log"
|
11
|
-
}
|
12
|
-
|
13
|
-
ARGV.options do |o|
|
14
|
-
script_name = File.basename($0)
|
15
|
-
|
16
|
-
o.set_summary_indent(' ')
|
17
|
-
o.banner = "Usage: #{script_name} [options] [directory | config]"
|
18
|
-
o.define_head "This script is used to run lsync scripts and plans. If you specify a directory, files ending in .lsync-script and .lsync-plan will all be processed."
|
19
|
-
|
20
|
-
o.separator ""
|
21
|
-
o.separator "Help and Copyright information"
|
22
|
-
|
23
|
-
o.on("-l log_path", String, "Set the directory for backup logs") do |log_path|
|
24
|
-
OPTIONS[:LogPath] = log_path
|
25
|
-
end
|
26
|
-
|
27
|
-
o.on_tail("--copy", "Display copyright information") do
|
28
|
-
puts "#{script_name} v#{LSync::VERSION::STRING}. Copyright (c) 2008-2010 Samuel Williams. Released under the GPLv3."
|
29
|
-
puts "See http://www.oriontransfer.co.nz/ for more information."
|
30
|
-
|
31
|
-
exit
|
32
|
-
end
|
33
|
-
|
34
|
-
o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
|
35
|
-
end.parse!
|
36
|
-
|
37
|
-
# ============================== Main Scripts / Plans ==============================
|
38
|
-
|
39
|
-
class LogPathChecker
|
40
|
-
def initialize(directory, filename)
|
41
|
-
full_path = File.join(directory, filename)
|
42
|
-
|
43
|
-
@directory_writable = File.directory?(directory) && File.writable?(directory)
|
44
|
-
@file_not_writable = File.exist?(full_path) && !File.writable?(full_path)
|
45
|
-
|
46
|
-
@accessable = @directory_writable && !@file_not_writable
|
47
|
-
@full_path = full_path
|
48
|
-
end
|
49
|
-
|
50
|
-
attr :accessable
|
51
|
-
attr :full_path
|
52
|
-
end
|
53
|
-
|
54
|
-
def setup_logging
|
55
|
-
# Console log output
|
56
|
-
$console_log = Logger.new($stdout)
|
57
|
-
$console_log.formatter = MinimalLogFormat.new
|
58
|
-
|
59
|
-
# File log output
|
60
|
-
filename = File.basename(OPTIONS[:LogPath])
|
61
|
-
directory = File.dirname(OPTIONS[:LogPath])
|
62
|
-
|
63
|
-
if filename == nil || filename == ""
|
64
|
-
filename = "backup.log"
|
65
|
-
end
|
66
|
-
|
67
|
-
check = LogPathChecker.new(directory, filename)
|
68
|
-
unless check.accessable
|
69
|
-
$console_log.warn "Could not write to #{check.full_path.dump} - changing log path to #{Dir.pwd.dump}"
|
70
|
-
|
71
|
-
directory = Dir.pwd
|
72
|
-
check = LogPathChecker.new(directory, filename)
|
73
|
-
end
|
74
|
-
|
75
|
-
if check.accessable
|
76
|
-
$backup_log = Logger.new(check.full_path, 'weekly')
|
77
|
-
else
|
78
|
-
$console_log.warn "Could not write to #{check.full_path.dump} - not logging to disk"
|
79
|
-
$backup_log = nil
|
80
|
-
end
|
81
|
-
|
82
|
-
$logger = TeeLogger.new($console_log, $backup_log)
|
83
|
-
end
|
84
|
-
|
85
|
-
def process_config_files
|
86
|
-
ARGV.each do |p|
|
87
|
-
unless File.exists? p
|
88
|
-
$logger.error "Could not process #{p}"
|
89
|
-
exit(20)
|
90
|
-
end
|
91
|
-
|
92
|
-
if File.directory? p
|
93
|
-
OPTIONS[:ConfigFiles] += Dir[File.join(p, "*.{lsync-script,lsync-plan}")]
|
94
|
-
else
|
95
|
-
OPTIONS[:ConfigFiles] << p
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def run_backups(config_files)
|
101
|
-
if config_files.size == 0
|
102
|
-
$logger.warn "No configuration files specified!"
|
103
|
-
else
|
104
|
-
config_files.each do |c|
|
105
|
-
config = LSync::load_from_file(c)
|
106
|
-
config.logger = $logger
|
107
|
-
config.run_backup
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def dump_exception_backtrace ex
|
113
|
-
ex.backtrace.each do |bt|
|
114
|
-
$logger.error bt
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
# Main Script Execution
|
119
|
-
setup_logging
|
120
|
-
|
121
|
-
process_config_files
|
122
|
-
|
123
|
-
$logger.info " Backup beginning at #{Time.now.to_s} ".center(96, "=")
|
124
|
-
|
125
|
-
begin
|
126
|
-
run_backups(OPTIONS[:ConfigFiles])
|
127
|
-
rescue LSync::Error
|
128
|
-
$logger.error "#{$!.class.name}: #{$!.to_s}. Dumping backtrace:"
|
129
|
-
dump_exception_backtrace($!)
|
130
|
-
exit(230)
|
131
|
-
rescue Interrupt
|
132
|
-
$logger.error "Backup process recevied interrupt (Ctrl-C). Dumping backtrace:"
|
133
|
-
dump_exception_backtrace($!)
|
134
|
-
exit(240)
|
135
|
-
rescue
|
136
|
-
$logger.error "Unknown exception #{$!.class.name} thrown: #{$!.to_s}. Dumping backtrace:"
|
137
|
-
dump_exception_backtrace($!)
|
138
|
-
exit(250)
|
139
|
-
ensure
|
140
|
-
$logger.info " Backup finishing at #{Time.now.to_s} ".center(96, "=")
|
141
|
-
end
|
142
|
-
|