Sorry I took so long to reply. Forgot about this thread. I am using
straight rsync. Running an rsync daemon on the servers I want. Then
I setup modules for the access. The reason I do this is to avoid
having ssh keys with blank passwords on my servers. Also, this is
only available on the internal network, so I'll also use things like
firewall rules and access-list in rsync to make sure only the machines
I want to get rsync access can.
···
On Sep 1, 11:05 am, Bob Hutchison <hu...@recursive.ca> wrote:
On 31-Aug-07, at 4:15 PM, dusty wrote:
> I haven't found any either, but I do have a nagios plugin using rsync
> to check the timestamps on remote files over rsync. New to posting
> here, whats the best way to post code? Include it inline? I'd be
> happy to share if you want it. I basically use open4 to call rsync
> and then parse the results. It might be helpful in your wheel
> project.
Is this rsync+ssh? If so, what did you handle passwords when making
the connection (I wound up going though disgusting conniptions using
expect)? I know that you can avoid login by setting up .ssh/
known_hosts but that is frowned upon in some circles.
Cheers,
Bob
> Dusty Doris
----
Bob Hutchison -- tumblelog at http://www.recursive.ca/so/
Recursive Design Inc. -- weblog athttp://www.recursive.ca/
hutchhttp://www.recursive.ca/ -- works onhttp://www.raconteur.info/
cms-for-static-content/home/
----
require 'rubygems'
require 'open4'
class RsyncUtils
attr_reader :rsync
def initialize(path='')
paths = ['/bin',
'/usr/bin',
'/usr/local/bin',
'/opt/local/bin'
]
paths << path unless path.empty?
paths.each() do |path|
if(test(?x, "#{path}/rsync"))
@rsync = "#{path}/rsync"
end
end
raise "Cannot find rsync, please specify the path" unless @rsync
end
def list(hostname,path,recurs=false)
recursive = "--recursive" if recurs
r = run_command("#{@rsync} #{recursive} #{hostname}::#{path}")
if r.exitstatus == 0
r.results = RsyncFile.parse_list(r.stdout)
end
r
end
def list_recursive(hostname,path)
list(hostname,path,true)
end
private
def run_command(command)
pid, stdin, stdout, stderr = Open4.popen4(command)
ignored, status = Process::waitpid2 pid
RsyncResult.new(stdout.readlines,
stderr.readlines,
status.exitstatus)
end
end
Here is a class that hands back my results
----------
class RsyncResult
attr_reader :stdout, :stderr, :exitstatus
attr_accessor :results
def initialize(stdout,stderr,exitstatus)
@stdout = stdout
@stderr = stderr
@exitstatus = exitstatus
end
end
Here is the class that parses the filelisting to tell me about the
files
------
class RsyncFile
attr_reader :name, :type, :time, :size
FILE_TYPE = 0
DIRECTORY_TYPE = 1
UNKNOWN_TYPE = 2
def initialize(name,type,time,size)
@name = name
@time = time
@size = size
@type = type
end
def is_file?
@type == FILE_TYPE
end
def is_dir?
@type == DIRECTORY_TYPE
end
def self.parse_list(files)
results =
files.each do |file|
parts = file.split
case parts[0]
when /^[rwx-]{10}$/
type = FILE_TYPE
when /^d[rwx-]{9}$/
type = DIRECTORY_TYPE
else
type = UNKNOWN_TYPE
end
time = Time.local(*ParseDate::parsedate("#{parts[2]}
#{parts[3]}"))
size = parts[1].to_i
name = parts[4]
results << RsyncFile.new(name,type,time,size)
end
results
end
end
Here is how I'd use it in a script.
rsync = RsyncUtils.new
check = rsync.list(@options["--hostname"],@options["--
path"],@options["--recursive"])
if check.exitstatus > 0
raise "#{check.stderr}"
end
#This would list all the files - the rsync output
if @options["--verbose"]
puts check.stdout
exit(0)
end
Now assume I have another class that is do a comparison of the results
for me. That is where I'm calling crit.compare. That's not as
important, as you can see I'm simply iterating through the results and
checking the Time on the current server vs. the time on the remove
file.
check.results.each do |r|
if r.type == RsyncFile::FILE_TYPE
diff = ((Time.now - r.time) - @options["--drift"].to_i).to_i
critical_files << r.name unless crit.compare(diff)
warning_files << r.name unless warn.compare(diff)
end
end
So, basically I would call the script
./rsync_file_age.rb --hostname somehost --path somedir/anotherdir/ --
warning 0:10 --critical 10:20
That would compile a command to RsyncUtils such as
rsync somehost::somedir/anotherdir/
It would then use open4 to run that command and would parse the
results.
Hope that is helpful.
BTW an rsyncd.conf file might look like this and would provide the
somedir module.
pid file = /var/run/rsyncd.pid
hosts allow = 10.0.0.10
uid = nobody
gid = nogroup
use chroot = no
max connections = 4
syslog facility = local5
[somedir]
path = /var/somedir
read only = true