Ruby 1.9.3, net-ssh 2.9.2
I am working on a project, in which I need to diff the same directory (and its subdirectories) on two different servers (local and remote). From there, I need to copy the newest/recently modified files to the correct server, and delete from the remote if a file is not present in the local.
NOTE: I cannot use rsync. We are backing up Asterisk-related directories to GlusterFS. At thousands of files, rsync comparing local to the Gluster volume is very slow (when we need it under 1 minute).
Here is my current code. I am omitting my work for copying/removing files, as I want to take this one step at a time.
require 'thread'
require 'date'
require 'rubygems'
require 'net/ssh'
SERVERS = ['local17', 'development']
CLIENT = SERVERS[0]
CLIENT_PATH = '/home/hstevens/temp_gfs'
BRICK_PATH = '/export/hunter_test'
@files = {
SERVERS[0] => {},
SERVERS[1] => {}
}
def grab_filenames_and_dates(files, server)
files.reject { |x| File.directory? x }
files.each do |file|
name = `ls --full-time "#{file}" | awk '{$1=$2=$3=$4=$5=$6=$7=$8=""; print $0}'`.strip
date = `ls --full-time "#{file}" | awk '{print $6, $7, $8}'`.strip
@files[server][name] = DateTime.parse(date)
end
end
# Collect diff information on all servers
ls_threads = SERVERS.map do |server|
Thread.new do
if server == CLIENT
files = Dir.glob("#{CLIENT_PATH}/**/*")
grab_filenames_and_dates(files, server)
else
Net::SSH.start(server, 'hstevens') do |session|
files = session.exec!(%Q(ruby -e 'puts Dir.glob("#{BRICK_PATH}/**/*")')).split("\n")
grab_filenames_and_dates(files, server)
end
end
end
end
ls_threads.each(&:join)
When I run my program, it works for the local server (CLIENT
/local17
), but fails on the remote server. I tried debugging statements (printing pwd
to console`, and it appears that although the method is called inside the Net::SSH session block, it is acting on my local server.
ls: cannot access /export/hunter_test/sorttable.js: No such file or directory
ls: cannot access /export/hunter_test/sorttable.js: No such file or directory
./gluster_rsync.rb:36:in `parse': invalid date (ArgumentError)
from ./gluster_rsync.rb:36:in `block in grab_filenames_and_dates'
from ./gluster_rsync.rb:33:in `each'
from ./gluster_rsync.rb:33:in `grab_filenames_and_dates'
from ./gluster_rsync.rb:53:in `block (3 levels) in <main>'
from /usr/local/lib/ruby/gems/1.9.1/gems/net-ssh-2.9.2/lib/net/ssh.rb:215:in `start'
from ./gluster_rsync.rb:51:in `block (2 levels) in <main>'
How can I properly wrap a method call inside a Net::SSH session?