rssh 0.0.1
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/Rakefile +10 -0
- data/lib/old/ssh.rb +11 -0
- data/lib/rsh.rb +18 -0
- data/lib/rsh/box.rb +145 -0
- data/lib/rsh/drivers/abstract.rb +19 -0
- data/lib/rsh/drivers/local.rb +52 -0
- data/lib/rsh/drivers/ssh.rb +145 -0
- data/lib/rsh/gems.rb +2 -0
- data/lib/rsh/support.rb +30 -0
- data/readme.md +4 -0
- data/spec/abstract_driver.rb +82 -0
- data/spec/abstract_driver/dir/dir2/file +0 -0
- data/spec/abstract_driver/local_file +1 -0
- data/spec/box_spec.rb +105 -0
- data/spec/box_spec/dir/dir2/file +0 -0
- data/spec/box_spec/local_file +1 -0
- data/spec/config.example.yml +4 -0
- data/spec/config.yml +5 -0
- data/spec/local_driver_spec.rb +9 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/ssh_driver_spec.rb +15 -0
- metadata +84 -0
data/Rakefile
ADDED
data/lib/old/ssh.rb
ADDED
data/lib/rsh.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
raise 'ruby 1.9.2 or higher required!' if RUBY_VERSION < '1.9.2'
|
|
2
|
+
|
|
3
|
+
require 'rsh/gems'
|
|
4
|
+
|
|
5
|
+
require 'open3'
|
|
6
|
+
|
|
7
|
+
require 'net/ssh'
|
|
8
|
+
require 'net/sftp'
|
|
9
|
+
|
|
10
|
+
%w(
|
|
11
|
+
support
|
|
12
|
+
|
|
13
|
+
drivers/abstract
|
|
14
|
+
drivers/local
|
|
15
|
+
drivers/ssh
|
|
16
|
+
|
|
17
|
+
box
|
|
18
|
+
).each{|f| require "rsh/#{f}"}
|
data/lib/rsh/box.rb
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
module Rsh
|
|
2
|
+
class Box
|
|
3
|
+
attr_accessor :options
|
|
4
|
+
|
|
5
|
+
def initialize options = {}
|
|
6
|
+
@options = options
|
|
7
|
+
options[:host] ||= 'localhost'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def driver
|
|
11
|
+
unless @driver
|
|
12
|
+
klass = options[:host] == 'localhost' ? Drivers::Local : Drivers::Ssh
|
|
13
|
+
@driver = klass.new options
|
|
14
|
+
end
|
|
15
|
+
@driver
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def local_driver
|
|
19
|
+
@local_driver ||= Drivers::Local.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def bulk &b
|
|
23
|
+
driver.bulk &b
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def upload_file from_local_path, to_remote_path, options = {}
|
|
27
|
+
bulk do
|
|
28
|
+
raise "file '#{from_local_path}' not exists!" unless local_driver.file_exist? from_local_path
|
|
29
|
+
if driver.file_exist?(to_remote_path)
|
|
30
|
+
if options[:override]
|
|
31
|
+
driver.remove_file to_remote_path
|
|
32
|
+
else
|
|
33
|
+
raise "file '#{to_remote_path}' already exists!"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
driver.upload_file from_local_path, to_remote_path
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def download_file from_remote_path, to_local_path, options = {}
|
|
41
|
+
bulk do
|
|
42
|
+
raise "file #{from_remote_path} not exists!" unless driver.file_exist?(from_remote_path)
|
|
43
|
+
if local_driver.file_exist? to_local_path
|
|
44
|
+
if options[:override]
|
|
45
|
+
local_driver.remove_file to_local_path
|
|
46
|
+
else
|
|
47
|
+
raise "file #{to_local_path} already exists!"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
driver.download_file from_remote_path, to_local_path
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def remove_file remote_file_path
|
|
55
|
+
bulk do
|
|
56
|
+
raise "file #{remote_file_path} not exists!" unless driver.file_exist? remote_file_path
|
|
57
|
+
driver.remove_file remote_file_path
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def exist? remote_path
|
|
62
|
+
driver.exist? remote_path
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def file_exist? remote_file_path
|
|
66
|
+
driver.file_exist? remote_file_path
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def remove_directory remote_directory_path
|
|
70
|
+
bulk do
|
|
71
|
+
raise "directory #{remote_directory_path} not exists!" unless driver.directory_exist? remote_directory_path
|
|
72
|
+
driver.remove_directory remote_directory_path
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def create_directory remote_path, options = {}
|
|
77
|
+
bulk do
|
|
78
|
+
if driver.directory_exist?(remote_path)
|
|
79
|
+
if options[:override]
|
|
80
|
+
driver.remove_directory remote_path
|
|
81
|
+
else
|
|
82
|
+
raise "directory '#{remote_path}' already exists!"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
driver.create_directory remote_path
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def directory_exist? remote_path
|
|
90
|
+
driver.directory_exist? remote_path
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def upload_directory from_local_path, to_remote_path, options = {}
|
|
94
|
+
bulk do
|
|
95
|
+
raise "directory '#{from_local_path}' not exists!" unless local_driver.directory_exist? from_local_path
|
|
96
|
+
if driver.directory_exist?(to_remote_path)
|
|
97
|
+
if options[:override]
|
|
98
|
+
driver.remove_directory to_remote_path
|
|
99
|
+
else
|
|
100
|
+
raise "directory '#{to_remote_path}' already exists!"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
driver.upload_directory from_local_path, to_remote_path
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def download_directory from_remote_path, to_local_path, options = {}
|
|
108
|
+
bulk do
|
|
109
|
+
raise "directory #{from_remote_path} not exists!" unless driver.directory_exist?(from_remote_path)
|
|
110
|
+
if local_driver.directory_exist? to_local_path
|
|
111
|
+
if options[:override]
|
|
112
|
+
local_driver.remove_directory to_local_path
|
|
113
|
+
else
|
|
114
|
+
raise "directory #{to_local_path} already exists!"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
driver.download_directory from_remote_path, to_local_path
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def with_tmp_dir &block
|
|
122
|
+
bulk do
|
|
123
|
+
tmp_dir = driver.generate_tmp_dir_name
|
|
124
|
+
begin
|
|
125
|
+
remove_directory tmp_dir if directory_exist? tmp_dir
|
|
126
|
+
create_directory tmp_dir
|
|
127
|
+
block.call
|
|
128
|
+
ensure
|
|
129
|
+
remove_directory tmp_dir if directory_exist? tmp_dir
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def bash cmd
|
|
135
|
+
code, stdout, stderr = driver.exec cmd
|
|
136
|
+
raise "can't execute '#{cmd}'!" unless code == 0
|
|
137
|
+
return stdout, stderr
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
protected
|
|
141
|
+
def method_missing m, *a, &b
|
|
142
|
+
driver.send m, *a, &b
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Rsh
|
|
2
|
+
module Drivers
|
|
3
|
+
class Abstract
|
|
4
|
+
attr_reader :options
|
|
5
|
+
|
|
6
|
+
def initialize options = {}
|
|
7
|
+
@options = options
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def bulk &b
|
|
11
|
+
b.call
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def generate_tmp_dir_name
|
|
15
|
+
"/tmp/ssh_tmp_dir_#{rand(10**6)}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Rsh
|
|
2
|
+
module Drivers
|
|
3
|
+
class Local < Abstract
|
|
4
|
+
def bulk &b
|
|
5
|
+
b.call
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def upload_file from_local_path, to_remote_path
|
|
9
|
+
FileUtils.copy from_local_path, to_remote_path
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def download_file from_remote_path, to_local_path
|
|
13
|
+
FileUtils.copy from_remote_path, to_local_path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def exist? remote_file_path
|
|
17
|
+
File.exist? remote_file_path
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
alias_method :directory_exist?, :exist?
|
|
21
|
+
alias_method :file_exist?, :exist?
|
|
22
|
+
|
|
23
|
+
def remove_file remote_file_path
|
|
24
|
+
File.delete remote_file_path
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def create_directory path
|
|
28
|
+
Dir.mkdir path
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def remove_directory path
|
|
32
|
+
FileUtils.rm_r path
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def upload_directory from_local_path, to_remote_path
|
|
36
|
+
FileUtils.cp_r from_local_path, to_remote_path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def download_directory from_remote_path, to_local_path
|
|
40
|
+
FileUtils.cp_r from_remote_path, to_local_path
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def exec command
|
|
44
|
+
code, stdout, stderr = Open3.popen3 command do |stdin, stdout, stderr, waitth|
|
|
45
|
+
[waitth.value.to_i, stdout.read, stderr.read]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
return code, stdout, stderr
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
module Rsh
|
|
2
|
+
module Drivers
|
|
3
|
+
class Ssh < Abstract
|
|
4
|
+
def initialize options = {}
|
|
5
|
+
super
|
|
6
|
+
raise "ssh options not provided!" unless options[:ssh]
|
|
7
|
+
raise "invalid ssh options!" unless options[:ssh].is_a?(Hash)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def upload_file from_local_path, to_remote_path
|
|
11
|
+
remote do |ssh, sftp|
|
|
12
|
+
sftp.upload! from_local_path, to_remote_path
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def download_file from_remote_path, to_local_path
|
|
17
|
+
File.open to_local_path, "w" do |out|
|
|
18
|
+
remote do |ssh, sftp|
|
|
19
|
+
sftp.download! from_remote_path, out #, :recursive => true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def exist? remote_file_path
|
|
25
|
+
remote do |ssh, sftp|
|
|
26
|
+
begin
|
|
27
|
+
fattrs = sftp.stat! remote_file_path
|
|
28
|
+
fattrs.directory? or fattrs.file? or fattrs.symlink?
|
|
29
|
+
rescue Net::SFTP::StatusException
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
alias_method :directory_exist?, :exist?
|
|
35
|
+
alias_method :file_exist?, :exist?
|
|
36
|
+
|
|
37
|
+
def remove_file remote_file_path
|
|
38
|
+
remote do |ssh, sftp|
|
|
39
|
+
sftp.remove! remote_file_path
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def exec command
|
|
44
|
+
remote do |ssh, sftp|
|
|
45
|
+
# somehow net-ssh doesn't executes ~/.profile, so we need to execute it manually
|
|
46
|
+
# command = ". ~/.profile && #{command}"
|
|
47
|
+
|
|
48
|
+
stdout, stderr, code, signal = hacked_exec! ssh, command
|
|
49
|
+
|
|
50
|
+
return code, stdout, stderr
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def open_connection
|
|
55
|
+
ssh_options = self.options[:ssh].clone
|
|
56
|
+
host = options[:host] || raise('host not provided!')
|
|
57
|
+
user = ssh_options.delete(:user) || raise('user not provied!')
|
|
58
|
+
@ssh = Net::SSH.start(host, user, ssh_options)
|
|
59
|
+
@sftp = @ssh.sftp.connect
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def close_connection
|
|
63
|
+
@ssh.close
|
|
64
|
+
# @sftp.close not needed
|
|
65
|
+
@ssh, @sftp = nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def bulk &block
|
|
69
|
+
remote &block
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def create_directory path
|
|
73
|
+
remote do |ssh, sftp|
|
|
74
|
+
sftp.mkdir! path
|
|
75
|
+
# exec "mkdir #{path}"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def remove_directory path
|
|
80
|
+
exec "rm -r #{path}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def upload_directory from_local_path, to_remote_path
|
|
84
|
+
remote do |ssh, sftp|
|
|
85
|
+
sftp.upload! from_local_path, to_remote_path
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def download_directory from_remote_path, to_local_path
|
|
90
|
+
remote do |ssh, sftp|
|
|
91
|
+
sftp.download! from_remote_path, to_local_path, :recursive => true
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
protected
|
|
96
|
+
# taken from here http://stackoverflow.com/questions/3386233/how-to-get-exit-status-with-rubys-netssh-library/3386375#3386375
|
|
97
|
+
def hacked_exec!(ssh, command, &block)
|
|
98
|
+
stdout_data = ""
|
|
99
|
+
stderr_data = ""
|
|
100
|
+
exit_code = nil
|
|
101
|
+
exit_signal = nil
|
|
102
|
+
|
|
103
|
+
channel = ssh.open_channel do |channel|
|
|
104
|
+
channel.exec(command) do |ch, success|
|
|
105
|
+
raise "could not execute command: #{command.inspect}" unless success
|
|
106
|
+
|
|
107
|
+
channel.on_data{|ch2, data| stdout_data << data}
|
|
108
|
+
channel.on_extended_data{|ch2, type, data| stderr_data << data}
|
|
109
|
+
channel.on_request("exit-status"){|ch,data| exit_code = data.read_long}
|
|
110
|
+
channel.on_request("exit-signal"){|ch, data| exit_signal = data.read_long}
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
channel.wait
|
|
115
|
+
|
|
116
|
+
[stdout_data, stderr_data, exit_code, exit_signal]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def remote(&block)
|
|
120
|
+
if @ssh
|
|
121
|
+
block.call @ssh, @sftp
|
|
122
|
+
else
|
|
123
|
+
# Rails.logger.info "Connecting to remote Hadoop #{options[:user]}@#{options[:host]}"
|
|
124
|
+
begin
|
|
125
|
+
open_connection
|
|
126
|
+
block.call @ssh, @sftp
|
|
127
|
+
ensure
|
|
128
|
+
close_connection
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Net::SSH.start options[:host], options[:user], :config => true do |ssh|
|
|
132
|
+
# ssh.sftp.connect do |sftp|
|
|
133
|
+
# begin
|
|
134
|
+
# @ssh, @sftp = ssh, sftp
|
|
135
|
+
# block.call @ssh, @sftp
|
|
136
|
+
# ensure
|
|
137
|
+
# @ssh, @sftp = nil
|
|
138
|
+
# end
|
|
139
|
+
# end
|
|
140
|
+
# end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
data/lib/rsh/gems.rb
ADDED
data/lib/rsh/support.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'net/ssh'
|
|
3
|
+
require 'net/sftp'
|
|
4
|
+
|
|
5
|
+
# class File
|
|
6
|
+
# class << self
|
|
7
|
+
# def ensure_dir_exist directory, options = {}
|
|
8
|
+
# options = options.symbolize_keys
|
|
9
|
+
# clean = options.delete :clean
|
|
10
|
+
# raise "unsupported options #{options.keys}!" unless options.empty?
|
|
11
|
+
#
|
|
12
|
+
# FileUtils.rm_r directory, :force => true if clean and File.exist?(directory)
|
|
13
|
+
# FileUtils.mkdir_p directory
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# def copy_dir_content from, to
|
|
17
|
+
# Dir.glob "#{from}/*" do |item|
|
|
18
|
+
# FileUtils.cp_r item, to
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# def copy_dir from, to
|
|
23
|
+
# FileUtils.cp_r from, to
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# def remove_dir dir
|
|
27
|
+
# FileUtils.rm_r dir
|
|
28
|
+
# end
|
|
29
|
+
# end
|
|
30
|
+
# end
|
data/readme.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
shared_examples_for 'abstract driver' do
|
|
4
|
+
dir = "#{File.dirname __FILE__}/abstract_driver"
|
|
5
|
+
with_tmp_spec_dir dir, before: :each
|
|
6
|
+
|
|
7
|
+
describe "io" do
|
|
8
|
+
before :each do
|
|
9
|
+
@local_dir = spec_dir
|
|
10
|
+
@remote_dir = @driver.generate_tmp_dir_name
|
|
11
|
+
|
|
12
|
+
@driver.remove_directory @remote_dir if @driver.directory_exist? @remote_dir
|
|
13
|
+
@driver.create_directory @remote_dir
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after :each do
|
|
17
|
+
@driver.remove_directory @remote_dir if @driver.directory_exist? @remote_dir
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "files" do
|
|
21
|
+
before :each do
|
|
22
|
+
@local_file = "#{@local_dir}/local_file"
|
|
23
|
+
@check_file = "#{@local_dir}/check_file"
|
|
24
|
+
@remote_file = "#{@remote_dir}/remote_file"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "file_exist?" do
|
|
28
|
+
@driver.file_exist?(@remote_file).should be_false
|
|
29
|
+
@driver.upload_file(@local_file, @remote_file)
|
|
30
|
+
@driver.file_exist?(@remote_file).should be_true
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "upload & download file" do
|
|
34
|
+
@driver.upload_file(@local_file, @remote_file)
|
|
35
|
+
@driver.file_exist?(@remote_file).should be_true
|
|
36
|
+
|
|
37
|
+
@driver.download_file(@remote_file, @check_file)
|
|
38
|
+
File.read(@local_file).should == File.read(@check_file)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "remove_file" do
|
|
42
|
+
@driver.upload_file(@local_file, @remote_file)
|
|
43
|
+
@driver.file_exist?(@remote_file).should be_true
|
|
44
|
+
@driver.remove_file(@remote_file)
|
|
45
|
+
@driver.file_exist?(@remote_file).should be_false
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe 'directories' do
|
|
50
|
+
before :each do
|
|
51
|
+
@from_local, @remote_path, @to_local = "#{@local_dir}/dir", "#{@remote_dir}/upload", "#{@local_dir}/download"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "directory_exist?, create_directory, remove_directory" do
|
|
55
|
+
dir = "#{@remote_dir}/some_dir"
|
|
56
|
+
@driver.directory_exist?(dir).should be_false
|
|
57
|
+
@driver.create_directory(dir)
|
|
58
|
+
@driver.directory_exist?(dir).should be_true
|
|
59
|
+
@driver.remove_directory(dir)
|
|
60
|
+
@driver.directory_exist?(dir).should be_false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "upload_directory & download_directory" do
|
|
64
|
+
upload_path_check = "#{@remote_path}/dir2/file"
|
|
65
|
+
@driver.file_exist?(upload_path_check).should be_false
|
|
66
|
+
@driver.upload_directory(@from_local, @remote_path)
|
|
67
|
+
@driver.file_exist?(upload_path_check).should be_true
|
|
68
|
+
|
|
69
|
+
download_path_check = "#{@to_local}/dir2/file"
|
|
70
|
+
File.exist?(download_path_check).should be_false
|
|
71
|
+
@driver.download_directory(@remote_path, @to_local)
|
|
72
|
+
File.exist?(download_path_check).should be_true
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe "shell" do
|
|
78
|
+
it 'exec' do
|
|
79
|
+
@driver.exec("echo 'ok'").should == [0, "ok\n", ""]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
some content
|
data/spec/box_spec.rb
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Rsh::Box do
|
|
4
|
+
with_tmp_spec_dir before: :each
|
|
5
|
+
|
|
6
|
+
before :each do
|
|
7
|
+
@box = Rsh::Box.new
|
|
8
|
+
|
|
9
|
+
@local_dir = spec_dir
|
|
10
|
+
@remote_dir = @box.generate_tmp_dir_name
|
|
11
|
+
|
|
12
|
+
@box.remove_directory @remote_dir if @box.directory_exist? @remote_dir
|
|
13
|
+
@box.create_directory @remote_dir
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
after :each do
|
|
17
|
+
@box.remove_directory @remote_dir if @box.directory_exist? @remote_dir
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "io" do
|
|
21
|
+
describe "files" do
|
|
22
|
+
before :each do
|
|
23
|
+
@local_file = "#{@local_dir}/local_file"
|
|
24
|
+
@check_file = "#{@local_dir}/check_file"
|
|
25
|
+
@remote_file = "#{@remote_dir}/remote_file"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "file_exist?" do
|
|
29
|
+
@box.file_exist?(@remote_file).should be_false
|
|
30
|
+
@box.upload_file(@local_file, @remote_file)
|
|
31
|
+
@box.file_exist?(@remote_file).should be_true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "upload_file" do
|
|
35
|
+
@box.upload_file(@local_file, @remote_file)
|
|
36
|
+
@box.file_exist?(@remote_file).should be_true
|
|
37
|
+
|
|
38
|
+
lambda{@box.upload_file(@local_file, @remote_file)}.should raise_error(/exists/)
|
|
39
|
+
|
|
40
|
+
# upload with override
|
|
41
|
+
@box.upload_file(@local_file, @remote_file, override: true)
|
|
42
|
+
@box.file_exist?(@remote_file).should be_true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "download_file" do
|
|
46
|
+
lambda{@box.download_file(@remote_file, @check_file)}.should raise_error(/not exists/)
|
|
47
|
+
@box.upload_file(@local_file, @remote_file)
|
|
48
|
+
@box.download_file(@remote_file, @check_file)
|
|
49
|
+
File.read(@local_file).should == File.read(@check_file)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "remove_file" do
|
|
53
|
+
lambda{@box.remove_file(@remote_file)}.should raise_error(/not exists/)
|
|
54
|
+
@box.upload_file(@local_file, @remote_file)
|
|
55
|
+
@box.file_exist?(@remote_file).should be_true
|
|
56
|
+
@box.remove_file(@remote_file)
|
|
57
|
+
@box.file_exist?(@remote_file).should be_false
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe 'directories' do
|
|
62
|
+
before :each do
|
|
63
|
+
@from_local, @remote_path, @to_local = "#{@local_dir}/dir", "#{@remote_dir}/upload", "#{@local_dir}/download"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "directory_exist?" do
|
|
67
|
+
@box.file_exist?(@remote_path).should be_false
|
|
68
|
+
@box.upload_directory(@from_local, @remote_path)
|
|
69
|
+
@box.file_exist?(@remote_path).should be_true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "upload_directory" do
|
|
73
|
+
@box.upload_directory(@from_local, @remote_path)
|
|
74
|
+
@box.directory_exist?(@remote_path).should be_true
|
|
75
|
+
|
|
76
|
+
lambda{@box.upload_directory(@from_local, @remote_path)}.should raise_error(/exists/)
|
|
77
|
+
|
|
78
|
+
# upload with override
|
|
79
|
+
@box.upload_directory(@from_local, @remote_path, override: true)
|
|
80
|
+
@box.directory_exist?(@remote_path).should be_true
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "download_directory" do
|
|
84
|
+
lambda{@box.download_directory(@remote_path, @to_local)}.should raise_error(/not exists/)
|
|
85
|
+
@box.upload_directory(@from_local, @remote_path)
|
|
86
|
+
@box.download_directory(@remote_path, @to_local)
|
|
87
|
+
File.exist?("#{@to_local}/dir2/file").should be_true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "remove_directory" do
|
|
91
|
+
lambda{@box.remove_directory(@remote_path)}.should raise_error(/not exists/)
|
|
92
|
+
@box.upload_directory(@from_local, @remote_path)
|
|
93
|
+
@box.directory_exist?(@remote_path).should be_true
|
|
94
|
+
@box.remove_directory(@remote_path)
|
|
95
|
+
@box.directory_exist?(@remote_path).should be_false
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "shell" do
|
|
101
|
+
it 'exec' do
|
|
102
|
+
@box.bash("echo 'ok'").should == ["ok\n", ""]
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
some content
|
data/spec/config.yml
ADDED
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'rspec_ext'
|
|
2
|
+
require 'rsh'
|
|
3
|
+
|
|
4
|
+
rspec do
|
|
5
|
+
def config
|
|
6
|
+
dir = File.dirname __FILE__
|
|
7
|
+
config_file_path = "#{dir}/config.yml"
|
|
8
|
+
raise "no config '#{config_file_path}'!" unless File.exist? config_file_path
|
|
9
|
+
@config ||= YAML.load_file config_file_path
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'abstract_driver'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
describe Rsh::Drivers::Ssh do
|
|
5
|
+
it_should_behave_like "abstract driver"
|
|
6
|
+
|
|
7
|
+
before :each do
|
|
8
|
+
@driver = Rsh::Drivers::Ssh.new config[:remote_driver]
|
|
9
|
+
@driver.open_connection
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
after :each do
|
|
13
|
+
@driver.close_connection
|
|
14
|
+
end
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rssh
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease: false
|
|
5
|
+
segments:
|
|
6
|
+
- 0
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
version: 0.0.1
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Alexey Petrushin
|
|
13
|
+
autorequire:
|
|
14
|
+
bindir: bin
|
|
15
|
+
cert_chain: []
|
|
16
|
+
|
|
17
|
+
date: 2011-01-30 00:00:00 +03:00
|
|
18
|
+
default_executable:
|
|
19
|
+
dependencies: []
|
|
20
|
+
|
|
21
|
+
description:
|
|
22
|
+
email:
|
|
23
|
+
executables: []
|
|
24
|
+
|
|
25
|
+
extensions: []
|
|
26
|
+
|
|
27
|
+
extra_rdoc_files: []
|
|
28
|
+
|
|
29
|
+
files:
|
|
30
|
+
- Rakefile
|
|
31
|
+
- readme.md
|
|
32
|
+
- lib/old/ssh.rb
|
|
33
|
+
- lib/rsh/box.rb
|
|
34
|
+
- lib/rsh/drivers/abstract.rb
|
|
35
|
+
- lib/rsh/drivers/local.rb
|
|
36
|
+
- lib/rsh/drivers/ssh.rb
|
|
37
|
+
- lib/rsh/gems.rb
|
|
38
|
+
- lib/rsh/support.rb
|
|
39
|
+
- lib/rsh.rb
|
|
40
|
+
- spec/abstract_driver/dir/dir2/file
|
|
41
|
+
- spec/abstract_driver/local_file
|
|
42
|
+
- spec/abstract_driver.rb
|
|
43
|
+
- spec/box_spec/dir/dir2/file
|
|
44
|
+
- spec/box_spec/local_file
|
|
45
|
+
- spec/box_spec.rb
|
|
46
|
+
- spec/config.example.yml
|
|
47
|
+
- spec/config.yml
|
|
48
|
+
- spec/local_driver_spec.rb
|
|
49
|
+
- spec/spec_helper.rb
|
|
50
|
+
- spec/ssh_driver_spec.rb
|
|
51
|
+
has_rdoc: true
|
|
52
|
+
homepage: http://github.com/alexeypetrushin/rssh
|
|
53
|
+
licenses: []
|
|
54
|
+
|
|
55
|
+
post_install_message:
|
|
56
|
+
rdoc_options: []
|
|
57
|
+
|
|
58
|
+
require_paths:
|
|
59
|
+
- lib
|
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
|
+
none: false
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
segments:
|
|
66
|
+
- 0
|
|
67
|
+
version: "0"
|
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
|
+
none: false
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
segments:
|
|
74
|
+
- 0
|
|
75
|
+
version: "0"
|
|
76
|
+
requirements: []
|
|
77
|
+
|
|
78
|
+
rubyforge_project:
|
|
79
|
+
rubygems_version: 1.3.7
|
|
80
|
+
signing_key:
|
|
81
|
+
specification_version: 3
|
|
82
|
+
summary: ruby ssh and io
|
|
83
|
+
test_files: []
|
|
84
|
+
|